Assorted basic/shared/home/import hardening fixes flagged by kres (#42950)
This commit is contained in:
+19
-5
@@ -726,7 +726,11 @@ static int write_to_journal(
|
||||
if (LOG_PRI(level) > log_target_max_level[LOG_TARGET_JOURNAL])
|
||||
return 0;
|
||||
|
||||
iovec_len = MIN(6 + log_context_num_fields() * 3, IOVEC_MAX);
|
||||
if (!MUL_SAFE(&iovec_len, log_context_num_fields(), 3) ||
|
||||
!ADD_SAFE(&iovec_len, iovec_len, 6))
|
||||
iovec_len = IOVEC_MAX;
|
||||
else
|
||||
iovec_len = MIN(iovec_len, IOVEC_MAX);
|
||||
iovec = newa(struct iovec, iovec_len);
|
||||
|
||||
log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object, extra_field, extra);
|
||||
@@ -1024,7 +1028,11 @@ int log_struct_internal(
|
||||
int r;
|
||||
bool fallback = false;
|
||||
|
||||
iovec_len = MIN(17 + log_context_num_fields() * 3, IOVEC_MAX);
|
||||
if (!MUL_SAFE(&iovec_len, log_context_num_fields(), 3) ||
|
||||
!ADD_SAFE(&iovec_len, iovec_len, 17))
|
||||
iovec_len = IOVEC_MAX;
|
||||
else
|
||||
iovec_len = MIN(iovec_len, IOVEC_MAX);
|
||||
iovec = newa(struct iovec, iovec_len);
|
||||
|
||||
/* If the journal is available do structured logging.
|
||||
@@ -1123,15 +1131,21 @@ int log_struct_iovec_internal(
|
||||
|
||||
char header[LINE_MAX];
|
||||
struct iovec *iovec;
|
||||
size_t n = 0, iovec_len;
|
||||
size_t n = 0, iovec_len, n_context_iovec, n_input_iovec_expanded;
|
||||
|
||||
iovec_len = MIN(1 + n_input_iovec * 2 + log_context_num_fields() * 3, IOVEC_MAX);
|
||||
if (!MUL_SAFE(&n_input_iovec_expanded, n_input_iovec, 2) ||
|
||||
!MUL_SAFE(&n_context_iovec, log_context_num_fields(), 3) ||
|
||||
!ADD_SAFE(&iovec_len, 1, n_input_iovec_expanded) ||
|
||||
!ADD_SAFE(&iovec_len, iovec_len, n_context_iovec))
|
||||
iovec_len = IOVEC_MAX;
|
||||
else
|
||||
iovec_len = MIN(iovec_len, IOVEC_MAX);
|
||||
iovec = newa(struct iovec, iovec_len);
|
||||
|
||||
log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
|
||||
|
||||
iovec[n++] = IOVEC_MAKE_STRING(header);
|
||||
for (size_t i = 0; i < n_input_iovec; i++) {
|
||||
for (size_t i = 0; i < n_input_iovec && n + 2 <= iovec_len; i++) {
|
||||
iovec[n++] = input_iovec[i];
|
||||
iovec[n++] = IOVEC_MAKE_STRING("\n");
|
||||
}
|
||||
|
||||
+49
-10
@@ -357,6 +357,33 @@ static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_le
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Walk backwards from 'end' (exclusive) to the start of the last complete UTF-8 character, without
|
||||
* descending below 'start', validate it and return a pointer to its first byte, optionally decoding it
|
||||
* into *ret_c. Returns NULL on a truncated or otherwise malformed sequence. */
|
||||
static const char* find_previous_unichar(const char *start, const char *end, char32_t *ret_c) {
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
assert(start);
|
||||
assert(end);
|
||||
assert(end > start);
|
||||
|
||||
for (p = end; p > start; ) {
|
||||
p--;
|
||||
if (((uint8_t) *p & 0xc0) != 0x80) /* Found a non-continuation byte, i.e. a character start. */
|
||||
break;
|
||||
}
|
||||
|
||||
r = utf8_encoded_valid_unichar(p, end - p);
|
||||
if (r < 0 || p + r != end)
|
||||
return NULL;
|
||||
|
||||
if (ret_c)
|
||||
assert_se(utf8_encoded_to_unichar(p, ret_c) == r);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
char* ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
|
||||
size_t x, k, len, len2;
|
||||
const char *i, *j;
|
||||
@@ -400,11 +427,13 @@ char* ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne
|
||||
continue; /* ANSI sequences don't take up any space in output */
|
||||
}
|
||||
|
||||
char32_t c;
|
||||
r = utf8_encoded_to_unichar(i, &c);
|
||||
r = utf8_encoded_valid_unichar(i, s + old_length - i);
|
||||
if (r < 0)
|
||||
return NULL;
|
||||
|
||||
char32_t c;
|
||||
assert_se(utf8_encoded_to_unichar(i, &c) == r);
|
||||
|
||||
int w = unichar_iswide(c) ? 2 : 1;
|
||||
if (k + w > x)
|
||||
break;
|
||||
@@ -431,9 +460,9 @@ char* ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne
|
||||
continue;
|
||||
}
|
||||
|
||||
tt = utf8_prev_char(t);
|
||||
r = utf8_encoded_to_unichar(tt, &c);
|
||||
if (r < 0)
|
||||
/* Find the previous complete UTF-8 character inside the retained suffix. */
|
||||
tt = find_previous_unichar(i, t, &c);
|
||||
if (!tt)
|
||||
return NULL;
|
||||
|
||||
w = unichar_iswide(c) ? 2 : 1;
|
||||
@@ -451,11 +480,21 @@ char* ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne
|
||||
if (k >= new_length) {
|
||||
/* Make space for ellipsis, if required and possible. We know that the edge character is not
|
||||
* part of an ANSI sequence (because then we'd skip it). If the last character we looked at
|
||||
* was wide, we don't need to make space. */
|
||||
if (j < s + old_length)
|
||||
j = utf8_next_char(j);
|
||||
else if (i > s)
|
||||
i = utf8_prev_char(i);
|
||||
* was wide, we don't need to make space.
|
||||
* Move the edge by one complete UTF-8 character within the input slice. */
|
||||
if (j < s + old_length) {
|
||||
r = utf8_encoded_valid_unichar(j, s + old_length - j);
|
||||
if (r < 0)
|
||||
return NULL;
|
||||
|
||||
j += r;
|
||||
} else if (i > s) {
|
||||
const char *tt = find_previous_unichar(s, i, NULL);
|
||||
if (!tt)
|
||||
return NULL;
|
||||
|
||||
i = tt;
|
||||
}
|
||||
}
|
||||
|
||||
len = i - s;
|
||||
|
||||
Reference in New Issue
Block a user