mirror of
https://github.com/systemd/systemd
synced 2026-03-16 10:04:47 +01:00
Compare commits
No commits in common. "2d4efd1dba568e59b149fbb82b51201951e8e178" and "871a3a33bbb3458c97e47fc828243082014fc583" have entirely different histories.
2d4efd1dba
...
871a3a33bb
1
.github/workflows/unit_tests.sh
vendored
1
.github/workflows/unit_tests.sh
vendored
@ -6,7 +6,6 @@ ADDITIONAL_DEPS=(
|
||||
clang
|
||||
expect
|
||||
fdisk
|
||||
jekyll
|
||||
libfdisk-dev
|
||||
libfido2-dev
|
||||
libp11-kit-dev
|
||||
|
||||
15
meson.build
15
meson.build
@ -3501,21 +3501,6 @@ meson.add_install_script('sh', '-c', 'touch $DESTDIR@0@'.format(prefixdir))
|
||||
|
||||
############################################################
|
||||
|
||||
# Ensure that changes to the docs/ directory do not break the
|
||||
# basic Github pages build. But only run it in developer mode,
|
||||
# as it might be fragile due to changes in the tooling, and it is
|
||||
# not generally useful for users.
|
||||
jekyll = find_program('jekyll', required : false)
|
||||
if get_option('mode') == 'developer' and want_tests != 'false' and jekyll.found()
|
||||
test('github-pages',
|
||||
jekyll,
|
||||
args : ['build',
|
||||
'--source', join_paths(project_source_root, 'docs'),
|
||||
'--destination', join_paths(project_build_root, '_site')])
|
||||
endif
|
||||
|
||||
############################################################
|
||||
|
||||
check_help = find_program('tools/check-help.sh')
|
||||
|
||||
foreach exec : public_programs
|
||||
|
||||
@ -2116,7 +2116,7 @@ int analyze_security(sd_bus *bus, char **units, AnalyzeSecurityFlags flags) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
_cleanup_strv_free_ char **list = NULL;
|
||||
size_t n = 0;
|
||||
size_t allocated = 0, n = 0;
|
||||
char **i;
|
||||
|
||||
r = sd_bus_call_method(
|
||||
@ -2148,7 +2148,7 @@ int analyze_security(sd_bus *bus, char **units, AnalyzeSecurityFlags flags) {
|
||||
if (!endswith(info.id, ".service"))
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(list, n + 2))
|
||||
if (!GREEDY_REALLOC(list, allocated, n + 2))
|
||||
return log_oom();
|
||||
|
||||
copy = strdup(info.id);
|
||||
|
||||
@ -342,7 +342,7 @@ static int acquire_time_data(sd_bus *bus, UnitTimes **out) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(unit_times_free_arrayp) UnitTimes *unit_times = NULL;
|
||||
BootTimes *boot_times = NULL;
|
||||
size_t c = 0;
|
||||
size_t allocated = 0, c = 0;
|
||||
UnitInfo u;
|
||||
int r;
|
||||
|
||||
@ -361,7 +361,7 @@ static int acquire_time_data(sd_bus *bus, UnitTimes **out) {
|
||||
while ((r = bus_parse_unit_info(reply, &u)) > 0) {
|
||||
UnitTimes *t;
|
||||
|
||||
if (!GREEDY_REALLOC(unit_times, c + 2))
|
||||
if (!GREEDY_REALLOC(unit_times, allocated, c + 2))
|
||||
return log_oom();
|
||||
|
||||
unit_times[c + 1].has_data = false;
|
||||
|
||||
@ -17,7 +17,8 @@ void* memdup(const void *p, size_t l) {
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
return memcpy_safe(ret, p, l);
|
||||
memcpy(ret, p, l);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void* memdup_suffix0(const void *p, size_t l) {
|
||||
@ -34,36 +35,28 @@ void* memdup_suffix0(const void *p, size_t l) {
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
((uint8_t*) ret)[l] = 0;
|
||||
return memcpy_safe(ret, p, l);
|
||||
*((uint8_t*) mempcpy(ret, p, l)) = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void* greedy_realloc(
|
||||
void **p,
|
||||
size_t need,
|
||||
size_t size) {
|
||||
|
||||
void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
|
||||
size_t a, newalloc;
|
||||
void *q;
|
||||
|
||||
assert(p);
|
||||
assert(allocated);
|
||||
|
||||
/* We use malloc_usable_size() for determining the current allocated size. On all systems we care
|
||||
* about this should be safe to rely on. Should there ever arise the need to avoid relying on this we
|
||||
* can instead locally fall back to realloc() on every call, rounded up to the next exponent of 2 or
|
||||
* so. */
|
||||
|
||||
if (*p && (size == 0 || (MALLOC_SIZEOF_SAFE(*p) / size >= need)))
|
||||
if (*allocated >= need)
|
||||
return *p;
|
||||
|
||||
if (_unlikely_(need > SIZE_MAX/2)) /* Overflow check */
|
||||
return NULL;
|
||||
newalloc = need * 2;
|
||||
|
||||
newalloc = need * 2;
|
||||
if (size_multiply_overflow(newalloc, size))
|
||||
return NULL;
|
||||
a = newalloc * size;
|
||||
|
||||
a = newalloc * size;
|
||||
if (a < 64) /* Allocate at least 64 bytes */
|
||||
a = 64;
|
||||
|
||||
@ -71,34 +64,49 @@ void* greedy_realloc(
|
||||
if (!q)
|
||||
return NULL;
|
||||
|
||||
return *p = q;
|
||||
if (size > 0) {
|
||||
size_t bn;
|
||||
|
||||
/* Adjust for the 64 byte minimum */
|
||||
newalloc = a / size;
|
||||
|
||||
bn = malloc_usable_size(q) / size;
|
||||
if (bn > newalloc) {
|
||||
void *qq;
|
||||
|
||||
/* The actual size allocated is larger than what we asked for. Let's call realloc() again to
|
||||
* take possession of the extra space. This should be cheap, since libc doesn't have to move
|
||||
* the memory for this. */
|
||||
|
||||
qq = reallocarray(q, bn, size);
|
||||
if (_likely_(qq)) {
|
||||
*p = qq;
|
||||
*allocated = bn;
|
||||
return qq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*p = q;
|
||||
*allocated = newalloc;
|
||||
return q;
|
||||
}
|
||||
|
||||
void* greedy_realloc0(
|
||||
void **p,
|
||||
size_t need,
|
||||
size_t size) {
|
||||
|
||||
size_t before, after;
|
||||
void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
|
||||
size_t prev;
|
||||
uint8_t *q;
|
||||
|
||||
assert(p);
|
||||
assert(allocated);
|
||||
|
||||
before = MALLOC_SIZEOF_SAFE(*p); /* malloc_usable_size() will return 0 on NULL input, as per docs */
|
||||
prev = *allocated;
|
||||
|
||||
q = greedy_realloc(p, need, size);
|
||||
q = greedy_realloc(p, allocated, need, size);
|
||||
if (!q)
|
||||
return NULL;
|
||||
|
||||
after = MALLOC_SIZEOF_SAFE(q);
|
||||
|
||||
if (size == 0) /* avoid division by zero */
|
||||
before = 0;
|
||||
else
|
||||
before = (before / size) * size; /* Round down */
|
||||
|
||||
if (after > before)
|
||||
memzero(q + before, after - before);
|
||||
if (*allocated > prev)
|
||||
memzero(q + prev * size, (*allocated - prev) * size);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ void* memdup_suffix0(const void *p, size_t l); /* We can't use _alloc_() here, s
|
||||
size_t _l_ = l; \
|
||||
assert(_l_ <= ALLOCA_MAX); \
|
||||
_q_ = alloca(_l_ ?: 1); \
|
||||
memcpy_safe(_q_, p, _l_); \
|
||||
memcpy(_q_, p, _l_); \
|
||||
})
|
||||
|
||||
#define memdupa_suffix0(p, l) \
|
||||
@ -76,7 +76,7 @@ void* memdup_suffix0(const void *p, size_t l); /* We can't use _alloc_() here, s
|
||||
assert(_l_ <= ALLOCA_MAX); \
|
||||
_q_ = alloca(_l_ + 1); \
|
||||
((uint8_t*) _q_)[_l_] = 0; \
|
||||
memcpy_safe(_q_, p, _l_); \
|
||||
memcpy(_q_, p, _l_); \
|
||||
})
|
||||
|
||||
static inline void freep(void *p) {
|
||||
@ -121,14 +121,14 @@ static inline void *memdup_suffix0_multiply(const void *p, size_t size, size_t n
|
||||
return memdup_suffix0(p, size * need);
|
||||
}
|
||||
|
||||
void* greedy_realloc(void **p, size_t need, size_t size);
|
||||
void* greedy_realloc0(void **p, size_t need, size_t size);
|
||||
void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size);
|
||||
void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size);
|
||||
|
||||
#define GREEDY_REALLOC(array, need) \
|
||||
greedy_realloc((void**) &(array), (need), sizeof((array)[0]))
|
||||
#define GREEDY_REALLOC(array, allocated, need) \
|
||||
greedy_realloc((void**) &(array), &(allocated), (need), sizeof((array)[0]))
|
||||
|
||||
#define GREEDY_REALLOC0(array, need) \
|
||||
greedy_realloc0((void**) &(array), (need), sizeof((array)[0]))
|
||||
#define GREEDY_REALLOC0(array, allocated, need) \
|
||||
greedy_realloc0((void**) &(array), &(allocated), (need), sizeof((array)[0]))
|
||||
|
||||
#define alloca0(n) \
|
||||
({ \
|
||||
@ -163,23 +163,3 @@ void* greedy_realloc0(void **p, size_t need, size_t size);
|
||||
#else
|
||||
# define msan_unpoison(r, s)
|
||||
#endif
|
||||
|
||||
/* This returns the number of usable bytes in a malloc()ed region as per malloc_usable_size(), in a way that
|
||||
* is compatible with _FORTIFY_SOURCES. If _FORTIFY_SOURCES is used many memory operations will take the
|
||||
* object size as returned by __builtin_object_size() into account. Hence, let's return the smaller size of
|
||||
* malloc_usable_size() and __builtin_object_size() here, so that we definitely operate in safe territory by
|
||||
* both the compiler's and libc's standards. Note that __builtin_object_size() evaluates to SIZE_MAX if the
|
||||
* size cannot be determined, hence the MIN() expression should be safe with dynamically sized memory,
|
||||
* too. Moreover, when NULL is passed malloc_usable_size() is documented to return zero, and
|
||||
* __builtin_object_size() returns SIZE_MAX too, hence we also return a sensible value of 0 in this corner
|
||||
* case. */
|
||||
#define MALLOC_SIZEOF_SAFE(x) \
|
||||
MIN(malloc_usable_size(x), __builtin_object_size(x, 0))
|
||||
|
||||
/* Inspired by ELEMENTSOF() but operates on malloc()'ed memory areas: typesafely returns the number of items
|
||||
* that fit into the specified memory block */
|
||||
#define MALLOC_ELEMENTSOF(x) \
|
||||
(__builtin_choose_expr( \
|
||||
__builtin_types_compatible_p(typeof(x), typeof(&*(x))), \
|
||||
MALLOC_SIZEOF_SAFE(x)/sizeof((x)[0]), \
|
||||
VOID_0))
|
||||
|
||||
@ -1728,7 +1728,7 @@ int btrfs_qgroup_find_parents(int fd, uint64_t qgroupid, uint64_t **ret) {
|
||||
};
|
||||
|
||||
_cleanup_free_ uint64_t *items = NULL;
|
||||
size_t n_items = 0;
|
||||
size_t n_items = 0, n_allocated = 0;
|
||||
int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
@ -1775,7 +1775,7 @@ int btrfs_qgroup_find_parents(int fd, uint64_t qgroupid, uint64_t **ret) {
|
||||
if (sh->objectid != qgroupid)
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(items, n_items+1))
|
||||
if (!GREEDY_REALLOC(items, n_allocated, n_items+1))
|
||||
return -ENOMEM;
|
||||
|
||||
items[n_items++] = sh->offset;
|
||||
|
||||
@ -59,7 +59,7 @@ int capability_list_length(void) {
|
||||
|
||||
int capability_set_to_string_alloc(uint64_t set, char **s) {
|
||||
_cleanup_free_ char *str = NULL;
|
||||
size_t n = 0;
|
||||
size_t allocated = 0, n = 0;
|
||||
|
||||
assert(s);
|
||||
|
||||
@ -77,14 +77,14 @@ int capability_set_to_string_alloc(uint64_t set, char **s) {
|
||||
|
||||
add = strlen(p);
|
||||
|
||||
if (!GREEDY_REALLOC(str, n + add + 2))
|
||||
if (!GREEDY_REALLOC(str, allocated, n + add + 2))
|
||||
return -ENOMEM;
|
||||
|
||||
strcpy(mempcpy(str + n, p, add), " ");
|
||||
n += add + 1;
|
||||
}
|
||||
|
||||
if (!GREEDY_REALLOC(str, n + 1))
|
||||
if (!GREEDY_REALLOC(str, allocated, n + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
str[n > 0 ? n - 1 : 0] = '\0'; /* truncate the last space, if it's there */
|
||||
|
||||
@ -1817,9 +1817,9 @@ done:
|
||||
|
||||
int cg_mask_to_string(CGroupMask mask, char **ret) {
|
||||
_cleanup_free_ char *s = NULL;
|
||||
size_t n = 0, allocated = 0;
|
||||
bool space = false;
|
||||
CGroupController c;
|
||||
size_t n = 0;
|
||||
|
||||
assert(ret);
|
||||
|
||||
@ -1838,7 +1838,7 @@ int cg_mask_to_string(CGroupMask mask, char **ret) {
|
||||
k = cgroup_controller_to_string(c);
|
||||
l = strlen(k);
|
||||
|
||||
if (!GREEDY_REALLOC(s, n + space + l + 1))
|
||||
if (!GREEDY_REALLOC(s, allocated, n + space + l + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
if (space)
|
||||
|
||||
@ -20,7 +20,7 @@ static int parse_env_file_internal(
|
||||
void *userdata,
|
||||
int *n_pushed) {
|
||||
|
||||
size_t n_key = 0, n_value = 0, last_value_whitespace = SIZE_MAX, last_key_whitespace = SIZE_MAX;
|
||||
size_t key_alloc = 0, n_key = 0, value_alloc = 0, n_value = 0, last_value_whitespace = SIZE_MAX, last_key_whitespace = SIZE_MAX;
|
||||
_cleanup_free_ char *contents = NULL, *key = NULL, *value = NULL;
|
||||
unsigned line = 1;
|
||||
char *p;
|
||||
@ -58,7 +58,7 @@ static int parse_env_file_internal(
|
||||
state = KEY;
|
||||
last_key_whitespace = SIZE_MAX;
|
||||
|
||||
if (!GREEDY_REALLOC(key, n_key+2))
|
||||
if (!GREEDY_REALLOC(key, key_alloc, n_key+2))
|
||||
return -ENOMEM;
|
||||
|
||||
key[n_key++] = c;
|
||||
@ -79,7 +79,7 @@ static int parse_env_file_internal(
|
||||
else if (last_key_whitespace == SIZE_MAX)
|
||||
last_key_whitespace = n_key;
|
||||
|
||||
if (!GREEDY_REALLOC(key, n_key+2))
|
||||
if (!GREEDY_REALLOC(key, key_alloc, n_key+2))
|
||||
return -ENOMEM;
|
||||
|
||||
key[n_key++] = c;
|
||||
@ -106,7 +106,7 @@ static int parse_env_file_internal(
|
||||
|
||||
n_key = 0;
|
||||
value = NULL;
|
||||
n_value = 0;
|
||||
value_alloc = n_value = 0;
|
||||
|
||||
} else if (c == '\'')
|
||||
state = SINGLE_QUOTE_VALUE;
|
||||
@ -117,7 +117,7 @@ static int parse_env_file_internal(
|
||||
else if (!strchr(WHITESPACE, c)) {
|
||||
state = VALUE;
|
||||
|
||||
if (!GREEDY_REALLOC(value, n_value+2))
|
||||
if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
|
||||
return -ENOMEM;
|
||||
|
||||
value[n_value++] = c;
|
||||
@ -149,7 +149,7 @@ static int parse_env_file_internal(
|
||||
|
||||
n_key = 0;
|
||||
value = NULL;
|
||||
n_value = 0;
|
||||
value_alloc = n_value = 0;
|
||||
|
||||
} else if (c == '\\') {
|
||||
state = VALUE_ESCAPE;
|
||||
@ -160,7 +160,7 @@ static int parse_env_file_internal(
|
||||
else if (last_value_whitespace == SIZE_MAX)
|
||||
last_value_whitespace = n_value;
|
||||
|
||||
if (!GREEDY_REALLOC(value, n_value+2))
|
||||
if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
|
||||
return -ENOMEM;
|
||||
|
||||
value[n_value++] = c;
|
||||
@ -173,7 +173,7 @@ static int parse_env_file_internal(
|
||||
|
||||
if (!strchr(NEWLINE, c)) {
|
||||
/* Escaped newlines we eat up entirely */
|
||||
if (!GREEDY_REALLOC(value, n_value+2))
|
||||
if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
|
||||
return -ENOMEM;
|
||||
|
||||
value[n_value++] = c;
|
||||
@ -184,7 +184,7 @@ static int parse_env_file_internal(
|
||||
if (c == '\'')
|
||||
state = PRE_VALUE;
|
||||
else {
|
||||
if (!GREEDY_REALLOC(value, n_value+2))
|
||||
if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
|
||||
return -ENOMEM;
|
||||
|
||||
value[n_value++] = c;
|
||||
@ -198,7 +198,7 @@ static int parse_env_file_internal(
|
||||
else if (c == '\\')
|
||||
state = DOUBLE_QUOTE_VALUE_ESCAPE;
|
||||
else {
|
||||
if (!GREEDY_REALLOC(value, n_value+2))
|
||||
if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
|
||||
return -ENOMEM;
|
||||
|
||||
value[n_value++] = c;
|
||||
@ -211,13 +211,13 @@ static int parse_env_file_internal(
|
||||
|
||||
if (strchr(SHELL_NEED_ESCAPE, c)) {
|
||||
/* If this is a char that needs escaping, just unescape it. */
|
||||
if (!GREEDY_REALLOC(value, n_value+2))
|
||||
if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
|
||||
return -ENOMEM;
|
||||
value[n_value++] = c;
|
||||
} else if (c != '\n') {
|
||||
/* If other char than what needs escaping, keep the "\" in place, like the
|
||||
* real shell does. */
|
||||
if (!GREEDY_REALLOC(value, n_value+3))
|
||||
if (!GREEDY_REALLOC(value, value_alloc, n_value+3))
|
||||
return -ENOMEM;
|
||||
value[n_value++] = '\\';
|
||||
value[n_value++] = c;
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
|
||||
_cleanup_free_ char *s = NULL;
|
||||
size_t sz = 0;
|
||||
size_t allocated = 0, sz = 0;
|
||||
char quote = 0; /* 0 or ' or " */
|
||||
bool backslash = false; /* whether we've just seen a backslash */
|
||||
char c;
|
||||
@ -42,7 +42,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
|
||||
* the pointer *p at the first invalid character. */
|
||||
|
||||
if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
|
||||
if (!GREEDY_REALLOC(s, sz+1))
|
||||
if (!GREEDY_REALLOC(s, allocated, sz+1))
|
||||
return -ENOMEM;
|
||||
|
||||
for (;; (*p)++, c = **p) {
|
||||
@ -57,7 +57,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
|
||||
/* We found a non-blank character, so we will always
|
||||
* want to return a string (even if it is empty),
|
||||
* allocate it here. */
|
||||
if (!GREEDY_REALLOC(s, sz+1))
|
||||
if (!GREEDY_REALLOC(s, allocated, sz+1))
|
||||
return -ENOMEM;
|
||||
break;
|
||||
}
|
||||
@ -65,7 +65,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
|
||||
|
||||
for (;; (*p)++, c = **p) {
|
||||
if (backslash) {
|
||||
if (!GREEDY_REALLOC(s, sz+7))
|
||||
if (!GREEDY_REALLOC(s, allocated, sz+7))
|
||||
return -ENOMEM;
|
||||
|
||||
if (c == 0) {
|
||||
@ -128,7 +128,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
|
||||
backslash = true;
|
||||
break;
|
||||
} else {
|
||||
if (!GREEDY_REALLOC(s, sz+2))
|
||||
if (!GREEDY_REALLOC(s, allocated, sz+2))
|
||||
return -ENOMEM;
|
||||
|
||||
s[sz++] = c;
|
||||
@ -160,7 +160,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
|
||||
goto finish;
|
||||
|
||||
} else {
|
||||
if (!GREEDY_REALLOC(s, sz+2))
|
||||
if (!GREEDY_REALLOC(s, allocated, sz+2))
|
||||
return -ENOMEM;
|
||||
|
||||
s[sz++] = c;
|
||||
|
||||
@ -424,7 +424,7 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
/* Use a bigger allocation if we got it anyway, but not more than the limit. */
|
||||
size = MIN3(MALLOC_SIZEOF_SAFE(buf) - 1, max_size, READ_FULL_BYTES_MAX);
|
||||
size = MIN3(malloc_usable_size(buf) - 1, max_size, READ_FULL_BYTES_MAX);
|
||||
|
||||
for (;;) {
|
||||
ssize_t k;
|
||||
@ -570,7 +570,7 @@ int read_full_stream_full(
|
||||
buf = t;
|
||||
/* Unless a size has been explicitly specified, try to read as much as fits into the memory
|
||||
* we allocated (minus 1, to leave one byte for the safety NUL byte) */
|
||||
n = size == SIZE_MAX ? MALLOC_SIZEOF_SAFE(buf) - 1 : n_next;
|
||||
n = size == SIZE_MAX ? malloc_usable_size(buf) - 1 : n_next;
|
||||
|
||||
errno = 0;
|
||||
k = fread(buf + l, 1, n - l, f);
|
||||
@ -1212,8 +1212,8 @@ static EndOfLineMarker categorize_eol(char c, ReadLineFlags flags) {
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(FILE*, funlockfile, NULL);
|
||||
|
||||
int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret) {
|
||||
size_t n = 0, allocated = 0, count = 0;
|
||||
_cleanup_free_ char *buffer = NULL;
|
||||
size_t n = 0, count = 0;
|
||||
int r;
|
||||
|
||||
assert(f);
|
||||
@ -1243,7 +1243,7 @@ int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret) {
|
||||
* If a line shall be skipped ret may be initialized as NULL. */
|
||||
|
||||
if (ret) {
|
||||
if (!GREEDY_REALLOC(buffer, 1))
|
||||
if (!GREEDY_REALLOC(buffer, allocated, 1))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -1315,7 +1315,7 @@ int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret) {
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
if (!GREEDY_REALLOC(buffer, n + 2))
|
||||
if (!GREEDY_REALLOC(buffer, allocated, n + 2))
|
||||
return -ENOMEM;
|
||||
|
||||
buffer[n] = c;
|
||||
|
||||
@ -549,10 +549,10 @@ int mkfifoat_atomic(int dirfd, const char *path, mode_t mode) {
|
||||
}
|
||||
|
||||
int get_files_in_directory(const char *path, char ***list) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
struct dirent *de;
|
||||
size_t n = 0;
|
||||
size_t bufsize = 0, n = 0;
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
|
||||
assert(path);
|
||||
|
||||
@ -572,7 +572,7 @@ int get_files_in_directory(const char *path, char ***list) {
|
||||
|
||||
if (list) {
|
||||
/* one extra slot is needed for the terminating NULL */
|
||||
if (!GREEDY_REALLOC(l, n + 2))
|
||||
if (!GREEDY_REALLOC(l, bufsize, n + 2))
|
||||
return -ENOMEM;
|
||||
|
||||
l[n] = strdup(de->d_name);
|
||||
|
||||
@ -230,7 +230,7 @@ struct Set {
|
||||
|
||||
typedef struct CacheMem {
|
||||
const void **ptr;
|
||||
size_t n_populated;
|
||||
size_t n_populated, n_allocated;
|
||||
bool active:1;
|
||||
} CacheMem;
|
||||
|
||||
@ -1897,10 +1897,10 @@ int set_put_strsplit(Set *s, const char *v, const char *separators, ExtractFlags
|
||||
}
|
||||
|
||||
/* expand the cachemem if needed, return true if newly (re)activated. */
|
||||
static int cachemem_maintain(CacheMem *mem, size_t size) {
|
||||
static int cachemem_maintain(CacheMem *mem, unsigned size) {
|
||||
assert(mem);
|
||||
|
||||
if (!GREEDY_REALLOC(mem->ptr, size)) {
|
||||
if (!GREEDY_REALLOC(mem->ptr, mem->n_allocated, size)) {
|
||||
if (size > 0)
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -1915,7 +1915,7 @@ static int cachemem_maintain(CacheMem *mem, size_t size) {
|
||||
|
||||
int iterated_cache_get(IteratedCache *cache, const void ***res_keys, const void ***res_values, unsigned *res_n_entries) {
|
||||
bool sync_keys = false, sync_values = false;
|
||||
size_t size;
|
||||
unsigned size;
|
||||
int r;
|
||||
|
||||
assert(cache);
|
||||
@ -1988,8 +1988,8 @@ IteratedCache* iterated_cache_free(IteratedCache *cache) {
|
||||
}
|
||||
|
||||
int set_strjoin(Set *s, const char *separator, bool wrap_with_separator, char **ret) {
|
||||
size_t separator_len, allocated = 0, len = 0;
|
||||
_cleanup_free_ char *str = NULL;
|
||||
size_t separator_len, len = 0;
|
||||
const char *value;
|
||||
bool first;
|
||||
|
||||
@ -2013,7 +2013,7 @@ int set_strjoin(Set *s, const char *separator, bool wrap_with_separator, char **
|
||||
if (l == 0)
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(str, len + l + (first ? 0 : separator_len) + (wrap_with_separator ? separator_len : 0) + 1))
|
||||
if (!GREEDY_REALLOC(str, allocated, len + l + (first ? 0 : separator_len) + (wrap_with_separator ? separator_len : 0) + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
if (separator_len > 0 && !first) {
|
||||
|
||||
@ -288,6 +288,7 @@ void iovw_free_contents(struct iovec_wrapper *iovw, bool free_vectors) {
|
||||
|
||||
iovw->iovec = mfree(iovw->iovec);
|
||||
iovw->count = 0;
|
||||
iovw->size_bytes = 0;
|
||||
}
|
||||
|
||||
struct iovec_wrapper *iovw_free_free(struct iovec_wrapper *iovw) {
|
||||
@ -306,7 +307,7 @@ int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len) {
|
||||
if (iovw->count >= IOV_MAX)
|
||||
return -E2BIG;
|
||||
|
||||
if (!GREEDY_REALLOC(iovw->iovec, iovw->count + 1))
|
||||
if (!GREEDY_REALLOC(iovw->iovec, iovw->size_bytes, iovw->count + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
iovw->iovec[iovw->count++] = IOVEC_MAKE(data, len);
|
||||
|
||||
@ -85,6 +85,7 @@ char* set_iovec_string_field_free(struct iovec *iovec, size_t *n_iovec, const ch
|
||||
struct iovec_wrapper {
|
||||
struct iovec *iovec;
|
||||
size_t count;
|
||||
size_t size_bytes;
|
||||
};
|
||||
|
||||
struct iovec_wrapper *iovw_new(void);
|
||||
|
||||
@ -16,11 +16,11 @@ size_t page_size(void) _pure_;
|
||||
#define PAGE_OFFSET(l) ((l) & (page_size() - 1))
|
||||
|
||||
/* Normal memcpy requires src to be nonnull. We do nothing if n is 0. */
|
||||
static inline void *memcpy_safe(void *dst, const void *src, size_t n) {
|
||||
static inline void memcpy_safe(void *dst, const void *src, size_t n) {
|
||||
if (n == 0)
|
||||
return dst;
|
||||
return;
|
||||
assert(src);
|
||||
return memcpy(dst, src, n);
|
||||
memcpy(dst, src, n);
|
||||
}
|
||||
|
||||
/* Normal memcmp requires s1 and s2 to be nonnull. We do nothing if n is 0. */
|
||||
@ -88,7 +88,7 @@ static inline void* erase_and_free(void *p) {
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
l = MALLOC_SIZEOF_SAFE(p);
|
||||
l = malloc_usable_size(p);
|
||||
explicit_bzero_safe(p, l);
|
||||
return mfree(p);
|
||||
}
|
||||
|
||||
@ -601,7 +601,7 @@ int get_process_root(pid_t pid, char **root) {
|
||||
int get_process_environ(pid_t pid, char **env) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
_cleanup_free_ char *outcome = NULL;
|
||||
size_t sz = 0;
|
||||
size_t allocated = 0, sz = 0;
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
@ -622,7 +622,7 @@ int get_process_environ(pid_t pid, char **env) {
|
||||
if (sz >= ENVIRONMENT_BLOCK_MAX)
|
||||
return -ENOBUFS;
|
||||
|
||||
if (!GREEDY_REALLOC(outcome, sz + 5))
|
||||
if (!GREEDY_REALLOC(outcome, allocated, sz + 5))
|
||||
return -ENOMEM;
|
||||
|
||||
r = safe_fgetc(f, &c);
|
||||
|
||||
@ -522,7 +522,7 @@ char* strshorten(char *s, size_t l) {
|
||||
}
|
||||
|
||||
char *strreplace(const char *text, const char *old_string, const char *new_string) {
|
||||
size_t l, old_len, new_len;
|
||||
size_t l, old_len, new_len, allocated = 0;
|
||||
char *t, *ret = NULL;
|
||||
const char *f;
|
||||
|
||||
@ -536,7 +536,7 @@ char *strreplace(const char *text, const char *old_string, const char *new_strin
|
||||
new_len = strlen(new_string);
|
||||
|
||||
l = strlen(text);
|
||||
if (!GREEDY_REALLOC(ret, l+1))
|
||||
if (!GREEDY_REALLOC(ret, allocated, l+1))
|
||||
return NULL;
|
||||
|
||||
f = text;
|
||||
@ -552,7 +552,7 @@ char *strreplace(const char *text, const char *old_string, const char *new_strin
|
||||
d = t - ret;
|
||||
nl = l - old_len + new_len;
|
||||
|
||||
if (!GREEDY_REALLOC(ret, nl + 1))
|
||||
if (!GREEDY_REALLOC(ret, allocated, nl + 1))
|
||||
return mfree(ret);
|
||||
|
||||
l = nl;
|
||||
@ -805,7 +805,7 @@ int strextendf(char **x, const char *format, ...) {
|
||||
/* Let's try to use the allocated buffer, if there's room at the end still. Otherwise let's extend by 64 chars. */
|
||||
if (*x) {
|
||||
m = strlen(*x);
|
||||
a = MALLOC_SIZEOF_SAFE(*x);
|
||||
a = malloc_usable_size(*x);
|
||||
assert(a >= m + 1);
|
||||
} else
|
||||
m = a = 0;
|
||||
@ -821,7 +821,7 @@ int strextendf(char **x, const char *format, ...) {
|
||||
return -ENOMEM;
|
||||
|
||||
*x = n;
|
||||
a = MALLOC_SIZEOF_SAFE(*x);
|
||||
a = malloc_usable_size(*x);
|
||||
}
|
||||
|
||||
/* Now, let's try to format the string into it */
|
||||
|
||||
@ -266,7 +266,7 @@ int strv_split_newlines_full(char ***ret, const char *s, ExtractFlags flags) {
|
||||
|
||||
int strv_split_full(char ***t, const char *s, const char *separators, ExtractFlags flags) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
size_t n = 0;
|
||||
size_t n = 0, allocated = 0;
|
||||
int r;
|
||||
|
||||
assert(t);
|
||||
@ -281,7 +281,7 @@ int strv_split_full(char ***t, const char *s, const char *separators, ExtractFla
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
if (!GREEDY_REALLOC(l, n + 2))
|
||||
if (!GREEDY_REALLOC(l, allocated, n + 2))
|
||||
return -ENOMEM;
|
||||
|
||||
l[n++] = TAKE_PTR(word);
|
||||
@ -302,7 +302,7 @@ int strv_split_full(char ***t, const char *s, const char *separators, ExtractFla
|
||||
|
||||
int strv_split_colon_pairs(char ***t, const char *s) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
size_t n = 0;
|
||||
size_t n = 0, allocated = 0;
|
||||
int r;
|
||||
|
||||
assert(t);
|
||||
@ -332,7 +332,7 @@ int strv_split_colon_pairs(char ***t, const char *s) {
|
||||
if (!second_or_empty)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!GREEDY_REALLOC(l, n + 3))
|
||||
if (!GREEDY_REALLOC(l, allocated, n + 3))
|
||||
return -ENOMEM;
|
||||
|
||||
l[n++] = TAKE_PTR(first);
|
||||
@ -708,9 +708,9 @@ int strv_make_nulstr(char * const *l, char **ret, size_t *ret_size) {
|
||||
* is provided separately.
|
||||
*/
|
||||
|
||||
size_t n_allocated = 0, n = 0;
|
||||
_cleanup_free_ char *m = NULL;
|
||||
char * const *i;
|
||||
size_t n = 0;
|
||||
|
||||
assert(ret);
|
||||
assert(ret_size);
|
||||
@ -720,7 +720,7 @@ int strv_make_nulstr(char * const *l, char **ret, size_t *ret_size) {
|
||||
|
||||
z = strlen(*i);
|
||||
|
||||
if (!GREEDY_REALLOC(m, n + z + 2))
|
||||
if (!GREEDY_REALLOC(m, n_allocated, n + z + 2))
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(m + n, *i, z + 1);
|
||||
|
||||
@ -1247,7 +1247,7 @@ int parse_nsec(const char *t, nsec_t *nsec) {
|
||||
int get_timezones(char ***ret) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
_cleanup_strv_free_ char **zones = NULL;
|
||||
size_t n_zones = 0;
|
||||
size_t n_zones = 0, n_allocated = 0;
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
@ -1256,6 +1256,7 @@ int get_timezones(char ***ret) {
|
||||
if (!zones)
|
||||
return -ENOMEM;
|
||||
|
||||
n_allocated = 2;
|
||||
n_zones = 1;
|
||||
|
||||
f = fopen("/usr/share/zoneinfo/zone1970.tab", "re");
|
||||
@ -1293,7 +1294,7 @@ int get_timezones(char ***ret) {
|
||||
if (!w)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!GREEDY_REALLOC(zones, n_zones + 2))
|
||||
if (!GREEDY_REALLOC(zones, n_allocated, n_zones + 2))
|
||||
return -ENOMEM;
|
||||
|
||||
zones[n_zones++] = TAKE_PTR(w);
|
||||
|
||||
@ -1644,8 +1644,8 @@ static int message_append_cmdline(sd_bus_message *m, const char *signature, char
|
||||
static int json_transform_one(sd_bus_message *m, JsonVariant **ret);
|
||||
|
||||
static int json_transform_array_or_struct(sd_bus_message *m, JsonVariant **ret) {
|
||||
size_t n_elements = 0, n_allocated = 0;
|
||||
JsonVariant **elements = NULL;
|
||||
size_t n_elements = 0;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
@ -1660,7 +1660,7 @@ static int json_transform_array_or_struct(sd_bus_message *m, JsonVariant **ret)
|
||||
if (r > 0)
|
||||
break;
|
||||
|
||||
if (!GREEDY_REALLOC(elements, n_elements + 1)) {
|
||||
if (!GREEDY_REALLOC(elements, n_allocated, n_elements + 1)) {
|
||||
r = log_oom();
|
||||
goto finish;
|
||||
}
|
||||
@ -1702,8 +1702,8 @@ static int json_transform_variant(sd_bus_message *m, const char *contents, JsonV
|
||||
}
|
||||
|
||||
static int json_transform_dict_array(sd_bus_message *m, JsonVariant **ret) {
|
||||
size_t n_elements = 0, n_allocated = 0;
|
||||
JsonVariant **elements = NULL;
|
||||
size_t n_elements = 0;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
@ -1727,7 +1727,7 @@ static int json_transform_dict_array(sd_bus_message *m, JsonVariant **ret) {
|
||||
|
||||
assert(type == 'e');
|
||||
|
||||
if (!GREEDY_REALLOC(elements, n_elements + 2)) {
|
||||
if (!GREEDY_REALLOC(elements, n_allocated, n_elements + 2)) {
|
||||
r = log_oom();
|
||||
goto finish;
|
||||
}
|
||||
|
||||
@ -1967,7 +1967,7 @@ static int build_environment(
|
||||
|
||||
static int build_pass_environment(const ExecContext *c, char ***ret) {
|
||||
_cleanup_strv_free_ char **pass_env = NULL;
|
||||
size_t n_env = 0;
|
||||
size_t n_env = 0, n_bufsize = 0;
|
||||
char **i;
|
||||
|
||||
STRV_FOREACH(i, c->pass_environment) {
|
||||
@ -1981,7 +1981,7 @@ static int build_pass_environment(const ExecContext *c, char ***ret) {
|
||||
if (!x)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!GREEDY_REALLOC(pass_env, n_env + 2))
|
||||
if (!GREEDY_REALLOC(pass_env, n_bufsize, n_env + 2))
|
||||
return -ENOMEM;
|
||||
|
||||
pass_env[n_env++] = TAKE_PTR(x);
|
||||
|
||||
@ -1498,8 +1498,8 @@ static size_t sort_job_list(Job **list, size_t n) {
|
||||
|
||||
int job_get_before(Job *j, Job*** ret) {
|
||||
_cleanup_free_ Job** list = NULL;
|
||||
size_t n = 0, n_allocated = 0;
|
||||
Unit *other = NULL;
|
||||
size_t n = 0;
|
||||
void *v;
|
||||
|
||||
/* Returns a list of all pending jobs that need to finish before this job may be started. */
|
||||
@ -1518,7 +1518,7 @@ int job_get_before(Job *j, Job*** ret) {
|
||||
if (job_compare(j, other->job, UNIT_AFTER) <= 0)
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(list, n+1))
|
||||
if (!GREEDY_REALLOC(list, n_allocated, n+1))
|
||||
return -ENOMEM;
|
||||
list[n++] = other->job;
|
||||
}
|
||||
@ -1529,7 +1529,7 @@ int job_get_before(Job *j, Job*** ret) {
|
||||
if (job_compare(j, other->job, UNIT_BEFORE) <= 0)
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(list, n+1))
|
||||
if (!GREEDY_REALLOC(list, n_allocated, n+1))
|
||||
return -ENOMEM;
|
||||
list[n++] = other->job;
|
||||
}
|
||||
@ -1543,8 +1543,8 @@ int job_get_before(Job *j, Job*** ret) {
|
||||
|
||||
int job_get_after(Job *j, Job*** ret) {
|
||||
_cleanup_free_ Job** list = NULL;
|
||||
size_t n = 0, n_allocated = 0;
|
||||
Unit *other = NULL;
|
||||
size_t n = 0;
|
||||
void *v;
|
||||
|
||||
assert(j);
|
||||
@ -1562,7 +1562,7 @@ int job_get_after(Job *j, Job*** ret) {
|
||||
if (job_compare(j, other->job, UNIT_BEFORE) >= 0)
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(list, n+1))
|
||||
if (!GREEDY_REALLOC(list, n_allocated, n+1))
|
||||
return -ENOMEM;
|
||||
list[n++] = other->job;
|
||||
}
|
||||
@ -1577,7 +1577,7 @@ int job_get_after(Job *j, Job*** ret) {
|
||||
if (job_compare(j, other->job, UNIT_AFTER) >= 0)
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(list, n+1))
|
||||
if (!GREEDY_REALLOC(list, n_allocated, n+1))
|
||||
return -ENOMEM;
|
||||
list[n++] = other->job;
|
||||
}
|
||||
|
||||
@ -712,7 +712,7 @@ int config_parse_exec(
|
||||
bool ignore = false, separate_argv0 = false;
|
||||
_cleanup_free_ ExecCommand *nce = NULL;
|
||||
_cleanup_strv_free_ char **n = NULL;
|
||||
size_t nlen = 0;
|
||||
size_t nlen = 0, nbufsize = 0;
|
||||
const char *f;
|
||||
|
||||
semicolon = false;
|
||||
@ -799,7 +799,7 @@ int config_parse_exec(
|
||||
if (!separate_argv0) {
|
||||
char *w = NULL;
|
||||
|
||||
if (!GREEDY_REALLOC(n, nlen + 2))
|
||||
if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
|
||||
return log_oom();
|
||||
|
||||
w = strdup(path);
|
||||
@ -831,7 +831,7 @@ int config_parse_exec(
|
||||
p += 2;
|
||||
p += strspn(p, WHITESPACE);
|
||||
|
||||
if (!GREEDY_REALLOC(n, nlen + 2))
|
||||
if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
|
||||
return log_oom();
|
||||
|
||||
w = strdup(";");
|
||||
@ -856,7 +856,7 @@ int config_parse_exec(
|
||||
return ignore ? 0 : -ENOEXEC;
|
||||
}
|
||||
|
||||
if (!GREEDY_REALLOC(n, nlen + 2))
|
||||
if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
|
||||
return log_oom();
|
||||
|
||||
n[nlen++] = TAKE_PTR(resolved);
|
||||
@ -2691,9 +2691,9 @@ int config_parse_pass_environ(
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_strv_free_ char **n = NULL;
|
||||
const Unit *u = userdata;
|
||||
size_t nlen = 0, nbufsize = 0;
|
||||
char*** passenv = data;
|
||||
size_t nlen = 0;
|
||||
const Unit *u = userdata;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
@ -2737,7 +2737,7 @@ int config_parse_pass_environ(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!GREEDY_REALLOC(n, nlen + 2))
|
||||
if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
|
||||
return log_oom();
|
||||
|
||||
n[nlen++] = TAKE_PTR(k);
|
||||
@ -2766,9 +2766,9 @@ int config_parse_unset_environ(
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_strv_free_ char **n = NULL;
|
||||
size_t nlen = 0, nbufsize = 0;
|
||||
char*** unsetenv = data;
|
||||
const Unit *u = userdata;
|
||||
size_t nlen = 0;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
@ -2812,7 +2812,7 @@ int config_parse_unset_environ(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!GREEDY_REALLOC(n, nlen + 2))
|
||||
if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
|
||||
return log_oom();
|
||||
|
||||
n[nlen++] = TAKE_PTR(k);
|
||||
|
||||
@ -2566,10 +2566,10 @@ static unsigned service_exec_command_index(Unit *u, ServiceExecCommand id, ExecC
|
||||
|
||||
static int service_serialize_exec_command(Unit *u, FILE *f, ExecCommand *command) {
|
||||
_cleanup_free_ char *args = NULL, *p = NULL;
|
||||
size_t allocated = 0, length = 0;
|
||||
Service *s = SERVICE(u);
|
||||
const char *type, *key;
|
||||
ServiceExecCommand id;
|
||||
size_t length = 0;
|
||||
unsigned idx;
|
||||
char **arg;
|
||||
|
||||
@ -2598,7 +2598,7 @@ static int service_serialize_exec_command(Unit *u, FILE *f, ExecCommand *command
|
||||
return log_oom();
|
||||
|
||||
n = strlen(e);
|
||||
if (!GREEDY_REALLOC(args, length + 2 + n + 2))
|
||||
if (!GREEDY_REALLOC(args, allocated, length + 2 + n + 2))
|
||||
return log_oom();
|
||||
|
||||
if (length > 0)
|
||||
@ -2610,7 +2610,7 @@ static int service_serialize_exec_command(Unit *u, FILE *f, ExecCommand *command
|
||||
args[length++] = '"';
|
||||
}
|
||||
|
||||
if (!GREEDY_REALLOC(args, length + 1))
|
||||
if (!GREEDY_REALLOC(args, allocated, length + 1))
|
||||
return log_oom();
|
||||
|
||||
args[length++] = 0;
|
||||
|
||||
@ -247,7 +247,7 @@ static int write_onlycap_list(void) {
|
||||
_cleanup_close_ int onlycap_fd = -1;
|
||||
_cleanup_free_ char *list = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
size_t len = 0;
|
||||
size_t len = 0, allocated = 0;
|
||||
int r;
|
||||
|
||||
f = fopen("/etc/smack/onlycap", "re");
|
||||
@ -272,7 +272,7 @@ static int write_onlycap_list(void) {
|
||||
continue;
|
||||
|
||||
l = strlen(buf);
|
||||
if (!GREEDY_REALLOC(list, len + l + 1))
|
||||
if (!GREEDY_REALLOC(list, allocated, len + l + 1))
|
||||
return log_oom();
|
||||
|
||||
stpcpy(list + len, buf)[0] = ' ';
|
||||
|
||||
@ -330,11 +330,11 @@ _pure_ static bool unit_matters_to_anchor(Unit *u, Job *j) {
|
||||
|
||||
static char* merge_unit_ids(const char* unit_log_field, char **pairs) {
|
||||
char **unit_id, **job_type, *ans = NULL;
|
||||
size_t size = 0, next;
|
||||
size_t alloc = 0, size = 0, next;
|
||||
|
||||
STRV_FOREACH_PAIR(unit_id, job_type, pairs) {
|
||||
next = strlen(unit_log_field) + strlen(*unit_id);
|
||||
if (!GREEDY_REALLOC(ans, size + next + 1))
|
||||
if (!GREEDY_REALLOC(ans, alloc, size + next + 1))
|
||||
return mfree(ans);
|
||||
|
||||
sprintf(ans + size, "%s%s", unit_log_field, *unit_id);
|
||||
|
||||
@ -4004,7 +4004,7 @@ char* unit_escape_setting(const char *s, UnitWriteFlags flags, char **buf) {
|
||||
|
||||
char* unit_concat_strv(char **l, UnitWriteFlags flags) {
|
||||
_cleanup_free_ char *result = NULL;
|
||||
size_t n = 0;
|
||||
size_t n = 0, allocated = 0;
|
||||
char **i;
|
||||
|
||||
/* Takes a list of strings, escapes them, and concatenates them. This may be used to format command lines in a
|
||||
@ -4021,7 +4021,7 @@ char* unit_concat_strv(char **l, UnitWriteFlags flags) {
|
||||
return NULL;
|
||||
|
||||
a = (n > 0) + 1 + strlen(p) + 1; /* separating space + " + entry + " */
|
||||
if (!GREEDY_REALLOC(result, n + a + 1))
|
||||
if (!GREEDY_REALLOC(result, allocated, n + a + 1))
|
||||
return NULL;
|
||||
|
||||
q = result + n;
|
||||
@ -4035,7 +4035,7 @@ char* unit_concat_strv(char **l, UnitWriteFlags flags) {
|
||||
n += a;
|
||||
}
|
||||
|
||||
if (!GREEDY_REALLOC(result, n + 1))
|
||||
if (!GREEDY_REALLOC(result, allocated, n + 1))
|
||||
return NULL;
|
||||
|
||||
result[n] = 0;
|
||||
|
||||
@ -11,8 +11,8 @@ int list_enrolled(struct crypt_device *cd) {
|
||||
int slot;
|
||||
const char *type;
|
||||
} *keyslot_metadata = NULL;
|
||||
size_t n_keyslot_metadata = 0, n_keyslot_metadata_allocated = 0;
|
||||
_cleanup_(table_unrefp) Table *t = NULL;
|
||||
size_t n_keyslot_metadata = 0;
|
||||
int slot_max, r;
|
||||
TableCell *cell;
|
||||
|
||||
@ -27,7 +27,7 @@ int list_enrolled(struct crypt_device *cd) {
|
||||
if (!IN_SET(status, CRYPT_SLOT_ACTIVE, CRYPT_SLOT_ACTIVE_LAST))
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(keyslot_metadata, n_keyslot_metadata+1))
|
||||
if (!GREEDY_REALLOC(keyslot_metadata, n_keyslot_metadata_allocated, n_keyslot_metadata+1))
|
||||
return log_oom();
|
||||
|
||||
keyslot_metadata[n_keyslot_metadata++] = (struct keyslot_metadata) {
|
||||
|
||||
@ -291,7 +291,7 @@ static int enumerate_dir(
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
struct dirent *de;
|
||||
_cleanup_strv_free_ char **files = NULL, **dirs = NULL;
|
||||
size_t n_files = 0, n_dirs = 0;
|
||||
size_t n_files = 0, allocated_files = 0, n_dirs = 0, allocated_dirs = 0;
|
||||
char **t;
|
||||
int r;
|
||||
|
||||
@ -314,7 +314,7 @@ static int enumerate_dir(
|
||||
dirent_ensure_type(d, de);
|
||||
|
||||
if (dropins && de->d_type == DT_DIR && endswith(de->d_name, ".d")) {
|
||||
if (!GREEDY_REALLOC0(dirs, n_dirs + 2))
|
||||
if (!GREEDY_REALLOC0(dirs, allocated_dirs, n_dirs + 2))
|
||||
return -ENOMEM;
|
||||
|
||||
dirs[n_dirs] = strdup(de->d_name);
|
||||
@ -326,7 +326,7 @@ static int enumerate_dir(
|
||||
if (!dirent_is_file(de))
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC0(files, n_files + 2))
|
||||
if (!GREEDY_REALLOC0(files, allocated_files, n_files + 2))
|
||||
return -ENOMEM;
|
||||
|
||||
files[n_files] = strdup(de->d_name);
|
||||
|
||||
@ -73,7 +73,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
|
||||
size_t sw_len = MIN(data_len - 1, h->sw_len);
|
||||
|
||||
r = decompress_startswith(alg, buf, csize, &buf2, h->data, sw_len, h->data[sw_len]);
|
||||
r = decompress_startswith(alg, buf, csize, &buf2, &sw_alloc, h->data, sw_len, h->data[sw_len]);
|
||||
assert_se(r > 0);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -75,6 +75,7 @@ static int pull_job_restart(PullJob *j, const char *new_url) {
|
||||
j->error = 0;
|
||||
j->payload = mfree(j->payload);
|
||||
j->payload_size = 0;
|
||||
j->payload_allocated = 0;
|
||||
j->written_compressed = 0;
|
||||
j->written_uncompressed = 0;
|
||||
j->content_length = UINT64_MAX;
|
||||
@ -265,7 +266,7 @@ static int pull_job_write_uncompressed(const void *p, size_t sz, void *userdata)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Short write");
|
||||
} else {
|
||||
|
||||
if (!GREEDY_REALLOC(j->payload, j->payload_size + sz))
|
||||
if (!GREEDY_REALLOC(j->payload, j->payload_allocated, j->payload_size + sz))
|
||||
return log_oom();
|
||||
|
||||
memcpy(j->payload + j->payload_size, p, sz);
|
||||
@ -370,6 +371,7 @@ static int pull_job_detect_compression(PullJob *j) {
|
||||
|
||||
j->payload = NULL;
|
||||
j->payload_size = 0;
|
||||
j->payload_allocated = 0;
|
||||
|
||||
j->state = PULL_JOB_RUNNING;
|
||||
|
||||
@ -393,7 +395,7 @@ static size_t pull_job_write_callback(void *contents, size_t size, size_t nmemb,
|
||||
case PULL_JOB_ANALYZING:
|
||||
/* Let's first check what it actually is */
|
||||
|
||||
if (!GREEDY_REALLOC(j->payload, j->payload_size + sz)) {
|
||||
if (!GREEDY_REALLOC(j->payload, j->payload_allocated, j->payload_size + sz)) {
|
||||
r = log_oom();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -57,6 +57,7 @@ struct PullJob {
|
||||
|
||||
uint8_t *payload;
|
||||
size_t payload_size;
|
||||
size_t payload_allocated;
|
||||
|
||||
int disk_fd;
|
||||
|
||||
|
||||
@ -171,7 +171,7 @@ static int get_source_for_fd(RemoteServer *s,
|
||||
assert(fd >= 0);
|
||||
assert(source);
|
||||
|
||||
if (!GREEDY_REALLOC0(s->sources, fd + 1))
|
||||
if (!GREEDY_REALLOC0(s->sources, s->sources_size, fd + 1))
|
||||
return log_oom();
|
||||
|
||||
r = journal_remote_get_writer(s, name, &writer);
|
||||
@ -197,7 +197,7 @@ static int remove_source(RemoteServer *s, int fd) {
|
||||
RemoteSource *source;
|
||||
|
||||
assert(s);
|
||||
assert(fd >= 0 && fd < (ssize_t) MALLOC_ELEMENTSOF(s->sources));
|
||||
assert(fd >= 0 && fd < (ssize_t) s->sources_size);
|
||||
|
||||
source = s->sources[fd];
|
||||
if (source) {
|
||||
@ -352,7 +352,8 @@ void journal_remote_server_destroy(RemoteServer *s) {
|
||||
hashmap_free_with_destructor(s->daemons, MHDDaemonWrapper_free);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < MALLOC_ELEMENTSOF(s->sources); i++)
|
||||
assert(s->sources_size == 0 || s->sources);
|
||||
for (i = 0; i < s->sources_size; i++)
|
||||
remove_source(s, i);
|
||||
free(s->sources);
|
||||
|
||||
@ -387,7 +388,7 @@ int journal_remote_handle_raw_source(
|
||||
* 0 if data is currently exhausted, negative on error.
|
||||
*/
|
||||
|
||||
assert(fd >= 0 && fd < (ssize_t) MALLOC_ELEMENTSOF(s->sources));
|
||||
assert(fd >= 0 && fd < (ssize_t) s->sources_size);
|
||||
source = s->sources[fd];
|
||||
assert(source->importer.fd == fd);
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@ struct MHDDaemonWrapper {
|
||||
|
||||
struct RemoteServer {
|
||||
RemoteSource **sources;
|
||||
size_t sources_size;
|
||||
size_t active;
|
||||
|
||||
sd_event *events;
|
||||
|
||||
@ -22,6 +22,7 @@ void dummy_server_init(Server *s, const uint8_t *buffer, size_t size) {
|
||||
if (buffer) {
|
||||
s->buffer = memdup_suffix0(buffer, size);
|
||||
assert_se(s->buffer);
|
||||
s->buffer_size = size + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <malloc.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "audit-type.h"
|
||||
#include "errno-util.h"
|
||||
@ -15,17 +13,12 @@
|
||||
typedef struct MapField {
|
||||
const char *audit_field;
|
||||
const char *journal_field;
|
||||
int (*map)(const char *field, const char **p, struct iovec **iov, size_t *n_iov);
|
||||
int (*map)(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, size_t *n_iov);
|
||||
} MapField;
|
||||
|
||||
static int map_simple_field(
|
||||
const char *field,
|
||||
const char **p,
|
||||
struct iovec **iov,
|
||||
size_t *n_iov) {
|
||||
|
||||
static int map_simple_field(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, size_t *n_iov) {
|
||||
_cleanup_free_ char *c = NULL;
|
||||
size_t l = 0;
|
||||
size_t l = 0, allocated = 0;
|
||||
const char *e;
|
||||
|
||||
assert(field);
|
||||
@ -34,13 +27,14 @@ static int map_simple_field(
|
||||
assert(n_iov);
|
||||
|
||||
l = strlen(field);
|
||||
c = malloc(l + 1);
|
||||
allocated = l + 1;
|
||||
c = malloc(allocated);
|
||||
if (!c)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(c, field, l);
|
||||
for (e = *p; !IN_SET(*e, 0, ' '); e++) {
|
||||
if (!GREEDY_REALLOC(c, l+2))
|
||||
if (!GREEDY_REALLOC(c, allocated, l+2))
|
||||
return -ENOMEM;
|
||||
|
||||
c[l++] = *e;
|
||||
@ -48,7 +42,7 @@ static int map_simple_field(
|
||||
|
||||
c[l] = 0;
|
||||
|
||||
if (!GREEDY_REALLOC(*iov, *n_iov + 1))
|
||||
if (!GREEDY_REALLOC(*iov, *n_iov_allocated, *n_iov + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
(*iov)[(*n_iov)++] = IOVEC_MAKE(c, l);
|
||||
@ -59,13 +53,7 @@ static int map_simple_field(
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int map_string_field_internal(
|
||||
const char *field,
|
||||
const char **p,
|
||||
struct iovec **iov,
|
||||
size_t *n_iov,
|
||||
bool filter_printable) {
|
||||
|
||||
static int map_string_field_internal(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, size_t *n_iov, bool filter_printable) {
|
||||
_cleanup_free_ char *c = NULL;
|
||||
const char *s, *e;
|
||||
size_t l;
|
||||
@ -95,8 +83,11 @@ static int map_string_field_internal(
|
||||
|
||||
} else if (unhexchar(**p) >= 0) {
|
||||
/* Hexadecimal escaping */
|
||||
size_t allocated = 0;
|
||||
|
||||
l = strlen(field);
|
||||
c = malloc(l + 2);
|
||||
allocated = l + 2;
|
||||
c = malloc(allocated);
|
||||
if (!c)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -118,7 +109,7 @@ static int map_string_field_internal(
|
||||
if (filter_printable && x < (uint8_t) ' ')
|
||||
x = (uint8_t) ' ';
|
||||
|
||||
if (!GREEDY_REALLOC(c, l+2))
|
||||
if (!GREEDY_REALLOC(c, allocated, l+2))
|
||||
return -ENOMEM;
|
||||
|
||||
c[l++] = (char) x;
|
||||
@ -128,7 +119,7 @@ static int map_string_field_internal(
|
||||
} else
|
||||
return 0;
|
||||
|
||||
if (!GREEDY_REALLOC(*iov, *n_iov + 1))
|
||||
if (!GREEDY_REALLOC(*iov, *n_iov_allocated, *n_iov + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
(*iov)[(*n_iov)++] = IOVEC_MAKE(c, l);
|
||||
@ -139,20 +130,15 @@ static int map_string_field_internal(
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int map_string_field(const char *field, const char **p, struct iovec **iov, size_t *n_iov) {
|
||||
return map_string_field_internal(field, p, iov, n_iov, false);
|
||||
static int map_string_field(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, size_t *n_iov) {
|
||||
return map_string_field_internal(field, p, iov, n_iov_allocated, n_iov, false);
|
||||
}
|
||||
|
||||
static int map_string_field_printable(const char *field, const char **p, struct iovec **iov, size_t *n_iov) {
|
||||
return map_string_field_internal(field, p, iov, n_iov, true);
|
||||
static int map_string_field_printable(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, size_t *n_iov) {
|
||||
return map_string_field_internal(field, p, iov, n_iov_allocated, n_iov, true);
|
||||
}
|
||||
|
||||
static int map_generic_field(
|
||||
const char *prefix,
|
||||
const char **p,
|
||||
struct iovec **iov,
|
||||
size_t *n_iov) {
|
||||
|
||||
static int map_generic_field(const char *prefix, const char **p, struct iovec **iov, size_t *n_iov_allocated, size_t *n_iov) {
|
||||
const char *e, *f;
|
||||
char *c, *t;
|
||||
int r;
|
||||
@ -196,7 +182,7 @@ static int map_generic_field(
|
||||
|
||||
e++;
|
||||
|
||||
r = map_simple_field(c, &e, iov, n_iov);
|
||||
r = map_simple_field(c, &e, iov, n_iov_allocated, n_iov);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -256,12 +242,14 @@ static int map_all_fields(
|
||||
const char *prefix,
|
||||
bool handle_msg,
|
||||
struct iovec **iov,
|
||||
size_t *n_iov_allocated,
|
||||
size_t *n_iov) {
|
||||
|
||||
int r;
|
||||
|
||||
assert(p);
|
||||
assert(iov);
|
||||
assert(n_iov_allocated);
|
||||
assert(n_iov);
|
||||
|
||||
for (;;) {
|
||||
@ -296,7 +284,7 @@ static int map_all_fields(
|
||||
if (!c)
|
||||
return -ENOMEM;
|
||||
|
||||
return map_all_fields(c, map_fields_userspace, "AUDIT_FIELD_", false, iov, n_iov);
|
||||
return map_all_fields(c, map_fields_userspace, "AUDIT_FIELD_", false, iov, n_iov_allocated, n_iov);
|
||||
}
|
||||
}
|
||||
|
||||
@ -306,7 +294,7 @@ static int map_all_fields(
|
||||
if (!v)
|
||||
continue;
|
||||
|
||||
r = m->map(m->journal_field, &v, iov, n_iov);
|
||||
r = m->map(m->journal_field, &v, iov, n_iov_allocated, n_iov);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to parse audit array: %m");
|
||||
|
||||
@ -318,7 +306,7 @@ static int map_all_fields(
|
||||
}
|
||||
|
||||
if (!mapped) {
|
||||
r = map_generic_field(prefix, &p, iov, n_iov);
|
||||
r = map_generic_field(prefix, &p, iov, n_iov_allocated, n_iov);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to parse audit array: %m");
|
||||
|
||||
@ -330,7 +318,7 @@ static int map_all_fields(
|
||||
}
|
||||
|
||||
void process_audit_string(Server *s, int type, const char *data, size_t size) {
|
||||
size_t n_iov = 0, z;
|
||||
size_t n_iov_allocated = 0, n_iov = 0, z;
|
||||
_cleanup_free_ struct iovec *iov = NULL;
|
||||
uint64_t seconds, msec, id;
|
||||
const char *p, *type_name;
|
||||
@ -371,7 +359,8 @@ void process_audit_string(Server *s, int type, const char *data, size_t size) {
|
||||
if (isempty(p))
|
||||
return;
|
||||
|
||||
iov = new(struct iovec, N_IOVEC_META_FIELDS + 8);
|
||||
n_iov_allocated = N_IOVEC_META_FIELDS + 8;
|
||||
iov = new(struct iovec, n_iov_allocated);
|
||||
if (!iov) {
|
||||
log_oom();
|
||||
return;
|
||||
@ -403,14 +392,14 @@ void process_audit_string(Server *s, int type, const char *data, size_t size) {
|
||||
|
||||
z = n_iov;
|
||||
|
||||
map_all_fields(p, map_fields_kernel, "_AUDIT_FIELD_", true, &iov, &n_iov);
|
||||
map_all_fields(p, map_fields_kernel, "_AUDIT_FIELD_", true, &iov, &n_iov_allocated, &n_iov);
|
||||
|
||||
if (!GREEDY_REALLOC(iov, n_iov + N_IOVEC_META_FIELDS)) {
|
||||
if (!GREEDY_REALLOC(iov, n_iov_allocated, n_iov + N_IOVEC_META_FIELDS)) {
|
||||
log_oom();
|
||||
goto finish;
|
||||
}
|
||||
|
||||
server_dispatch_message(s, iov, n_iov, MALLOC_ELEMENTSOF(iov), NULL, NULL, LOG_NOTICE, 0);
|
||||
server_dispatch_message(s, iov, n_iov, n_iov_allocated, NULL, NULL, LOG_NOTICE, 0);
|
||||
|
||||
finish:
|
||||
/* free() all entries that map_all_fields() added. All others
|
||||
|
||||
@ -378,8 +378,8 @@ static int client_context_read_extra_fields(
|
||||
Server *s,
|
||||
ClientContext *c) {
|
||||
|
||||
size_t size = 0, n_iovec = 0, n_allocated = 0, left;
|
||||
_cleanup_free_ struct iovec *iovec = NULL;
|
||||
size_t size = 0, n_iovec = 0, left;
|
||||
_cleanup_free_ void *data = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
struct stat st;
|
||||
@ -445,7 +445,7 @@ static int client_context_read_extra_fields(
|
||||
if (!journal_field_valid((const char *) field, eq - field, false))
|
||||
return -EBADMSG;
|
||||
|
||||
if (!GREEDY_REALLOC(iovec, n_iovec+1))
|
||||
if (!GREEDY_REALLOC(iovec, n_allocated, n_iovec+1))
|
||||
return -ENOMEM;
|
||||
|
||||
iovec[n_iovec++] = IOVEC_MAKE(field, v);
|
||||
|
||||
@ -105,7 +105,7 @@ static int server_process_entry(
|
||||
*
|
||||
* Note that *remaining is altered on both success and failure. */
|
||||
|
||||
size_t n = 0, j, tn = SIZE_MAX, entry_size = 0;
|
||||
size_t n = 0, j, tn = SIZE_MAX, m = 0, entry_size = 0;
|
||||
char *identifier = NULL, *message = NULL;
|
||||
struct iovec *iovec = NULL;
|
||||
int priority = LOG_INFO;
|
||||
@ -146,7 +146,7 @@ static int server_process_entry(
|
||||
}
|
||||
|
||||
/* n existing properties, 1 new, +1 for _TRANSPORT */
|
||||
if (!GREEDY_REALLOC(iovec,
|
||||
if (!GREEDY_REALLOC(iovec, m,
|
||||
n + 2 +
|
||||
N_IOVEC_META_FIELDS + N_IOVEC_OBJECT_FIELDS +
|
||||
client_context_extra_fields_n_iovec(context))) {
|
||||
@ -273,7 +273,7 @@ static int server_process_entry(
|
||||
server_forward_wall(s, priority, identifier, message, ucred);
|
||||
}
|
||||
|
||||
server_dispatch_message(s, iovec, n, MALLOC_ELEMENTSOF(iovec), context, tv, priority, object_pid);
|
||||
server_dispatch_message(s, iovec, n, m, context, tv, priority, object_pid);
|
||||
|
||||
finish:
|
||||
for (j = 0; j < n; j++) {
|
||||
|
||||
@ -1254,12 +1254,12 @@ int server_process_datagram(
|
||||
uint32_t revents,
|
||||
void *userdata) {
|
||||
|
||||
size_t label_len = 0, m;
|
||||
Server *s = userdata;
|
||||
struct ucred *ucred = NULL;
|
||||
struct timeval *tv = NULL;
|
||||
struct cmsghdr *cmsg;
|
||||
char *label = NULL;
|
||||
size_t label_len = 0, m;
|
||||
struct iovec iovec;
|
||||
ssize_t n;
|
||||
int *fds = NULL, v = 0;
|
||||
@ -1302,10 +1302,10 @@ int server_process_datagram(
|
||||
(size_t) LINE_MAX,
|
||||
ALIGN(sizeof(struct nlmsghdr)) + ALIGN((size_t) MAX_AUDIT_MESSAGE_LENGTH)) + 1);
|
||||
|
||||
if (!GREEDY_REALLOC(s->buffer, m))
|
||||
if (!GREEDY_REALLOC(s->buffer, s->buffer_size, m))
|
||||
return log_oom();
|
||||
|
||||
iovec = IOVEC_MAKE(s->buffer, MALLOC_ELEMENTSOF(s->buffer) - 1); /* Leave room for trailing NUL we add later */
|
||||
iovec = IOVEC_MAKE(s->buffer, s->buffer_size - 1); /* Leave room for trailing NUL we add later */
|
||||
|
||||
n = recvmsg_safe(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
|
||||
if (IN_SET(n, -EINTR, -EAGAIN))
|
||||
|
||||
@ -95,6 +95,7 @@ struct Server {
|
||||
uint64_t seqnum;
|
||||
|
||||
char *buffer;
|
||||
size_t buffer_size;
|
||||
|
||||
JournalRateLimit *ratelimit;
|
||||
usec_t sync_interval_usec;
|
||||
|
||||
@ -90,6 +90,7 @@ struct StdoutStream {
|
||||
|
||||
char *buffer;
|
||||
size_t length;
|
||||
size_t allocated;
|
||||
|
||||
sd_event_source *event_source;
|
||||
|
||||
@ -551,8 +552,8 @@ static int stdout_stream_scan(
|
||||
|
||||
static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
|
||||
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control;
|
||||
size_t limit, consumed, allocated;
|
||||
StdoutStream *s = userdata;
|
||||
size_t limit, consumed;
|
||||
struct ucred *ucred;
|
||||
struct iovec iovec;
|
||||
ssize_t l;
|
||||
@ -574,19 +575,16 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents,
|
||||
}
|
||||
|
||||
/* If the buffer is almost full, add room for another 1K */
|
||||
allocated = MALLOC_ELEMENTSOF(s->buffer);
|
||||
if (s->length + 512 >= allocated) {
|
||||
if (!GREEDY_REALLOC(s->buffer, s->length + 1 + 1024)) {
|
||||
if (s->length + 512 >= s->allocated) {
|
||||
if (!GREEDY_REALLOC(s->buffer, s->allocated, s->length + 1 + 1024)) {
|
||||
log_oom();
|
||||
goto terminate;
|
||||
}
|
||||
|
||||
allocated = MALLOC_ELEMENTSOF(s->buffer);
|
||||
}
|
||||
|
||||
/* Try to make use of the allocated buffer in full, but never read more than the configured line size. Also,
|
||||
* always leave room for a terminating NUL we might need to add. */
|
||||
limit = MIN(allocated - 1, MAX(s->server->line_max, STDOUT_STREAM_SETUP_PROTOCOL_LINE_MAX));
|
||||
limit = MIN(s->allocated - 1, MAX(s->server->line_max, STDOUT_STREAM_SETUP_PROTOCOL_LINE_MAX));
|
||||
assert(s->length <= limit);
|
||||
iovec = IOVEC_MAKE(s->buffer + s->length, limit - s->length);
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@ struct sd_dhcp_lease {
|
||||
DHCPServerData servers[_SD_DHCP_LEASE_SERVER_TYPE_MAX];
|
||||
|
||||
struct sd_dhcp_route *static_route;
|
||||
size_t static_route_size;
|
||||
size_t static_route_size, static_route_allocated;
|
||||
|
||||
uint16_t mtu; /* 0 if unset */
|
||||
|
||||
|
||||
@ -104,7 +104,8 @@ int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
|
||||
int dhcp6_option_parse_status(DHCP6Option *option, size_t len);
|
||||
int dhcp6_option_parse_ia(sd_dhcp6_client *client, DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code);
|
||||
int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
||||
struct in6_addr **addrs, size_t count);
|
||||
struct in6_addr **addrs, size_t count,
|
||||
size_t *allocated);
|
||||
int dhcp6_option_parse_domainname_list(const uint8_t *optval, uint16_t optlen,
|
||||
char ***str_arr);
|
||||
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char **str);
|
||||
|
||||
@ -27,10 +27,12 @@ struct sd_dhcp6_lease {
|
||||
|
||||
struct in6_addr *dns;
|
||||
size_t dns_count;
|
||||
size_t dns_allocated;
|
||||
char **domains;
|
||||
size_t domains_count;
|
||||
struct in6_addr *ntp;
|
||||
size_t ntp_count;
|
||||
size_t ntp_allocated;
|
||||
char **ntp_fqdn;
|
||||
size_t ntp_fqdn_count;
|
||||
char *fqdn;
|
||||
|
||||
@ -678,12 +678,14 @@ int dhcp6_option_parse_ia(sd_dhcp6_client *client, DHCP6Option *iaoption, DHCP6I
|
||||
}
|
||||
|
||||
int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
||||
struct in6_addr **addrs, size_t count) {
|
||||
struct in6_addr **addrs, size_t count,
|
||||
size_t *allocated) {
|
||||
|
||||
if (optlen == 0 || optlen % sizeof(struct in6_addr) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!GREEDY_REALLOC(*addrs, count * sizeof(struct in6_addr) + optlen))
|
||||
if (!GREEDY_REALLOC(*addrs, *allocated,
|
||||
count * sizeof(struct in6_addr) + optlen))
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(*addrs + count, optval, optlen);
|
||||
@ -695,10 +697,10 @@ int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
||||
|
||||
static int parse_domain(const uint8_t **data, uint16_t *len, char **out_domain) {
|
||||
_cleanup_free_ char *ret = NULL;
|
||||
size_t n = 0, allocated = 0;
|
||||
const uint8_t *optval = *data;
|
||||
uint16_t optlen = *len;
|
||||
bool first = true;
|
||||
size_t n = 0;
|
||||
int r;
|
||||
|
||||
if (optlen <= 1)
|
||||
@ -728,7 +730,7 @@ static int parse_domain(const uint8_t **data, uint16_t *len, char **out_domain)
|
||||
optval += c;
|
||||
optlen -= c;
|
||||
|
||||
if (!GREEDY_REALLOC(ret, n + !first + DNS_LABEL_ESCAPED_MAX))
|
||||
if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
|
||||
return -ENOMEM;
|
||||
|
||||
if (first)
|
||||
@ -744,7 +746,7 @@ static int parse_domain(const uint8_t **data, uint16_t *len, char **out_domain)
|
||||
}
|
||||
|
||||
if (n) {
|
||||
if (!GREEDY_REALLOC(ret, n + 1))
|
||||
if (!GREEDY_REALLOC(ret, allocated, n + 1))
|
||||
return -ENOMEM;
|
||||
ret[n] = 0;
|
||||
}
|
||||
|
||||
@ -630,7 +630,7 @@ static int get_dnssl_info(sd_ndisc_router *rt, uint8_t **ret) {
|
||||
_public_ int sd_ndisc_router_dnssl_get_domains(sd_ndisc_router *rt, char ***ret) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
_cleanup_free_ char *e = NULL;
|
||||
size_t n = 0, left;
|
||||
size_t allocated = 0, n = 0, left;
|
||||
uint8_t *ri, *p;
|
||||
bool first = true;
|
||||
int r;
|
||||
@ -691,7 +691,7 @@ _public_ int sd_ndisc_router_dnssl_get_domains(sd_ndisc_router *rt, char ***ret)
|
||||
if (1U + *p + 1U > left)
|
||||
return -EBADMSG;
|
||||
|
||||
if (!GREEDY_REALLOC(e, n + !first + DNS_LABEL_ESCAPED_MAX + 1U))
|
||||
if (!GREEDY_REALLOC(e, allocated, n + !first + DNS_LABEL_ESCAPED_MAX + 1U))
|
||||
return -ENOMEM;
|
||||
|
||||
if (first)
|
||||
|
||||
@ -158,12 +158,13 @@ void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, siz
|
||||
fputs("\n", f);
|
||||
}
|
||||
|
||||
int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, const char *string) {
|
||||
int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string) {
|
||||
_cleanup_free_ struct sd_dhcp_route *routes = NULL;
|
||||
size_t size = 0;
|
||||
size_t size = 0, allocated = 0;
|
||||
|
||||
assert(ret);
|
||||
assert(ret_size);
|
||||
assert(ret_allocated);
|
||||
assert(string);
|
||||
|
||||
/* WORD FORMAT: dst_ip/dst_prefixlen,gw_ip */
|
||||
@ -179,7 +180,7 @@ int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, const
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
if (!GREEDY_REALLOC(routes, size + 1))
|
||||
if (!GREEDY_REALLOC(routes, allocated, size + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
tok = word;
|
||||
@ -219,6 +220,7 @@ int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, const
|
||||
}
|
||||
|
||||
*ret_size = size;
|
||||
*ret_allocated = allocated;
|
||||
*ret = TAKE_PTR(routes);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -22,7 +22,7 @@ struct sd_dhcp_route;
|
||||
struct sd_dhcp_lease;
|
||||
|
||||
void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, size_t size);
|
||||
int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, const char *string);
|
||||
int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string);
|
||||
|
||||
/* It is not necessary to add deserialize_dhcp_option(). Use unhexmem() instead. */
|
||||
int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size);
|
||||
|
||||
@ -440,13 +440,14 @@ static int lease_parse_sip_server(const uint8_t *option, size_t len, struct in_a
|
||||
|
||||
static int lease_parse_routes(
|
||||
const uint8_t *option, size_t len,
|
||||
struct sd_dhcp_route **routes, size_t *routes_size) {
|
||||
struct sd_dhcp_route **routes, size_t *routes_size, size_t *routes_allocated) {
|
||||
|
||||
struct in_addr addr;
|
||||
|
||||
assert(option || len <= 0);
|
||||
assert(routes);
|
||||
assert(routes_size);
|
||||
assert(routes_allocated);
|
||||
|
||||
if (len <= 0)
|
||||
return 0;
|
||||
@ -454,7 +455,7 @@ static int lease_parse_routes(
|
||||
if (len % 8 != 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!GREEDY_REALLOC(*routes, *routes_size + (len / 8)))
|
||||
if (!GREEDY_REALLOC(*routes, *routes_allocated, *routes_size + (len / 8)))
|
||||
return -ENOMEM;
|
||||
|
||||
while (len >= 8) {
|
||||
@ -485,11 +486,12 @@ static int lease_parse_routes(
|
||||
/* parses RFC3442 Classless Static Route Option */
|
||||
static int lease_parse_classless_routes(
|
||||
const uint8_t *option, size_t len,
|
||||
struct sd_dhcp_route **routes, size_t *routes_size) {
|
||||
struct sd_dhcp_route **routes, size_t *routes_size, size_t *routes_allocated) {
|
||||
|
||||
assert(option || len <= 0);
|
||||
assert(routes);
|
||||
assert(routes_size);
|
||||
assert(routes_allocated);
|
||||
|
||||
if (len <= 0)
|
||||
return 0;
|
||||
@ -500,7 +502,7 @@ static int lease_parse_classless_routes(
|
||||
uint8_t dst_octets;
|
||||
struct sd_dhcp_route *route;
|
||||
|
||||
if (!GREEDY_REALLOC(*routes, *routes_size + 1))
|
||||
if (!GREEDY_REALLOC(*routes, *routes_allocated, *routes_size + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
route = *routes + *routes_size;
|
||||
@ -614,7 +616,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
|
||||
break;
|
||||
|
||||
case SD_DHCP_OPTION_STATIC_ROUTE:
|
||||
r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size);
|
||||
r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse static routes, ignoring: %m");
|
||||
break;
|
||||
@ -676,7 +678,8 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
|
||||
r = lease_parse_classless_routes(
|
||||
option, len,
|
||||
&lease->static_route,
|
||||
&lease->static_route_size);
|
||||
&lease->static_route_size,
|
||||
&lease->static_route_allocated);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse classless routes, ignoring: %m");
|
||||
break;
|
||||
@ -744,7 +747,7 @@ int dhcp_lease_parse_search_domains(const uint8_t *option, size_t len, char ***d
|
||||
|
||||
while (pos < len) {
|
||||
_cleanup_free_ char *name = NULL;
|
||||
size_t n = 0;
|
||||
size_t n = 0, allocated = 0;
|
||||
size_t jump_barrier = pos, next_chunk = 0;
|
||||
bool first = true;
|
||||
|
||||
@ -764,7 +767,7 @@ int dhcp_lease_parse_search_domains(const uint8_t *option, size_t len, char ***d
|
||||
if (pos >= len)
|
||||
return -EBADMSG;
|
||||
|
||||
if (!GREEDY_REALLOC(name, n + !first + DNS_LABEL_ESCAPED_MAX))
|
||||
if (!GREEDY_REALLOC(name, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
|
||||
return -ENOMEM;
|
||||
|
||||
if (first)
|
||||
@ -803,7 +806,7 @@ int dhcp_lease_parse_search_domains(const uint8_t *option, size_t len, char ***d
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
if (!GREEDY_REALLOC(name, n + 1))
|
||||
if (!GREEDY_REALLOC(name, allocated, n + 1))
|
||||
return -ENOMEM;
|
||||
name[n] = 0;
|
||||
|
||||
@ -1229,6 +1232,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
||||
r = deserialize_dhcp_routes(
|
||||
&lease->static_route,
|
||||
&lease->static_route_size,
|
||||
&lease->static_route_allocated,
|
||||
routes);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse DHCP routes %s, ignoring: %m", routes);
|
||||
|
||||
@ -66,6 +66,7 @@ struct sd_dhcp6_client {
|
||||
bool information_request;
|
||||
bool iaid_set;
|
||||
be16_t *req_opts;
|
||||
size_t req_opts_allocated;
|
||||
size_t req_opts_len;
|
||||
char *fqdn;
|
||||
char *mudurl;
|
||||
@ -455,7 +456,8 @@ int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, uint16_t option)
|
||||
if (client->req_opts[t] == htobe16(option))
|
||||
return -EEXIST;
|
||||
|
||||
if (!GREEDY_REALLOC(client->req_opts, client->req_opts_len + 1))
|
||||
if (!GREEDY_REALLOC(client->req_opts, client->req_opts_allocated,
|
||||
client->req_opts_len + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
client->req_opts[client->req_opts_len++] = htobe16(option);
|
||||
|
||||
@ -203,7 +203,8 @@ int dhcp6_lease_set_dns(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) {
|
||||
return 0;
|
||||
|
||||
r = dhcp6_option_parse_ip6addrs(optval, optlen, &lease->dns,
|
||||
lease->dns_count);
|
||||
lease->dns_count,
|
||||
&lease->dns_allocated);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -268,6 +269,7 @@ int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) {
|
||||
|
||||
lease->ntp = mfree(lease->ntp);
|
||||
lease->ntp_count = 0;
|
||||
lease->ntp_allocated = 0;
|
||||
|
||||
while ((r = dhcp6_option_parse(&optval, &optlen, &subopt, &sublen,
|
||||
&subval)) >= 0) {
|
||||
@ -282,7 +284,8 @@ int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) {
|
||||
|
||||
s = dhcp6_option_parse_ip6addrs(subval, sublen,
|
||||
&lease->ntp,
|
||||
lease->ntp_count);
|
||||
lease->ntp_count,
|
||||
&lease->ntp_allocated);
|
||||
if (s < 0)
|
||||
return s;
|
||||
|
||||
@ -324,7 +327,8 @@ int dhcp6_lease_set_sntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen)
|
||||
/* Using deprecated SNTP information */
|
||||
|
||||
r = dhcp6_option_parse_ip6addrs(optval, optlen, &lease->ntp,
|
||||
lease->ntp_count);
|
||||
lease->ntp_count,
|
||||
&lease->ntp_allocated);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@ -882,6 +882,8 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
|
||||
if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
|
||||
p = startswith(line, "Groups:");
|
||||
if (p) {
|
||||
size_t allocated = 0;
|
||||
|
||||
for (;;) {
|
||||
unsigned long g;
|
||||
int n = 0;
|
||||
@ -893,7 +895,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
|
||||
if (sscanf(p, "%lu%n", &g, &n) != 1)
|
||||
return -EIO;
|
||||
|
||||
if (!GREEDY_REALLOC(c->supplementary_gids, c->n_supplementary_gids+1))
|
||||
if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
|
||||
return -ENOMEM;
|
||||
|
||||
c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
|
||||
|
||||
@ -222,10 +222,12 @@ struct sd_bus {
|
||||
|
||||
sd_bus_message **rqueue;
|
||||
size_t rqueue_size;
|
||||
size_t rqueue_allocated;
|
||||
|
||||
sd_bus_message **wqueue;
|
||||
size_t wqueue_size;
|
||||
size_t windex;
|
||||
size_t wqueue_allocated;
|
||||
|
||||
uint64_t cookie;
|
||||
uint64_t read_counter; /* A counter for each incoming msg */
|
||||
|
||||
@ -711,6 +711,7 @@ int bus_match_parse(
|
||||
unsigned *ret_n_components) {
|
||||
|
||||
struct bus_match_component *components = NULL;
|
||||
size_t components_allocated = 0;
|
||||
unsigned n_components = 0;
|
||||
int r;
|
||||
|
||||
@ -723,6 +724,7 @@ int bus_match_parse(
|
||||
enum bus_match_node_type t;
|
||||
unsigned j = 0;
|
||||
_cleanup_free_ char *value = NULL;
|
||||
size_t value_allocated = 0;
|
||||
bool escaped = false, quoted;
|
||||
uint8_t u;
|
||||
|
||||
@ -778,7 +780,7 @@ int bus_match_parse(
|
||||
}
|
||||
}
|
||||
|
||||
if (!GREEDY_REALLOC(value, j + 2)) {
|
||||
if (!GREEDY_REALLOC(value, value_allocated, j + 2)) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
@ -804,7 +806,7 @@ int bus_match_parse(
|
||||
} else
|
||||
u = 0;
|
||||
|
||||
if (!GREEDY_REALLOC(components, n_components + 1)) {
|
||||
if (!GREEDY_REALLOC(components, components_allocated, n_components + 1)) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -117,6 +117,7 @@ static void message_reset_containers(sd_bus_message *m) {
|
||||
message_free_last_container(m);
|
||||
|
||||
m->containers = mfree(m->containers);
|
||||
m->containers_allocated = 0;
|
||||
m->root_container.index = 0;
|
||||
}
|
||||
|
||||
@ -1288,7 +1289,7 @@ static int message_add_offset(sd_bus_message *m, size_t offset) {
|
||||
if (!c->need_offsets)
|
||||
return 0;
|
||||
|
||||
if (!GREEDY_REALLOC(c->offsets, c->n_offsets + 1))
|
||||
if (!GREEDY_REALLOC(c->offsets, c->offsets_allocated, c->n_offsets + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
c->offsets[c->n_offsets++] = offset;
|
||||
@ -2030,7 +2031,7 @@ _public_ int sd_bus_message_open_container(
|
||||
assert_return(!m->poisoned, -ESTALE);
|
||||
|
||||
/* Make sure we have space for one more container */
|
||||
if (!GREEDY_REALLOC(m->containers, m->n_containers + 1)) {
|
||||
if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1)) {
|
||||
m->poisoned = true;
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -4110,7 +4111,7 @@ _public_ int sd_bus_message_enter_container(sd_bus_message *m,
|
||||
if (m->n_containers >= BUS_CONTAINER_DEPTH)
|
||||
return -EBADMSG;
|
||||
|
||||
if (!GREEDY_REALLOC(m->containers, m->n_containers + 1))
|
||||
if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
if (message_end_of_signature(m))
|
||||
|
||||
@ -26,7 +26,7 @@ struct bus_container {
|
||||
uint32_t *array_size;
|
||||
|
||||
/* gvariant: list of offsets to end of children if this is struct/dict entry/array */
|
||||
size_t *offsets, n_offsets, offset_index;
|
||||
size_t *offsets, n_offsets, offsets_allocated, offset_index;
|
||||
size_t item_size;
|
||||
|
||||
char *peeked_signature;
|
||||
@ -111,6 +111,7 @@ struct sd_bus_message {
|
||||
|
||||
struct bus_container root_container, *containers;
|
||||
size_t n_containers;
|
||||
size_t containers_allocated;
|
||||
|
||||
struct iovec *iovec;
|
||||
struct iovec iovec_fixed[2];
|
||||
|
||||
@ -700,7 +700,7 @@ int bus_socket_start_auth(sd_bus *b) {
|
||||
static int bus_socket_inotify_setup(sd_bus *b) {
|
||||
_cleanup_free_ int *new_watches = NULL;
|
||||
_cleanup_free_ char *absolute = NULL;
|
||||
size_t n = 0, done = 0, i;
|
||||
size_t n_allocated = 0, n = 0, done = 0, i;
|
||||
unsigned max_follow = 32;
|
||||
const char *p;
|
||||
int wd, r;
|
||||
@ -737,7 +737,7 @@ static int bus_socket_inotify_setup(sd_bus *b) {
|
||||
* that exists we want to know when files are created or moved into it. For all parents of it we just care if
|
||||
* they are removed or renamed. */
|
||||
|
||||
if (!GREEDY_REALLOC(new_watches, n + 1)) {
|
||||
if (!GREEDY_REALLOC(new_watches, n_allocated, n + 1)) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
@ -786,7 +786,7 @@ static int bus_socket_inotify_setup(sd_bus *b) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!GREEDY_REALLOC(new_watches, n + 1)) {
|
||||
if (!GREEDY_REALLOC(new_watches, n_allocated, n + 1)) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -153,11 +153,13 @@ static void bus_reset_queues(sd_bus *b) {
|
||||
bus_message_unref_queued(b->rqueue[--b->rqueue_size], b);
|
||||
|
||||
b->rqueue = mfree(b->rqueue);
|
||||
b->rqueue_allocated = 0;
|
||||
|
||||
while (b->wqueue_size > 0)
|
||||
bus_message_unref_queued(b->wqueue[--b->wqueue_size], b);
|
||||
|
||||
b->wqueue = mfree(b->wqueue);
|
||||
b->wqueue_allocated = 0;
|
||||
}
|
||||
|
||||
static sd_bus* bus_free(sd_bus *b) {
|
||||
@ -251,7 +253,7 @@ _public_ int sd_bus_new(sd_bus **ret) {
|
||||
};
|
||||
|
||||
/* We guarantee that wqueue always has space for at least one entry */
|
||||
if (!GREEDY_REALLOC(b->wqueue, 1))
|
||||
if (!GREEDY_REALLOC(b->wqueue, b->wqueue_allocated, 1))
|
||||
return -ENOMEM;
|
||||
|
||||
assert_se(pthread_mutex_init(&b->memfd_cache_mutex, NULL) == 0);
|
||||
@ -629,8 +631,8 @@ int bus_start_running(sd_bus *bus) {
|
||||
}
|
||||
|
||||
static int parse_address_key(const char **p, const char *key, char **value) {
|
||||
size_t l, n = 0, allocated = 0;
|
||||
_cleanup_free_ char *r = NULL;
|
||||
size_t l, n = 0;
|
||||
const char *a;
|
||||
|
||||
assert(p);
|
||||
@ -673,7 +675,7 @@ static int parse_address_key(const char **p, const char *key, char **value) {
|
||||
a++;
|
||||
}
|
||||
|
||||
if (!GREEDY_REALLOC(r, n + 2))
|
||||
if (!GREEDY_REALLOC(r, allocated, n + 2))
|
||||
return -ENOMEM;
|
||||
|
||||
r[n++] = c;
|
||||
@ -845,6 +847,7 @@ static int parse_exec_address(sd_bus *b, const char **p, char **guid) {
|
||||
char *path = NULL;
|
||||
unsigned n_argv = 0, j;
|
||||
char **argv = NULL;
|
||||
size_t allocated = 0;
|
||||
int r;
|
||||
|
||||
assert(b);
|
||||
@ -878,7 +881,7 @@ static int parse_exec_address(sd_bus *b, const char **p, char **guid) {
|
||||
(*p)++;
|
||||
|
||||
if (ul >= n_argv) {
|
||||
if (!GREEDY_REALLOC0(argv, ul + 2)) {
|
||||
if (!GREEDY_REALLOC0(argv, allocated, ul + 2)) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
@ -2045,7 +2048,7 @@ int bus_rqueue_make_room(sd_bus *bus) {
|
||||
if (bus->rqueue_size >= BUS_RQUEUE_MAX)
|
||||
return -ENOBUFS;
|
||||
|
||||
if (!GREEDY_REALLOC(bus->rqueue, bus->rqueue_size + 1))
|
||||
if (!GREEDY_REALLOC(bus->rqueue, bus->rqueue_allocated, bus->rqueue_size + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
@ -2161,7 +2164,7 @@ _public_ int sd_bus_send(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie) {
|
||||
if (bus->wqueue_size >= BUS_WQUEUE_MAX)
|
||||
return -ENOBUFS;
|
||||
|
||||
if (!GREEDY_REALLOC(bus->wqueue, bus->wqueue_size + 1))
|
||||
if (!GREEDY_REALLOC(bus->wqueue, bus->wqueue_allocated, bus->wqueue_size + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
bus->wqueue[bus->wqueue_size++] = bus_message_ref_queued(m, bus);
|
||||
|
||||
@ -29,7 +29,7 @@ struct sd_device_enumerator {
|
||||
|
||||
DeviceEnumerationType type;
|
||||
sd_device **devices;
|
||||
size_t n_devices, current_device_index;
|
||||
size_t n_devices, n_allocated, current_device_index;
|
||||
bool scan_uptodate;
|
||||
|
||||
Set *match_subsystem;
|
||||
@ -279,7 +279,7 @@ int device_enumerator_add_device(sd_device_enumerator *enumerator, sd_device *de
|
||||
assert_return(enumerator, -EINVAL);
|
||||
assert_return(device, -EINVAL);
|
||||
|
||||
if (!GREEDY_REALLOC(enumerator->devices, enumerator->n_devices + 1))
|
||||
if (!GREEDY_REALLOC(enumerator->devices, enumerator->n_allocated, enumerator->n_devices + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
enumerator->devices[enumerator->n_devices++] = sd_device_ref(device);
|
||||
|
||||
@ -480,6 +480,7 @@ static int device_update_properties_bufs(sd_device *device) {
|
||||
const char *val, *prop;
|
||||
_cleanup_free_ char **buf_strv = NULL;
|
||||
_cleanup_free_ uint8_t *buf_nulstr = NULL;
|
||||
size_t allocated_nulstr = 0;
|
||||
size_t nulstr_len = 0, num = 0, i = 0;
|
||||
|
||||
assert(device);
|
||||
@ -492,7 +493,7 @@ static int device_update_properties_bufs(sd_device *device) {
|
||||
|
||||
len = strlen(prop) + 1 + strlen(val);
|
||||
|
||||
buf_nulstr = GREEDY_REALLOC0(buf_nulstr, nulstr_len + len + 2);
|
||||
buf_nulstr = GREEDY_REALLOC0(buf_nulstr, allocated_nulstr, nulstr_len + len + 2);
|
||||
if (!buf_nulstr)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@ -144,6 +144,7 @@ struct sd_event {
|
||||
unsigned n_sources;
|
||||
|
||||
struct epoll_event *event_queue;
|
||||
size_t event_queue_allocated;
|
||||
|
||||
LIST_HEAD(sd_event_source, sources);
|
||||
|
||||
@ -3857,45 +3858,38 @@ static int epoll_wait_usec(
|
||||
}
|
||||
|
||||
static int process_epoll(sd_event *e, usec_t timeout, int64_t threshold, int64_t *ret_min_priority) {
|
||||
size_t n_event_queue, m, n_event_max;
|
||||
int64_t min_priority = threshold;
|
||||
bool something_new = false;
|
||||
size_t n_event_queue, m;
|
||||
int r;
|
||||
|
||||
assert(e);
|
||||
assert(ret_min_priority);
|
||||
|
||||
n_event_queue = MAX(e->n_sources, 1u);
|
||||
if (!GREEDY_REALLOC(e->event_queue, n_event_queue))
|
||||
if (!GREEDY_REALLOC(e->event_queue, e->event_queue_allocated, n_event_queue))
|
||||
return -ENOMEM;
|
||||
|
||||
n_event_max = MALLOC_ELEMENTSOF(e->event_queue);
|
||||
|
||||
/* If we still have inotify data buffered, then query the other fds, but don't wait on it */
|
||||
if (e->inotify_data_buffered)
|
||||
timeout = 0;
|
||||
|
||||
for (;;) {
|
||||
r = epoll_wait_usec(
|
||||
e->epoll_fd,
|
||||
e->event_queue,
|
||||
n_event_max,
|
||||
timeout);
|
||||
r = epoll_wait_usec(e->epoll_fd, e->event_queue, e->event_queue_allocated, timeout);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
m = (size_t) r;
|
||||
|
||||
if (m < n_event_max)
|
||||
if (m < e->event_queue_allocated)
|
||||
break;
|
||||
|
||||
if (n_event_max >= n_event_queue * 10)
|
||||
if (e->event_queue_allocated >= n_event_queue * 10)
|
||||
break;
|
||||
|
||||
if (!GREEDY_REALLOC(e->event_queue, n_event_max + n_event_queue))
|
||||
if (!GREEDY_REALLOC(e->event_queue, e->event_queue_allocated, e->event_queue_allocated + n_event_queue))
|
||||
return -ENOMEM;
|
||||
|
||||
n_event_max = MALLOC_ELEMENTSOF(e->event_queue);
|
||||
timeout = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -438,12 +438,13 @@ static int inotify_handler(sd_event_source *s, const struct inotify_event *ev, v
|
||||
log_info("inotify-handler <%s>: overflow", description);
|
||||
c->create_overflow |= bit;
|
||||
} else if (ev->mask & IN_CREATE) {
|
||||
if (streq(ev->name, "sub"))
|
||||
log_debug("inotify-handler <%s>: create on %s", description, ev->name);
|
||||
else {
|
||||
unsigned i;
|
||||
unsigned i;
|
||||
|
||||
log_debug("inotify-handler <%s>: create on %s", description, ev->name);
|
||||
|
||||
if (!streq(ev->name, "sub")) {
|
||||
assert_se(safe_atou(ev->name, &i) >= 0);
|
||||
|
||||
assert_se(i < c->n_create_events);
|
||||
c->create_called[i] |= bit;
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ static int catalog_entry_lang(
|
||||
int catalog_import_file(OrderedHashmap *h, const char *path) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
_cleanup_free_ char *payload = NULL;
|
||||
size_t payload_size = 0;
|
||||
size_t payload_size = 0, payload_allocated = 0;
|
||||
unsigned n = 0;
|
||||
sd_id128_t id;
|
||||
_cleanup_free_ char *deflang = NULL, *lang = NULL;
|
||||
@ -345,7 +345,8 @@ int catalog_import_file(OrderedHashmap *h, const char *path) {
|
||||
path, n);
|
||||
|
||||
line_len = strlen(line);
|
||||
if (!GREEDY_REALLOC(payload, payload_size + (empty_line ? 1 : 0) + line_len + 1 + 1))
|
||||
if (!GREEDY_REALLOC(payload, payload_allocated,
|
||||
payload_size + (empty_line ? 1 : 0) + line_len + 1 + 1))
|
||||
return log_oom();
|
||||
|
||||
if (empty_line)
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if HAVE_XZ
|
||||
@ -158,12 +157,8 @@ int compress_blob_zstd(
|
||||
#endif
|
||||
}
|
||||
|
||||
int decompress_blob_xz(
|
||||
const void *src,
|
||||
uint64_t src_size,
|
||||
void **dst,
|
||||
size_t* dst_size,
|
||||
size_t dst_max) {
|
||||
int decompress_blob_xz(const void *src, uint64_t src_size,
|
||||
void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max) {
|
||||
|
||||
#if HAVE_XZ
|
||||
_cleanup_(lzma_end) lzma_stream s = LZMA_STREAM_INIT;
|
||||
@ -173,14 +168,16 @@ int decompress_blob_xz(
|
||||
assert(src);
|
||||
assert(src_size > 0);
|
||||
assert(dst);
|
||||
assert(dst_alloc_size);
|
||||
assert(dst_size);
|
||||
assert(*dst_alloc_size == 0 || *dst);
|
||||
|
||||
ret = lzma_stream_decoder(&s, UINT64_MAX, 0);
|
||||
if (ret != LZMA_OK)
|
||||
return -ENOMEM;
|
||||
|
||||
space = MIN(src_size * 2, dst_max ?: SIZE_MAX);
|
||||
if (!greedy_realloc(dst, space, 1))
|
||||
if (!greedy_realloc(dst, dst_alloc_size, space, 1))
|
||||
return -ENOMEM;
|
||||
|
||||
s.next_in = src;
|
||||
@ -206,7 +203,7 @@ int decompress_blob_xz(
|
||||
|
||||
used = space - s.avail_out;
|
||||
space = MIN(2 * space, dst_max ?: SIZE_MAX);
|
||||
if (!greedy_realloc(dst, space, 1))
|
||||
if (!greedy_realloc(dst, dst_alloc_size, space, 1))
|
||||
return -ENOMEM;
|
||||
|
||||
s.avail_out = space - used;
|
||||
@ -220,12 +217,8 @@ int decompress_blob_xz(
|
||||
#endif
|
||||
}
|
||||
|
||||
int decompress_blob_lz4(
|
||||
const void *src,
|
||||
uint64_t src_size,
|
||||
void **dst,
|
||||
size_t* dst_size,
|
||||
size_t dst_max) {
|
||||
int decompress_blob_lz4(const void *src, uint64_t src_size,
|
||||
void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max) {
|
||||
|
||||
#if HAVE_LZ4
|
||||
char* out;
|
||||
@ -234,7 +227,9 @@ int decompress_blob_lz4(
|
||||
assert(src);
|
||||
assert(src_size > 0);
|
||||
assert(dst);
|
||||
assert(dst_alloc_size);
|
||||
assert(dst_size);
|
||||
assert(*dst_alloc_size == 0 || *dst);
|
||||
|
||||
if (src_size <= 8)
|
||||
return -EBADMSG;
|
||||
@ -242,9 +237,14 @@ int decompress_blob_lz4(
|
||||
size = unaligned_read_le64(src);
|
||||
if (size < 0 || (unsigned) size != unaligned_read_le64(src))
|
||||
return -EFBIG;
|
||||
out = greedy_realloc(dst, size, 1);
|
||||
if (!out)
|
||||
return -ENOMEM;
|
||||
if ((size_t) size > *dst_alloc_size) {
|
||||
out = realloc(*dst, size);
|
||||
if (!out)
|
||||
return -ENOMEM;
|
||||
*dst = out;
|
||||
*dst_alloc_size = size;
|
||||
} else
|
||||
out = *dst;
|
||||
|
||||
r = LZ4_decompress_safe((char*)src + 8, out, src_size - 8, size);
|
||||
if (r < 0 || r != size)
|
||||
@ -258,11 +258,8 @@ int decompress_blob_lz4(
|
||||
}
|
||||
|
||||
int decompress_blob_zstd(
|
||||
const void *src,
|
||||
uint64_t src_size,
|
||||
void **dst,
|
||||
size_t *dst_size,
|
||||
size_t dst_max) {
|
||||
const void *src, uint64_t src_size,
|
||||
void **dst, size_t *dst_alloc_size, size_t *dst_size, size_t dst_max) {
|
||||
|
||||
#if HAVE_ZSTD
|
||||
uint64_t size;
|
||||
@ -270,7 +267,9 @@ int decompress_blob_zstd(
|
||||
assert(src);
|
||||
assert(src_size > 0);
|
||||
assert(dst);
|
||||
assert(dst_alloc_size);
|
||||
assert(dst_size);
|
||||
assert(*dst_alloc_size == 0 || *dst);
|
||||
|
||||
size = ZSTD_getFrameContentSize(src, src_size);
|
||||
if (IN_SET(size, ZSTD_CONTENTSIZE_ERROR, ZSTD_CONTENTSIZE_UNKNOWN))
|
||||
@ -281,7 +280,7 @@ int decompress_blob_zstd(
|
||||
if (size > SIZE_MAX)
|
||||
return -E2BIG;
|
||||
|
||||
if (!(greedy_realloc(dst, MAX(ZSTD_DStreamOutSize(), size), 1)))
|
||||
if (!(greedy_realloc(dst, dst_alloc_size, MAX(ZSTD_DStreamOutSize(), size), 1)))
|
||||
return -ENOMEM;
|
||||
|
||||
_cleanup_(ZSTD_freeDCtxp) ZSTD_DCtx *dctx = ZSTD_createDCtx();
|
||||
@ -294,7 +293,7 @@ int decompress_blob_zstd(
|
||||
};
|
||||
ZSTD_outBuffer output = {
|
||||
.dst = *dst,
|
||||
.size = MALLOC_SIZEOF_SAFE(*dst),
|
||||
.size = *dst_alloc_size,
|
||||
};
|
||||
|
||||
size_t k = ZSTD_decompressStream(dctx, &output, &input);
|
||||
@ -313,63 +312,57 @@ int decompress_blob_zstd(
|
||||
|
||||
int decompress_blob(
|
||||
int compression,
|
||||
const void *src,
|
||||
uint64_t src_size,
|
||||
void **dst,
|
||||
size_t* dst_size,
|
||||
size_t dst_max) {
|
||||
const void *src, uint64_t src_size,
|
||||
void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max) {
|
||||
|
||||
if (compression == OBJECT_COMPRESSED_XZ)
|
||||
return decompress_blob_xz(
|
||||
src, src_size,
|
||||
dst, dst_size, dst_max);
|
||||
dst, dst_alloc_size, dst_size, dst_max);
|
||||
else if (compression == OBJECT_COMPRESSED_LZ4)
|
||||
return decompress_blob_lz4(
|
||||
src, src_size,
|
||||
dst, dst_size, dst_max);
|
||||
dst, dst_alloc_size, dst_size, dst_max);
|
||||
else if (compression == OBJECT_COMPRESSED_ZSTD)
|
||||
return decompress_blob_zstd(
|
||||
src, src_size,
|
||||
dst, dst_size, dst_max);
|
||||
dst, dst_alloc_size, dst_size, dst_max);
|
||||
else
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
int decompress_startswith_xz(
|
||||
const void *src,
|
||||
uint64_t src_size,
|
||||
void **buffer,
|
||||
const void *prefix,
|
||||
size_t prefix_len,
|
||||
uint8_t extra) {
|
||||
int decompress_startswith_xz(const void *src, uint64_t src_size,
|
||||
void **buffer, size_t *buffer_size,
|
||||
const void *prefix, size_t prefix_len,
|
||||
uint8_t extra) {
|
||||
|
||||
#if HAVE_XZ
|
||||
_cleanup_(lzma_end) lzma_stream s = LZMA_STREAM_INIT;
|
||||
size_t allocated;
|
||||
lzma_ret ret;
|
||||
|
||||
/* Checks whether the decompressed blob starts with the mentioned prefix. The byte extra needs to
|
||||
* follow the prefix */
|
||||
/* Checks whether the decompressed blob starts with the
|
||||
* mentioned prefix. The byte extra needs to follow the
|
||||
* prefix */
|
||||
|
||||
assert(src);
|
||||
assert(src_size > 0);
|
||||
assert(buffer);
|
||||
assert(buffer_size);
|
||||
assert(prefix);
|
||||
assert(*buffer_size == 0 || *buffer);
|
||||
|
||||
ret = lzma_stream_decoder(&s, UINT64_MAX, 0);
|
||||
if (ret != LZMA_OK)
|
||||
return -EBADMSG;
|
||||
|
||||
if (!(greedy_realloc(buffer, ALIGN_8(prefix_len + 1), 1)))
|
||||
if (!(greedy_realloc(buffer, buffer_size, ALIGN_8(prefix_len + 1), 1)))
|
||||
return -ENOMEM;
|
||||
|
||||
allocated = MALLOC_SIZEOF_SAFE(*buffer);
|
||||
|
||||
s.next_in = src;
|
||||
s.avail_in = src_size;
|
||||
|
||||
s.next_out = *buffer;
|
||||
s.avail_out = allocated;
|
||||
s.avail_out = *buffer_size;
|
||||
|
||||
for (;;) {
|
||||
ret = lzma_code(&s, LZMA_FINISH);
|
||||
@ -377,20 +370,19 @@ int decompress_startswith_xz(
|
||||
if (!IN_SET(ret, LZMA_OK, LZMA_STREAM_END))
|
||||
return -EBADMSG;
|
||||
|
||||
if (allocated - s.avail_out >= prefix_len + 1)
|
||||
if (*buffer_size - s.avail_out >= prefix_len + 1)
|
||||
return memcmp(*buffer, prefix, prefix_len) == 0 &&
|
||||
((const uint8_t*) *buffer)[prefix_len] == extra;
|
||||
|
||||
if (ret == LZMA_STREAM_END)
|
||||
return 0;
|
||||
|
||||
s.avail_out += allocated;
|
||||
s.avail_out += *buffer_size;
|
||||
|
||||
if (!(greedy_realloc(buffer, allocated * 2, 1)))
|
||||
if (!(greedy_realloc(buffer, buffer_size, *buffer_size * 2, 1)))
|
||||
return -ENOMEM;
|
||||
|
||||
allocated = MALLOC_SIZEOF_SAFE(*buffer);
|
||||
s.next_out = *(uint8_t**)buffer + allocated - s.avail_out;
|
||||
s.next_out = *(uint8_t**)buffer + *buffer_size - s.avail_out;
|
||||
}
|
||||
|
||||
#else
|
||||
@ -398,43 +390,36 @@ int decompress_startswith_xz(
|
||||
#endif
|
||||
}
|
||||
|
||||
int decompress_startswith_lz4(
|
||||
const void *src,
|
||||
uint64_t src_size,
|
||||
void **buffer,
|
||||
const void *prefix,
|
||||
size_t prefix_len,
|
||||
uint8_t extra) {
|
||||
|
||||
int decompress_startswith_lz4(const void *src, uint64_t src_size,
|
||||
void **buffer, size_t *buffer_size,
|
||||
const void *prefix, size_t prefix_len,
|
||||
uint8_t extra) {
|
||||
#if HAVE_LZ4
|
||||
/* Checks whether the decompressed blob starts with the mentioned prefix. The byte extra needs to
|
||||
* follow the prefix */
|
||||
/* Checks whether the decompressed blob starts with the
|
||||
* mentioned prefix. The byte extra needs to follow the
|
||||
* prefix */
|
||||
|
||||
size_t allocated;
|
||||
int r;
|
||||
|
||||
assert(src);
|
||||
assert(src_size > 0);
|
||||
assert(buffer);
|
||||
assert(buffer_size);
|
||||
assert(prefix);
|
||||
assert(*buffer_size == 0 || *buffer);
|
||||
|
||||
if (src_size <= 8)
|
||||
return -EBADMSG;
|
||||
|
||||
if (!(greedy_realloc(buffer, ALIGN_8(prefix_len + 1), 1)))
|
||||
if (!(greedy_realloc(buffer, buffer_size, ALIGN_8(prefix_len + 1), 1)))
|
||||
return -ENOMEM;
|
||||
allocated = MALLOC_SIZEOF_SAFE(*buffer);
|
||||
|
||||
r = LZ4_decompress_safe_partial(
|
||||
(char*)src + 8,
|
||||
*buffer,
|
||||
src_size - 8,
|
||||
prefix_len + 1,
|
||||
allocated);
|
||||
|
||||
/* One lz4 < 1.8.3, we might get "failure" (r < 0), or "success" where just a part of the buffer is
|
||||
* decompressed. But if we get a smaller amount of bytes than requested, we don't know whether there
|
||||
* isn't enough data to fill the requested size or whether we just got a partial answer.
|
||||
r = LZ4_decompress_safe_partial((char*)src + 8, *buffer, src_size - 8,
|
||||
prefix_len + 1, *buffer_size);
|
||||
/* One lz4 < 1.8.3, we might get "failure" (r < 0), or "success" where
|
||||
* just a part of the buffer is decompressed. But if we get a smaller
|
||||
* amount of bytes than requested, we don't know whether there isn't enough
|
||||
* data to fill the requested size or whether we just got a partial answer.
|
||||
*/
|
||||
if (r < 0 || (size_t) r < prefix_len + 1) {
|
||||
size_t size;
|
||||
@ -452,7 +437,7 @@ int decompress_startswith_lz4(
|
||||
|
||||
/* Before version 1.8.3, lz4 always tries to decode full a "sequence",
|
||||
* so in pathological cases might need to decompress the full field. */
|
||||
r = decompress_blob_lz4(src, src_size, buffer, &size, 0);
|
||||
r = decompress_blob_lz4(src, src_size, buffer, buffer_size, &size, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -468,17 +453,17 @@ int decompress_startswith_lz4(
|
||||
}
|
||||
|
||||
int decompress_startswith_zstd(
|
||||
const void *src,
|
||||
uint64_t src_size,
|
||||
void **buffer,
|
||||
const void *prefix,
|
||||
size_t prefix_len,
|
||||
const void *src, uint64_t src_size,
|
||||
void **buffer, size_t *buffer_size,
|
||||
const void *prefix, size_t prefix_len,
|
||||
uint8_t extra) {
|
||||
#if HAVE_ZSTD
|
||||
assert(src);
|
||||
assert(src_size > 0);
|
||||
assert(buffer);
|
||||
assert(buffer_size);
|
||||
assert(prefix);
|
||||
assert(*buffer_size == 0 || *buffer);
|
||||
|
||||
uint64_t size = ZSTD_getFrameContentSize(src, src_size);
|
||||
if (IN_SET(size, ZSTD_CONTENTSIZE_ERROR, ZSTD_CONTENTSIZE_UNKNOWN))
|
||||
@ -491,7 +476,7 @@ int decompress_startswith_zstd(
|
||||
if (!dctx)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!(greedy_realloc(buffer, MAX(ZSTD_DStreamOutSize(), prefix_len + 1), 1)))
|
||||
if (!(greedy_realloc(buffer, buffer_size, MAX(ZSTD_DStreamOutSize(), prefix_len + 1), 1)))
|
||||
return -ENOMEM;
|
||||
|
||||
ZSTD_inBuffer input = {
|
||||
@ -500,7 +485,7 @@ int decompress_startswith_zstd(
|
||||
};
|
||||
ZSTD_outBuffer output = {
|
||||
.dst = *buffer,
|
||||
.size = MALLOC_SIZEOF_SAFE(*buffer),
|
||||
.size = *buffer_size,
|
||||
};
|
||||
size_t k;
|
||||
|
||||
@ -520,30 +505,28 @@ int decompress_startswith_zstd(
|
||||
|
||||
int decompress_startswith(
|
||||
int compression,
|
||||
const void *src,
|
||||
uint64_t src_size,
|
||||
void **buffer,
|
||||
const void *prefix,
|
||||
size_t prefix_len,
|
||||
const void *src, uint64_t src_size,
|
||||
void **buffer, size_t *buffer_size,
|
||||
const void *prefix, size_t prefix_len,
|
||||
uint8_t extra) {
|
||||
|
||||
if (compression == OBJECT_COMPRESSED_XZ)
|
||||
return decompress_startswith_xz(
|
||||
src, src_size,
|
||||
buffer,
|
||||
buffer, buffer_size,
|
||||
prefix, prefix_len,
|
||||
extra);
|
||||
|
||||
else if (compression == OBJECT_COMPRESSED_LZ4)
|
||||
return decompress_startswith_lz4(
|
||||
src, src_size,
|
||||
buffer,
|
||||
buffer, buffer_size,
|
||||
prefix, prefix_len,
|
||||
extra);
|
||||
else if (compression == OBJECT_COMPRESSED_ZSTD)
|
||||
return decompress_startswith_zstd(
|
||||
src, src_size,
|
||||
buffer,
|
||||
buffer, buffer_size,
|
||||
prefix, prefix_len,
|
||||
extra);
|
||||
else
|
||||
|
||||
@ -37,30 +37,30 @@ static inline int compress_blob(const void *src, uint64_t src_size,
|
||||
}
|
||||
|
||||
int decompress_blob_xz(const void *src, uint64_t src_size,
|
||||
void **dst, size_t* dst_size, size_t dst_max);
|
||||
void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max);
|
||||
int decompress_blob_lz4(const void *src, uint64_t src_size,
|
||||
void **dst, size_t* dst_size, size_t dst_max);
|
||||
void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max);
|
||||
int decompress_blob_zstd(const void *src, uint64_t src_size,
|
||||
void **dst, size_t* dst_size, size_t dst_max);
|
||||
void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max);
|
||||
int decompress_blob(int compression,
|
||||
const void *src, uint64_t src_size,
|
||||
void **dst, size_t* dst_size, size_t dst_max);
|
||||
void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max);
|
||||
|
||||
int decompress_startswith_xz(const void *src, uint64_t src_size,
|
||||
void **buffer,
|
||||
void **buffer, size_t *buffer_size,
|
||||
const void *prefix, size_t prefix_len,
|
||||
uint8_t extra);
|
||||
int decompress_startswith_lz4(const void *src, uint64_t src_size,
|
||||
void **buffer,
|
||||
void **buffer, size_t *buffer_size,
|
||||
const void *prefix, size_t prefix_len,
|
||||
uint8_t extra);
|
||||
int decompress_startswith_zstd(const void *src, uint64_t src_size,
|
||||
void **buffer,
|
||||
void **buffer, size_t *buffer_size,
|
||||
const void *prefix, size_t prefix_len,
|
||||
uint8_t extra);
|
||||
int decompress_startswith(int compression,
|
||||
const void *src, uint64_t src_size,
|
||||
void **buffer,
|
||||
void **buffer, size_t *buffer_size,
|
||||
const void *prefix, size_t prefix_len,
|
||||
uint8_t extra);
|
||||
|
||||
|
||||
@ -1495,7 +1495,7 @@ int journal_file_find_data_object_with_hash(
|
||||
l -= offsetof(Object, data.payload);
|
||||
|
||||
r = decompress_blob(o->object.flags & OBJECT_COMPRESSION_MASK,
|
||||
o->data.payload, l, &f->compress_buffer, &rsize, 0);
|
||||
o->data.payload, l, &f->compress_buffer, &f->compress_buffer_size, &rsize, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -3919,11 +3919,8 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
|
||||
#if HAVE_COMPRESSION
|
||||
size_t rsize = 0;
|
||||
|
||||
r = decompress_blob(
|
||||
o->object.flags & OBJECT_COMPRESSION_MASK,
|
||||
o->data.payload, l,
|
||||
&from->compress_buffer, &rsize,
|
||||
0);
|
||||
r = decompress_blob(o->object.flags & OBJECT_COMPRESSION_MASK,
|
||||
o->data.payload, l, &from->compress_buffer, &from->compress_buffer_size, &rsize, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@ -108,6 +108,7 @@ typedef struct JournalFile {
|
||||
uint64_t compress_threshold_bytes;
|
||||
#if HAVE_COMPRESSION
|
||||
void *compress_buffer;
|
||||
size_t compress_buffer_size;
|
||||
#endif
|
||||
|
||||
#if HAVE_GCRYPT
|
||||
|
||||
@ -99,6 +99,7 @@ struct sd_journal {
|
||||
uint64_t fields_offset;
|
||||
uint64_t fields_hash_table_index;
|
||||
char *fields_buffer;
|
||||
size_t fields_buffer_allocated;
|
||||
|
||||
int flags;
|
||||
|
||||
|
||||
@ -127,7 +127,7 @@ int journal_directory_vacuum(
|
||||
bool verbose) {
|
||||
|
||||
uint64_t sum = 0, freed = 0, n_active_files = 0;
|
||||
size_t n_list = 0, i;
|
||||
size_t n_list = 0, n_allocated = 0, i;
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
struct vacuum_info *list = NULL;
|
||||
usec_t retention_limit = 0;
|
||||
@ -262,7 +262,7 @@ int journal_directory_vacuum(
|
||||
|
||||
patch_realtime(dirfd(d), p, &st, &realtime);
|
||||
|
||||
if (!GREEDY_REALLOC(list, n_list + 1)) {
|
||||
if (!GREEDY_REALLOC(list, n_allocated, n_list + 1)) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
@ -153,12 +153,12 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
|
||||
compression = o->object.flags & OBJECT_COMPRESSION_MASK;
|
||||
if (compression) {
|
||||
_cleanup_free_ void *b = NULL;
|
||||
size_t b_size;
|
||||
size_t alloc = 0, b_size;
|
||||
|
||||
r = decompress_blob(compression,
|
||||
o->data.payload,
|
||||
le64toh(o->object.size) - offsetof(Object, data.payload),
|
||||
&b, &b_size, 0);
|
||||
&b, &alloc, &b_size, 0);
|
||||
if (r < 0) {
|
||||
error_errno(offset, r, "%s decompression failed: %m",
|
||||
object_compressed_to_string(compression));
|
||||
|
||||
@ -2321,7 +2321,7 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **
|
||||
#if HAVE_COMPRESSION
|
||||
r = decompress_startswith(compression,
|
||||
o->data.payload, l,
|
||||
&f->compress_buffer,
|
||||
&f->compress_buffer, &f->compress_buffer_size,
|
||||
field, field_length, '=');
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Cannot decompress %s object of length %"PRIu64" at offset "OFSfmt": %m",
|
||||
@ -2332,7 +2332,7 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **
|
||||
|
||||
r = decompress_blob(compression,
|
||||
o->data.payload, l,
|
||||
&f->compress_buffer, &rsize,
|
||||
&f->compress_buffer, &f->compress_buffer_size, &rsize,
|
||||
j->data_threshold);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -2389,11 +2389,9 @@ static int return_data(sd_journal *j, JournalFile *f, Object *o, const void **da
|
||||
size_t rsize;
|
||||
int r;
|
||||
|
||||
r = decompress_blob(
|
||||
compression,
|
||||
o->data.payload, l,
|
||||
&f->compress_buffer, &rsize,
|
||||
j->data_threshold);
|
||||
r = decompress_blob(compression,
|
||||
o->data.payload, l, &f->compress_buffer,
|
||||
&f->compress_buffer_size, &rsize, j->data_threshold);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -3145,7 +3143,7 @@ _public_ int sd_journal_enumerate_fields(sd_journal *j, const char **field) {
|
||||
if (sz > j->data_threshold)
|
||||
sz = j->data_threshold;
|
||||
|
||||
if (!GREEDY_REALLOC(j->fields_buffer, sz + 1))
|
||||
if (!GREEDY_REALLOC(j->fields_buffer, j->fields_buffer_allocated, sz + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(j->fields_buffer, o->field.payload, sz);
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
typedef int (compress_t)(const void *src, uint64_t src_size, void *dst,
|
||||
size_t dst_alloc_size, size_t *dst_size);
|
||||
typedef int (decompress_t)(const void *src, uint64_t src_size,
|
||||
void **dst, size_t* dst_size, size_t dst_max);
|
||||
void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max);
|
||||
|
||||
#if HAVE_COMPRESSION
|
||||
|
||||
@ -80,6 +80,7 @@ static void test_compress_decompress(const char* label, const char* type,
|
||||
|
||||
_cleanup_free_ char *text, *buf;
|
||||
_cleanup_free_ void *buf2 = NULL;
|
||||
size_t buf2_allocated = 0;
|
||||
size_t skipped = 0, compressed = 0, total = 0;
|
||||
|
||||
text = make_buf(MAX_SIZE, type);
|
||||
@ -115,8 +116,9 @@ static void test_compress_decompress(const char* label, const char* type,
|
||||
if (j >= size)
|
||||
log_error("%s \"compressed\" %zu -> %zu", label, size, j);
|
||||
|
||||
r = decompress(buf, j, &buf2, &k, 0);
|
||||
r = decompress(buf, j, &buf2, &buf2_allocated, &k, 0);
|
||||
assert_se(r == 0);
|
||||
assert_se(buf2_allocated >= k);
|
||||
assert_se(k == size);
|
||||
|
||||
assert_se(memcmp(text, buf2, size) == 0);
|
||||
|
||||
@ -34,10 +34,10 @@
|
||||
typedef int (compress_blob_t)(const void *src, uint64_t src_size,
|
||||
void *dst, size_t dst_alloc_size, size_t *dst_size);
|
||||
typedef int (decompress_blob_t)(const void *src, uint64_t src_size,
|
||||
void **dst,
|
||||
void **dst, size_t *dst_alloc_size,
|
||||
size_t* dst_size, size_t dst_max);
|
||||
typedef int (decompress_sw_t)(const void *src, uint64_t src_size,
|
||||
void **buffer,
|
||||
void **buffer, size_t *buffer_size,
|
||||
const void *prefix, size_t prefix_len,
|
||||
uint8_t extra);
|
||||
|
||||
@ -45,16 +45,14 @@ typedef int (compress_stream_t)(int fdf, int fdt, uint64_t max_bytes);
|
||||
typedef int (decompress_stream_t)(int fdf, int fdt, uint64_t max_size);
|
||||
|
||||
#if HAVE_COMPRESSION
|
||||
_unused_ static void test_compress_decompress(
|
||||
const char *compression,
|
||||
compress_blob_t compress,
|
||||
decompress_blob_t decompress,
|
||||
const char *data,
|
||||
size_t data_len,
|
||||
bool may_fail) {
|
||||
|
||||
_unused_ static void test_compress_decompress(const char *compression,
|
||||
compress_blob_t compress,
|
||||
decompress_blob_t decompress,
|
||||
const char *data,
|
||||
size_t data_len,
|
||||
bool may_fail) {
|
||||
char compressed[512];
|
||||
size_t csize;
|
||||
size_t csize, usize = 0;
|
||||
_cleanup_free_ char *decompressed = NULL;
|
||||
int r;
|
||||
|
||||
@ -68,26 +66,26 @@ _unused_ static void test_compress_decompress(
|
||||
} else {
|
||||
assert_se(r == 0);
|
||||
r = decompress(compressed, csize,
|
||||
(void **) &decompressed, &csize, 0);
|
||||
(void **) &decompressed, &usize, &csize, 0);
|
||||
assert_se(r == 0);
|
||||
assert_se(decompressed);
|
||||
assert_se(memcmp(decompressed, data, data_len) == 0);
|
||||
}
|
||||
|
||||
r = decompress("garbage", 7,
|
||||
(void **) &decompressed, &csize, 0);
|
||||
(void **) &decompressed, &usize, &csize, 0);
|
||||
assert_se(r < 0);
|
||||
|
||||
/* make sure to have the minimal lz4 compressed size */
|
||||
r = decompress("00000000\1g", 9,
|
||||
(void **) &decompressed, &csize, 0);
|
||||
(void **) &decompressed, &usize, &csize, 0);
|
||||
assert_se(r < 0);
|
||||
|
||||
r = decompress("\100000000g", 9,
|
||||
(void **) &decompressed, &csize, 0);
|
||||
(void **) &decompressed, &usize, &csize, 0);
|
||||
assert_se(r < 0);
|
||||
|
||||
explicit_bzero_safe(decompressed, MALLOC_SIZEOF_SAFE(decompressed));
|
||||
memzero(decompressed, usize);
|
||||
}
|
||||
|
||||
_unused_ static void test_decompress_startswith(const char *compression,
|
||||
@ -99,7 +97,7 @@ _unused_ static void test_decompress_startswith(const char *compression,
|
||||
|
||||
char *compressed;
|
||||
_cleanup_free_ char *compressed1 = NULL, *compressed2 = NULL, *decompressed = NULL;
|
||||
size_t csize, len;
|
||||
size_t csize, usize = 0, len;
|
||||
int r;
|
||||
|
||||
log_info("/* testing decompress_startswith with %s on %.20s text */",
|
||||
@ -124,17 +122,17 @@ _unused_ static void test_decompress_startswith(const char *compression,
|
||||
|
||||
len = strlen(data);
|
||||
|
||||
r = decompress_sw(compressed, csize, (void **) &decompressed, data, len, '\0');
|
||||
r = decompress_sw(compressed, csize, (void **) &decompressed, &usize, data, len, '\0');
|
||||
assert_se(r > 0);
|
||||
r = decompress_sw(compressed, csize, (void **) &decompressed, data, len, 'w');
|
||||
r = decompress_sw(compressed, csize, (void **) &decompressed, &usize, data, len, 'w');
|
||||
assert_se(r == 0);
|
||||
r = decompress_sw(compressed, csize, (void **) &decompressed, "barbarbar", 9, ' ');
|
||||
r = decompress_sw(compressed, csize, (void **) &decompressed, &usize, "barbarbar", 9, ' ');
|
||||
assert_se(r == 0);
|
||||
r = decompress_sw(compressed, csize, (void **) &decompressed, data, len - 1, data[len-1]);
|
||||
r = decompress_sw(compressed, csize, (void **) &decompressed, &usize, data, len - 1, data[len-1]);
|
||||
assert_se(r > 0);
|
||||
r = decompress_sw(compressed, csize, (void **) &decompressed, data, len - 1, 'w');
|
||||
r = decompress_sw(compressed, csize, (void **) &decompressed, &usize, data, len - 1, 'w');
|
||||
assert_se(r == 0);
|
||||
r = decompress_sw(compressed, csize, (void **) &decompressed, data, len, '\0');
|
||||
r = decompress_sw(compressed, csize, (void **) &decompressed, &usize, data, len, '\0');
|
||||
assert_se(r > 0);
|
||||
}
|
||||
|
||||
@ -154,12 +152,13 @@ _unused_ static void test_decompress_startswith_short(const char *compression,
|
||||
assert_se(r == 0);
|
||||
|
||||
for (i = 1; i < strlen(TEXT); i++) {
|
||||
size_t alloc_size = i;
|
||||
_cleanup_free_ void *buf2 = NULL;
|
||||
|
||||
assert_se(buf2 = malloc(i));
|
||||
|
||||
assert_se(decompress_sw(buf, csize, &buf2, TEXT, i, TEXT[i]) == 1);
|
||||
assert_se(decompress_sw(buf, csize, &buf2, TEXT, i, 'y') == 0);
|
||||
assert_se(decompress_sw(buf, csize, &buf2, &alloc_size, TEXT, i, TEXT[i]) == 1);
|
||||
assert_se(decompress_sw(buf, csize, &buf2, &alloc_size, TEXT, i, 'y') == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -71,11 +71,14 @@ struct sd_netlink {
|
||||
|
||||
sd_netlink_message **rqueue;
|
||||
unsigned rqueue_size;
|
||||
size_t rqueue_allocated;
|
||||
|
||||
sd_netlink_message **rqueue_partial;
|
||||
unsigned rqueue_partial_size;
|
||||
size_t rqueue_partial_allocated;
|
||||
|
||||
struct nlmsghdr *rbuffer;
|
||||
size_t rbuffer_allocated;
|
||||
|
||||
bool processing:1;
|
||||
|
||||
|
||||
@ -1064,7 +1064,7 @@ static int netlink_container_parse(sd_netlink_message *m,
|
||||
struct rtattr *rta,
|
||||
size_t rt_len) {
|
||||
_cleanup_free_ struct netlink_attribute *attributes = NULL;
|
||||
size_t n = 0;
|
||||
size_t n_allocated = 0;
|
||||
|
||||
/* RTA_OK() macro compares with rta->rt_len, which is unsigned short, and
|
||||
* LGTM.com analysis does not like the type difference. Hence, here we
|
||||
@ -1075,7 +1075,7 @@ static int netlink_container_parse(sd_netlink_message *m,
|
||||
|
||||
type = RTA_TYPE(rta);
|
||||
|
||||
if (!GREEDY_REALLOC0(attributes, type + 1))
|
||||
if (!GREEDY_REALLOC0(attributes, n_allocated, type + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
if (attributes[type].offset != 0)
|
||||
@ -1084,13 +1084,10 @@ static int netlink_container_parse(sd_netlink_message *m,
|
||||
attributes[type].offset = (uint8_t *) rta - (uint8_t *) m->hdr;
|
||||
attributes[type].nested = RTA_FLAGS(rta) & NLA_F_NESTED;
|
||||
attributes[type].net_byteorder = RTA_FLAGS(rta) & NLA_F_NET_BYTEORDER;
|
||||
|
||||
if (type + 1U > n)
|
||||
n = type + 1U;
|
||||
}
|
||||
|
||||
container->attributes = TAKE_PTR(attributes);
|
||||
container->n_attributes = n;
|
||||
container->n_attributes = n_allocated;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <malloc.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
@ -298,15 +297,16 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_gr
|
||||
*/
|
||||
int socket_read_message(sd_netlink *rtnl) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *first = NULL;
|
||||
bool multi_part = false, done = false;
|
||||
size_t len, allocated;
|
||||
struct iovec iov = {};
|
||||
uint32_t group = 0;
|
||||
unsigned i = 0;
|
||||
bool multi_part = false, done = false;
|
||||
size_t len;
|
||||
int r;
|
||||
unsigned i = 0;
|
||||
|
||||
assert(rtnl);
|
||||
assert(rtnl->rbuffer);
|
||||
assert(rtnl->rbuffer_allocated >= sizeof(struct nlmsghdr));
|
||||
|
||||
/* read nothing, just get the pending message size */
|
||||
r = socket_recv_message(rtnl->fd, &iov, NULL, true);
|
||||
@ -316,11 +316,12 @@ int socket_read_message(sd_netlink *rtnl) {
|
||||
len = (size_t) r;
|
||||
|
||||
/* make room for the pending message */
|
||||
if (!greedy_realloc((void **)&rtnl->rbuffer, len, sizeof(uint8_t)))
|
||||
if (!greedy_realloc((void **)&rtnl->rbuffer,
|
||||
&rtnl->rbuffer_allocated,
|
||||
len, sizeof(uint8_t)))
|
||||
return -ENOMEM;
|
||||
|
||||
allocated = MALLOC_SIZEOF_SAFE(rtnl->rbuffer);
|
||||
iov = IOVEC_MAKE(rtnl->rbuffer, allocated);
|
||||
iov = IOVEC_MAKE(rtnl->rbuffer, rtnl->rbuffer_allocated);
|
||||
|
||||
/* read the pending message */
|
||||
r = socket_recv_message(rtnl->fd, &iov, &group, false);
|
||||
@ -329,7 +330,7 @@ int socket_read_message(sd_netlink *rtnl) {
|
||||
else
|
||||
len = (size_t) r;
|
||||
|
||||
if (len > allocated)
|
||||
if (len > rtnl->rbuffer_allocated)
|
||||
/* message did not fit in read buffer */
|
||||
return -EIO;
|
||||
|
||||
|
||||
@ -63,7 +63,8 @@ static int sd_netlink_new(sd_netlink **ret) {
|
||||
|
||||
/* We guarantee that the read buffer has at least space for
|
||||
* a message header */
|
||||
if (!greedy_realloc((void**)&rtnl->rbuffer, sizeof(struct nlmsghdr), sizeof(uint8_t)))
|
||||
if (!greedy_realloc((void**)&rtnl->rbuffer, &rtnl->rbuffer_allocated,
|
||||
sizeof(struct nlmsghdr), sizeof(uint8_t)))
|
||||
return -ENOMEM;
|
||||
|
||||
*ret = TAKE_PTR(rtnl);
|
||||
@ -294,7 +295,7 @@ int rtnl_rqueue_make_room(sd_netlink *rtnl) {
|
||||
"rtnl: exhausted the read queue size (%d)",
|
||||
RTNL_RQUEUE_MAX);
|
||||
|
||||
if (!GREEDY_REALLOC(rtnl->rqueue, rtnl->rqueue_size + 1))
|
||||
if (!GREEDY_REALLOC(rtnl->rqueue, rtnl->rqueue_allocated, rtnl->rqueue_size + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
@ -308,7 +309,8 @@ int rtnl_rqueue_partial_make_room(sd_netlink *rtnl) {
|
||||
"rtnl: exhausted the partial read queue size (%d)",
|
||||
RTNL_RQUEUE_MAX);
|
||||
|
||||
if (!GREEDY_REALLOC(rtnl->rqueue_partial, rtnl->rqueue_partial_size + 1))
|
||||
if (!GREEDY_REALLOC(rtnl->rqueue_partial, rtnl->rqueue_partial_allocated,
|
||||
rtnl->rqueue_partial_size + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
|
||||
@ -340,7 +340,7 @@ static int network_link_get_ifindexes(int ifindex, const char *key, int **ret) {
|
||||
char path[STRLEN("/run/systemd/netif/links/") + DECIMAL_STR_MAX(ifindex) + 1];
|
||||
_cleanup_free_ int *ifis = NULL;
|
||||
_cleanup_free_ char *s = NULL;
|
||||
size_t c = 0;
|
||||
size_t allocated = 0, c = 0;
|
||||
int r;
|
||||
|
||||
assert_return(ifindex > 0, -EINVAL);
|
||||
@ -362,7 +362,7 @@ static int network_link_get_ifindexes(int ifindex, const char *key, int **ret) {
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
if (!GREEDY_REALLOC(ifis, c + 2))
|
||||
if (!GREEDY_REALLOC(ifis, allocated, c + 2))
|
||||
return -ENOMEM;
|
||||
|
||||
r = ifis[c++] = parse_ifindex(word);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Originally generated from system-config-keyboard's model list.
|
||||
# Generated from system-config-keyboard's model list
|
||||
# consolelayout xlayout xmodel xvariant xoptions
|
||||
sg ch pc105 de_nodeadkeys terminate:ctrl_alt_bksp
|
||||
nl nl pc105 - terminate:ctrl_alt_bksp
|
||||
@ -63,7 +63,6 @@ by by,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
|
||||
il il pc105 - terminate:ctrl_alt_bksp
|
||||
kazakh kz,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
|
||||
lt.baltic lt pc105 - terminate:ctrl_alt_bksp
|
||||
lt.l4 lt pc105 - terminate:ctrl_alt_bksp
|
||||
lt.l4 lt pc105 - terminate:ctrl_alt_bksp
|
||||
lt lt pc105 - terminate:ctrl_alt_bksp
|
||||
khmer kh,us pc105 - terminate:ctrl_alt_bksp
|
||||
es-dvorak es microsoftpro dvorak terminate:ctrl_alt_bksp
|
||||
|
||||
@ -93,9 +93,9 @@ static void test_vconsole_convert_to_x11(void) {
|
||||
log_info("/* test with known variant, new mapping (es:dvorak) */");
|
||||
assert_se(free_and_strdup(&c.vc_keymap, "es-dvorak") >= 0);
|
||||
|
||||
assert_se(vconsole_convert_to_x11(&c) == 1);
|
||||
assert_se(vconsole_convert_to_x11(&c) == 0); // FIXME
|
||||
assert_se(streq(c.x11_layout, "es"));
|
||||
assert_se(streq(c.x11_variant, "dvorak"));
|
||||
assert_se(c.x11_variant == NULL); // FIXME: "dvorak"
|
||||
|
||||
log_info("/* test with old mapping (fr:latin9) */");
|
||||
assert_se(free_and_strdup(&c.vc_keymap, "fr-latin9") >= 0);
|
||||
|
||||
@ -828,7 +828,7 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus
|
||||
*/
|
||||
if (c != SESSION_GREETER &&
|
||||
vtnr > 0 &&
|
||||
vtnr < MALLOC_ELEMENTSOF(m->seat0->positions) &&
|
||||
vtnr < m->seat0->position_count &&
|
||||
m->seat0->positions[vtnr] &&
|
||||
m->seat0->positions[vtnr]->class != SESSION_GREETER)
|
||||
return sd_bus_error_set(error, BUS_ERROR_SESSION_BUSY, "Already occupied by a session");
|
||||
|
||||
@ -267,25 +267,13 @@ int seat_set_active(Seat *s, Session *session) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Session* seat_get_position(Seat *s, unsigned pos) {
|
||||
assert(s);
|
||||
|
||||
if (pos >= MALLOC_ELEMENTSOF(s->positions))
|
||||
return NULL;
|
||||
|
||||
return s->positions[pos];
|
||||
}
|
||||
|
||||
int seat_switch_to(Seat *s, unsigned num) {
|
||||
Session *session;
|
||||
|
||||
/* Public session positions skip 0 (there is only F1-F12). Maybe it
|
||||
* will get reassigned in the future, so return error for now. */
|
||||
if (num == 0)
|
||||
return -EINVAL;
|
||||
|
||||
session = seat_get_position(s, num);
|
||||
if (!session) {
|
||||
if (num >= s->position_count || !s->positions[num]) {
|
||||
/* allow switching to unused VTs to trigger auto-activate */
|
||||
if (seat_has_vts(s) && num < 64)
|
||||
return chvt(num);
|
||||
@ -293,57 +281,47 @@ int seat_switch_to(Seat *s, unsigned num) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return session_activate(session);
|
||||
return session_activate(s->positions[num]);
|
||||
}
|
||||
|
||||
int seat_switch_to_next(Seat *s) {
|
||||
unsigned start, i;
|
||||
Session *session;
|
||||
|
||||
if (MALLOC_ELEMENTSOF(s->positions) == 0)
|
||||
if (s->position_count == 0)
|
||||
return -EINVAL;
|
||||
|
||||
start = 1;
|
||||
if (s->active && s->active->position > 0)
|
||||
start = s->active->position;
|
||||
|
||||
for (i = start + 1; i < MALLOC_ELEMENTSOF(s->positions); ++i) {
|
||||
session = seat_get_position(s, i);
|
||||
if (session)
|
||||
return session_activate(session);
|
||||
}
|
||||
for (i = start + 1; i < s->position_count; ++i)
|
||||
if (s->positions[i])
|
||||
return session_activate(s->positions[i]);
|
||||
|
||||
for (i = 1; i < start; ++i) {
|
||||
session = seat_get_position(s, i);
|
||||
if (session)
|
||||
return session_activate(session);
|
||||
}
|
||||
for (i = 1; i < start; ++i)
|
||||
if (s->positions[i])
|
||||
return session_activate(s->positions[i]);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int seat_switch_to_previous(Seat *s) {
|
||||
unsigned start, i;
|
||||
Session *session;
|
||||
|
||||
if (MALLOC_ELEMENTSOF(s->positions) == 0)
|
||||
if (s->position_count == 0)
|
||||
return -EINVAL;
|
||||
|
||||
start = 1;
|
||||
if (s->active && s->active->position > 0)
|
||||
start = s->active->position;
|
||||
|
||||
for (i = start - 1; i > 0; --i) {
|
||||
session = seat_get_position(s, i);
|
||||
if (session)
|
||||
return session_activate(session);
|
||||
}
|
||||
for (i = start - 1; i > 0; --i)
|
||||
if (s->positions[i])
|
||||
return session_activate(s->positions[i]);
|
||||
|
||||
for (i = MALLOC_ELEMENTSOF(s->positions) - 1; i > start; --i) {
|
||||
session = seat_get_position(s, i);
|
||||
if (session)
|
||||
return session_activate(session);
|
||||
}
|
||||
for (i = s->position_count - 1; i > start; --i)
|
||||
if (s->positions[i])
|
||||
return session_activate(s->positions[i]);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -490,7 +468,7 @@ void seat_evict_position(Seat *s, Session *session) {
|
||||
if (pos == 0)
|
||||
return;
|
||||
|
||||
if (pos < MALLOC_ELEMENTSOF(s->positions) && s->positions[pos] == session) {
|
||||
if (pos < s->position_count && s->positions[pos] == session) {
|
||||
s->positions[pos] = NULL;
|
||||
|
||||
/* There might be another session claiming the same
|
||||
@ -510,7 +488,7 @@ void seat_claim_position(Seat *s, Session *session, unsigned pos) {
|
||||
if (seat_has_vts(s))
|
||||
pos = session->vtnr;
|
||||
|
||||
if (!GREEDY_REALLOC0(s->positions, pos + 1))
|
||||
if (!GREEDY_REALLOC0(s->positions, s->position_count, pos + 1))
|
||||
return;
|
||||
|
||||
seat_evict_position(s, session);
|
||||
@ -526,7 +504,7 @@ static void seat_assign_position(Seat *s, Session *session) {
|
||||
if (session->position > 0)
|
||||
return;
|
||||
|
||||
for (pos = 1; pos < MALLOC_ELEMENTSOF(s->positions); ++pos)
|
||||
for (pos = 1; pos < s->position_count; ++pos)
|
||||
if (!s->positions[pos])
|
||||
break;
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ struct Seat {
|
||||
LIST_HEAD(Session, sessions);
|
||||
|
||||
Session **positions;
|
||||
size_t position_count;
|
||||
|
||||
bool in_gc_queue:1;
|
||||
bool started:1;
|
||||
|
||||
@ -292,9 +292,9 @@ int machine_load(Machine *m) {
|
||||
(void) deserialize_usec(monotonic, &m->timestamp.monotonic);
|
||||
|
||||
if (netif) {
|
||||
_cleanup_free_ int *ni = NULL;
|
||||
size_t nr = 0;
|
||||
size_t allocated = 0, nr = 0;
|
||||
const char *p;
|
||||
_cleanup_free_ int *ni = NULL;
|
||||
|
||||
p = netif;
|
||||
for (;;) {
|
||||
@ -314,13 +314,14 @@ int machine_load(Machine *m) {
|
||||
if (r < 0)
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(ni, nr + 1))
|
||||
if (!GREEDY_REALLOC(ni, allocated, nr + 1))
|
||||
return log_oom();
|
||||
|
||||
ni[nr++] = r;
|
||||
}
|
||||
|
||||
free_and_replace(m->netif, ni);
|
||||
free(m->netif);
|
||||
m->netif = TAKE_PTR(ni);
|
||||
m->n_netif = nr;
|
||||
}
|
||||
|
||||
|
||||
@ -2261,10 +2261,10 @@ static int list_transfers(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_free_ TransferInfo *transfers = NULL;
|
||||
size_t n_transfers = 0, n_allocated = 0;
|
||||
const char *type, *remote, *local;
|
||||
sd_bus *bus = userdata;
|
||||
uint32_t id, max_id = 0;
|
||||
size_t n_transfers = 0;
|
||||
double progress;
|
||||
int r;
|
||||
|
||||
@ -2281,7 +2281,7 @@ static int list_transfers(int argc, char *argv[], void *userdata) {
|
||||
while ((r = sd_bus_message_read(reply, "(usssdo)", &id, &type, &remote, &local, &progress, NULL)) > 0) {
|
||||
size_t l;
|
||||
|
||||
if (!GREEDY_REALLOC(transfers, n_transfers + 1))
|
||||
if (!GREEDY_REALLOC(transfers, n_allocated, n_transfers + 1))
|
||||
return log_oom();
|
||||
|
||||
transfers[n_transfers].id = id;
|
||||
|
||||
@ -723,7 +723,7 @@ static int find_mount_points(const char *what, char ***list) {
|
||||
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
||||
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
size_t n = 0;
|
||||
size_t bufsize = 0, n = 0;
|
||||
int r;
|
||||
|
||||
assert(what);
|
||||
@ -755,7 +755,7 @@ static int find_mount_points(const char *what, char ***list) {
|
||||
continue;
|
||||
|
||||
/* one extra slot is needed for the terminating NULL */
|
||||
if (!GREEDY_REALLOC0(l, n + 2))
|
||||
if (!GREEDY_REALLOC0(l, bufsize, n + 2))
|
||||
return log_oom();
|
||||
|
||||
l[n] = strdup(target);
|
||||
@ -764,7 +764,7 @@ static int find_mount_points(const char *what, char ***list) {
|
||||
n++;
|
||||
}
|
||||
|
||||
if (!GREEDY_REALLOC0(l, n + 1))
|
||||
if (!GREEDY_REALLOC0(l, bufsize, n + 1))
|
||||
return log_oom();
|
||||
|
||||
*list = TAKE_PTR(l);
|
||||
|
||||
@ -716,7 +716,7 @@ static int acquire_link_info(sd_bus *bus, sd_netlink *rtnl, char **patterns, Lin
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
|
||||
_cleanup_(link_info_array_freep) LinkInfo *links = NULL;
|
||||
_cleanup_close_ int fd = -1;
|
||||
size_t c = 0;
|
||||
size_t allocated = 0, c = 0;
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
@ -742,7 +742,7 @@ static int acquire_link_info(sd_bus *bus, sd_netlink *rtnl, char **patterns, Lin
|
||||
}
|
||||
|
||||
for (sd_netlink_message *i = reply; i; i = sd_netlink_message_next(i)) {
|
||||
if (!GREEDY_REALLOC0(links, c + 2)) /* We keep one trailing one as marker */
|
||||
if (!GREEDY_REALLOC0(links, allocated, c + 2)) /* We keep one trailing one as marker */
|
||||
return -ENOMEM;
|
||||
|
||||
r = decode_link(i, links + c, patterns, matched_patterns);
|
||||
|
||||
@ -82,7 +82,8 @@ static int address_label_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
|
||||
log_link_message_warning_errno(link, m, r, "Could not set address label");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
}
|
||||
} else if (r >= 0)
|
||||
(void) manager_rtnl_process_address(rtnl, m, link->manager);
|
||||
|
||||
if (link->address_label_messages == 0)
|
||||
log_link_debug(link, "Addresses label set");
|
||||
|
||||
@ -653,13 +653,14 @@ static int address_set_netlink_message(const Address *address, sd_netlink_messag
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int address_remove_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg) {
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->address_remove_messages > 0);
|
||||
assert(error_msg);
|
||||
|
||||
link->address_remove_messages--;
|
||||
|
||||
@ -668,12 +669,22 @@ static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EADDRNOTAVAIL)
|
||||
log_link_message_warning_errno(link, m, r, "Could not drop address");
|
||||
log_link_message_warning_errno(link, m, r, error_msg);
|
||||
else if (r >= 0)
|
||||
(void) manager_rtnl_process_address(rtnl, m, link->manager);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int address_remove(const Address *address, Link *link) {
|
||||
static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
return address_remove_handler_internal(rtnl, m, link, "Could not drop address");
|
||||
}
|
||||
|
||||
int address_remove(
|
||||
const Address *address,
|
||||
Link *link,
|
||||
link_netlink_message_handler_t callback) {
|
||||
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||
int r;
|
||||
|
||||
@ -696,7 +707,7 @@ int address_remove(const Address *address, Link *link) {
|
||||
return r;
|
||||
|
||||
r = netlink_call_async(link->manager->rtnl, NULL, req,
|
||||
address_remove_handler,
|
||||
callback ?: address_remove_handler,
|
||||
link_netlink_destroy_callback, link);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||
@ -823,7 +834,7 @@ int link_drop_foreign_addresses(Link *link) {
|
||||
r = k;
|
||||
}
|
||||
} else {
|
||||
k = address_remove(address, link);
|
||||
k = address_remove(address, link, NULL);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
}
|
||||
@ -843,7 +854,7 @@ int link_drop_addresses(Link *link) {
|
||||
if (address->family == AF_INET6 && in6_addr_is_link_local(&address->in_addr.in6) == 1 && link_ipv6ll_enabled(link))
|
||||
continue;
|
||||
|
||||
k = address_remove(address, link);
|
||||
k = address_remove(address, link, NULL);
|
||||
if (k < 0 && r >= 0) {
|
||||
r = k;
|
||||
continue;
|
||||
@ -923,7 +934,8 @@ int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m,
|
||||
log_link_message_warning_errno(link, m, r, error_msg);
|
||||
link_enter_failed(link);
|
||||
return 0;
|
||||
}
|
||||
} else if (r >= 0)
|
||||
(void) manager_rtnl_process_address(rtnl, m, link->manager);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -1422,7 +1434,7 @@ static void static_address_on_acd(sd_ipv4acd *acd, int event, void *userdata) {
|
||||
case SD_IPV4ACD_EVENT_CONFLICT:
|
||||
log_link_warning(link, "DAD conflict. Dropping address "IPV4_ADDRESS_FMT_STR,
|
||||
IPV4_ADDRESS_FMT_VAL(address->in_addr.in));
|
||||
r = address_remove(address, link);
|
||||
r = address_remove(address, link, NULL);
|
||||
if (r < 0)
|
||||
log_link_error_errno(link, r, "Failed to drop DAD conflicted address "IPV4_ADDRESS_FMT_STR,
|
||||
IPV4_ADDRESS_FMT_VAL(address->in_addr.in));
|
||||
|
||||
@ -53,7 +53,8 @@ int address_new(Address **ret);
|
||||
Address *address_free(Address *address);
|
||||
int address_get(Link *link, const Address *in, Address **ret);
|
||||
int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);
|
||||
int address_remove(const Address *address, Link *link);
|
||||
int address_remove_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);
|
||||
int address_remove(const Address *address, Link *link, link_netlink_message_handler_t callback);
|
||||
bool address_equal(const Address *a1, const Address *a2);
|
||||
bool address_is_ready(const Address *a);
|
||||
void address_set_broadcast(Address *a);
|
||||
|
||||
@ -101,8 +101,8 @@ static int link_push_uplink_to_dhcp_server(
|
||||
sd_dhcp_server *s) {
|
||||
|
||||
_cleanup_free_ struct in_addr *addresses = NULL;
|
||||
size_t n_addresses = 0, n_allocated = 0;
|
||||
bool use_dhcp_lease_data = true;
|
||||
size_t n_addresses = 0;
|
||||
|
||||
assert(link);
|
||||
|
||||
@ -131,7 +131,7 @@ static int link_push_uplink_to_dhcp_server(
|
||||
if (in4_addr_is_null(&ia) || in4_addr_is_localhost(&ia))
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(addresses, n_addresses + 1))
|
||||
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
|
||||
return log_oom();
|
||||
|
||||
addresses[n_addresses++] = ia;
|
||||
@ -156,7 +156,7 @@ static int link_push_uplink_to_dhcp_server(
|
||||
if (in4_addr_is_null(&ia.in) || in4_addr_is_localhost(&ia.in))
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(addresses, n_addresses + 1))
|
||||
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
|
||||
return log_oom();
|
||||
|
||||
addresses[n_addresses++] = ia.in;
|
||||
@ -188,7 +188,7 @@ static int link_push_uplink_to_dhcp_server(
|
||||
|
||||
int n = sd_dhcp_lease_get_servers(link->dhcp_lease, what, &da);
|
||||
if (n > 0) {
|
||||
if (!GREEDY_REALLOC(addresses, n_addresses + n))
|
||||
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
|
||||
return log_oom();
|
||||
|
||||
for (int j = 0; j < n; j++)
|
||||
@ -203,11 +203,7 @@ static int link_push_uplink_to_dhcp_server(
|
||||
return sd_dhcp_server_set_servers(s, what, addresses, n_addresses);
|
||||
}
|
||||
|
||||
static int dhcp4_server_parse_dns_server_string_and_warn(
|
||||
const char *string,
|
||||
struct in_addr **addresses,
|
||||
size_t *n_addresses) {
|
||||
|
||||
static int dhcp4_server_parse_dns_server_string_and_warn(Link *l, const char *string, struct in_addr **addresses, size_t *n_allocated, size_t *n_addresses) {
|
||||
for (;;) {
|
||||
_cleanup_free_ char *word = NULL, *server_name = NULL;
|
||||
union in_addr_union address;
|
||||
@ -233,7 +229,7 @@ static int dhcp4_server_parse_dns_server_string_and_warn(
|
||||
if (in4_addr_is_null(&address.in) || in4_addr_is_localhost(&address.in))
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(*addresses, *n_addresses + 1))
|
||||
if (!GREEDY_REALLOC(*addresses, *n_allocated, *n_addresses + 1))
|
||||
return log_oom();
|
||||
|
||||
(*addresses)[(*n_addresses)++] = address.in;
|
||||
@ -244,8 +240,8 @@ static int dhcp4_server_parse_dns_server_string_and_warn(
|
||||
|
||||
static int dhcp4_server_set_dns_from_resolve_conf(Link *link) {
|
||||
_cleanup_free_ struct in_addr *addresses = NULL;
|
||||
size_t n_addresses = 0, n_allocated = 0;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
size_t n_addresses = 0;
|
||||
int n = 0, r;
|
||||
|
||||
f = fopen(PRIVATE_UPLINK_RESOLV_CONF, "re");
|
||||
@ -277,7 +273,7 @@ static int dhcp4_server_set_dns_from_resolve_conf(Link *link) {
|
||||
if (!a)
|
||||
continue;
|
||||
|
||||
r = dhcp4_server_parse_dns_server_string_and_warn(a, &addresses, &n_addresses);
|
||||
r = dhcp4_server_parse_dns_server_string_and_warn(link, a, &addresses, &n_allocated, &n_addresses);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to parse DNS server address '%s', ignoring.", a);
|
||||
}
|
||||
|
||||
@ -66,13 +66,13 @@ static int dhcp4_release_old_lease(Link *link) {
|
||||
log_link_debug(link, "Removing old DHCPv4 address and routes.");
|
||||
|
||||
SET_FOREACH(route, link->dhcp_routes_old) {
|
||||
k = route_remove(route, NULL, link);
|
||||
k = route_remove(route, NULL, link, NULL);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
}
|
||||
|
||||
if (link->dhcp_address_old) {
|
||||
k = address_remove(link->dhcp_address_old, link);
|
||||
k = address_remove(link->dhcp_address_old, link, NULL);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
}
|
||||
@ -180,10 +180,6 @@ static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *li
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
|
||||
r = dhcp4_request_address_and_routes(link, false);
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -716,6 +712,48 @@ static int dhcp_reset_hostname(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp4_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->dhcp4_remove_messages > 0);
|
||||
|
||||
link->dhcp4_remove_messages--;
|
||||
|
||||
r = link_route_remove_handler_internal(rtnl, m, link, "Failed to remove DHCPv4 route, ignoring");
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
if (link->dhcp4_remove_messages == 0) {
|
||||
r = dhcp4_request_address_and_routes(link, false);
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dhcp4_address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->dhcp4_remove_messages > 0);
|
||||
|
||||
link->dhcp4_remove_messages--;
|
||||
|
||||
r = address_remove_handler_internal(rtnl, m, link, "Failed to remove DHCPv4 address, ignoring");
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
if (link->dhcp4_remove_messages == 0) {
|
||||
r = dhcp4_request_address_and_routes(link, false);
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dhcp4_remove_all(Link *link) {
|
||||
Route *route;
|
||||
int k, r = 0;
|
||||
@ -723,15 +761,19 @@ static int dhcp4_remove_all(Link *link) {
|
||||
assert(link);
|
||||
|
||||
SET_FOREACH(route, link->dhcp_routes) {
|
||||
k = route_remove(route, NULL, link);
|
||||
k = route_remove(route, NULL, link, dhcp4_route_remove_handler);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
else
|
||||
link->dhcp4_remove_messages++;
|
||||
}
|
||||
|
||||
if (link->dhcp_address) {
|
||||
k = address_remove(link->dhcp_address, link);
|
||||
k = address_remove(link->dhcp_address, link, dhcp4_address_remove_handler);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
else
|
||||
link->dhcp4_remove_messages++;
|
||||
}
|
||||
|
||||
return r;
|
||||
@ -948,7 +990,7 @@ static int dhcp4_after_address_configure(Request *req, void *object) {
|
||||
if (link->dhcp_address_old &&
|
||||
!address_equal(link->dhcp_address_old, link->dhcp_address)) {
|
||||
/* Still too old address exists? Let's remove it immediately. */
|
||||
r = address_remove(link->dhcp_address_old, link);
|
||||
r = address_remove(link->dhcp_address_old, link, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -170,7 +170,7 @@ static int dhcp6_pd_remove_old(Link *link, bool force) {
|
||||
log_link_debug(link, "Removing old DHCPv6 Prefix Delegation addresses and routes.");
|
||||
|
||||
SET_FOREACH(route, link->dhcp6_pd_routes_old) {
|
||||
k = route_remove(route, NULL, link);
|
||||
k = route_remove(route, NULL, link, NULL);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
|
||||
@ -180,7 +180,7 @@ static int dhcp6_pd_remove_old(Link *link, bool force) {
|
||||
}
|
||||
|
||||
SET_FOREACH(address, link->dhcp6_pd_addresses_old) {
|
||||
k = address_remove(address, link);
|
||||
k = address_remove(address, link, NULL);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
}
|
||||
@ -212,7 +212,7 @@ int dhcp6_pd_remove(Link *link) {
|
||||
log_link_debug(link, "Removing DHCPv6 Prefix Delegation addresses and routes.");
|
||||
|
||||
SET_FOREACH(route, link->dhcp6_pd_routes) {
|
||||
k = route_remove(route, NULL, link);
|
||||
k = route_remove(route, NULL, link, NULL);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
|
||||
@ -222,7 +222,7 @@ int dhcp6_pd_remove(Link *link) {
|
||||
}
|
||||
|
||||
SET_FOREACH(address, link->dhcp6_pd_addresses) {
|
||||
k = address_remove(address, link);
|
||||
k = address_remove(address, link, NULL);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
}
|
||||
@ -761,13 +761,13 @@ static int dhcp6_remove_old(Link *link, bool force) {
|
||||
log_link_debug(link, "Removing old DHCPv6 addresses and routes.");
|
||||
|
||||
SET_FOREACH(route, link->dhcp6_routes_old) {
|
||||
k = route_remove(route, NULL, link);
|
||||
k = route_remove(route, NULL, link, NULL);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
}
|
||||
|
||||
SET_FOREACH(address, link->dhcp6_addresses_old) {
|
||||
k = address_remove(address, link);
|
||||
k = address_remove(address, link, NULL);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
}
|
||||
@ -795,13 +795,13 @@ static int dhcp6_remove(Link *link) {
|
||||
log_link_debug(link, "Removing DHCPv6 addresses and routes.");
|
||||
|
||||
SET_FOREACH(route, link->dhcp6_routes) {
|
||||
k = route_remove(route, NULL, link);
|
||||
k = route_remove(route, NULL, link, NULL);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
}
|
||||
|
||||
SET_FOREACH(address, link->dhcp6_addresses) {
|
||||
k = address_remove(address, link);
|
||||
k = address_remove(address, link, NULL);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ static int ipv4ll_address_lost(Link *link) {
|
||||
log_link_debug(link, "IPv4 link-local release "IPV4_ADDRESS_FMT_STR,
|
||||
IPV4_ADDRESS_FMT_VAL(address->in_addr.in));
|
||||
|
||||
return address_remove(address, link);
|
||||
return address_remove(address, link, NULL);
|
||||
}
|
||||
|
||||
static int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
|
||||
@ -138,7 +138,7 @@ bool link_ipv6_enabled(Link *link) {
|
||||
bool link_is_ready_to_configure(Link *link, bool allow_unmanaged) {
|
||||
assert(link);
|
||||
|
||||
if (!link->network) {
|
||||
if (!link->network || link->network->unmanaged) {
|
||||
if (!allow_unmanaged)
|
||||
return false;
|
||||
|
||||
@ -552,28 +552,14 @@ int link_get(Manager *m, int ifindex, Link **ret) {
|
||||
|
||||
assert(m);
|
||||
assert(ifindex > 0);
|
||||
assert(ret);
|
||||
|
||||
link = hashmap_get(m->links, INT_TO_PTR(ifindex));
|
||||
if (!link)
|
||||
return -ENODEV;
|
||||
|
||||
if (ret)
|
||||
*ret = link;
|
||||
return 0;
|
||||
}
|
||||
*ret = link;
|
||||
|
||||
int link_get_by_name(Manager *m, const char *ifname, Link **ret) {
|
||||
Link *link;
|
||||
|
||||
assert(m);
|
||||
assert(ifname);
|
||||
|
||||
link = hashmap_get(m->links_by_name, ifname);
|
||||
if (!link)
|
||||
return -ENODEV;
|
||||
|
||||
if (ret)
|
||||
*ret = link;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1723,8 +1709,6 @@ static void link_drop_requests(Link *link) {
|
||||
|
||||
|
||||
static Link *link_drop(Link *link) {
|
||||
char **n;
|
||||
|
||||
if (!link)
|
||||
return NULL;
|
||||
|
||||
@ -1750,11 +1734,6 @@ static Link *link_drop(Link *link) {
|
||||
(void) unlink(link->state_file);
|
||||
link_clean(link);
|
||||
|
||||
STRV_FOREACH(n, link->alternative_names)
|
||||
hashmap_remove(link->manager->links_by_name, *n);
|
||||
|
||||
hashmap_remove(link->manager->links_by_name, link->ifname);
|
||||
|
||||
/* The following must be called at last. */
|
||||
assert_se(hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)) == link);
|
||||
return link_unref(link);
|
||||
@ -2225,33 +2204,8 @@ static int link_get_network(Link *link, Network **ret) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int link_update_alternative_names(Link *link, sd_netlink_message *message) {
|
||||
_cleanup_strv_free_ char **altnames = NULL;
|
||||
char **n;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(message);
|
||||
|
||||
r = sd_netlink_message_read_strv(message, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &altnames);
|
||||
if (r < 0 && r != -ENODATA)
|
||||
return r;
|
||||
|
||||
STRV_FOREACH(n, link->alternative_names)
|
||||
hashmap_remove(link->manager->links_by_name, *n);
|
||||
|
||||
strv_free_and_replace(link->alternative_names, altnames);
|
||||
|
||||
STRV_FOREACH(n, link->alternative_names) {
|
||||
r = hashmap_ensure_put(&link->manager->links_by_name, &string_hash_ops, *n, link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool force) {
|
||||
_cleanup_strv_free_ char **s = NULL;
|
||||
Network *network;
|
||||
int r;
|
||||
|
||||
@ -2261,10 +2215,12 @@ static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool for
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = link_update_alternative_names(link, m);
|
||||
if (r < 0)
|
||||
r = sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &s);
|
||||
if (r < 0 && r != -ENODATA)
|
||||
return r;
|
||||
|
||||
strv_free_and_replace(link->alternative_names, s);
|
||||
|
||||
r = link_get_network(link, &network);
|
||||
if (r == -ENOENT) {
|
||||
link_enter_unmanaged(link);
|
||||
@ -2430,6 +2386,7 @@ static int link_initialized_and_synced(Link *link) {
|
||||
}
|
||||
|
||||
static int link_initialized_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
_cleanup_strv_free_ char **s = NULL;
|
||||
int r;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
@ -2439,12 +2396,14 @@ static int link_initialized_handler(sd_netlink *rtnl, sd_netlink_message *m, Lin
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = link_update_alternative_names(link, m);
|
||||
if (r < 0) {
|
||||
r = sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &s);
|
||||
if (r < 0 && r != -ENODATA) {
|
||||
link_enter_failed(link);
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
strv_free_and_replace(link->alternative_names, s);
|
||||
|
||||
r = link_initialized_and_synced(link);
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
@ -2588,6 +2547,10 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
|
||||
if (r < 0)
|
||||
log_link_debug_errno(link, r, "Failed to get driver, continuing without: %m");
|
||||
|
||||
r = sd_netlink_message_read_strv(message, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &link->alternative_names);
|
||||
if (r < 0 && r != -ENODATA)
|
||||
return r;
|
||||
|
||||
if (asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -2597,14 +2560,6 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
|
||||
if (asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d", link->ifindex) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
r = hashmap_ensure_put(&manager->links_by_name, &string_hash_ops, link->ifname, link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = link_update_alternative_names(link, message);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = link_update_flags(link, message, false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -2922,6 +2877,7 @@ static int link_admin_state_down(Link *link) {
|
||||
}
|
||||
|
||||
static int link_update(Link *link, sd_netlink_message *m) {
|
||||
_cleanup_strv_free_ char **s = NULL;
|
||||
hw_addr_data hw_addr;
|
||||
const char *ifname;
|
||||
uint32_t mtu;
|
||||
@ -2951,12 +2907,12 @@ static int link_update(Link *link, sd_netlink_message *m) {
|
||||
r = link_add(manager, m, &link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else {
|
||||
r = link_update_alternative_names(link, m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &s);
|
||||
if (r >= 0)
|
||||
strv_free_and_replace(link->alternative_names, s);
|
||||
|
||||
r = sd_netlink_message_read_u32(m, IFLA_MTU, &mtu);
|
||||
if (r >= 0 && mtu > 0) {
|
||||
link->mtu = mtu;
|
||||
|
||||
@ -112,6 +112,7 @@ typedef struct Link {
|
||||
char *lease_file;
|
||||
uint32_t original_mtu;
|
||||
unsigned dhcp4_messages;
|
||||
unsigned dhcp4_remove_messages;
|
||||
sd_ipv4acd *dhcp_acd;
|
||||
bool dhcp4_route_failed:1;
|
||||
bool dhcp4_route_retrying:1;
|
||||
@ -210,7 +211,6 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref);
|
||||
DEFINE_TRIVIAL_DESTRUCTOR(link_netlink_destroy_callback, Link, link_unref);
|
||||
|
||||
int link_get(Manager *m, int ifindex, Link **ret);
|
||||
int link_get_by_name(Manager *m, const char *ifname, Link **ret);
|
||||
|
||||
int link_up(Link *link);
|
||||
int link_down(Link *link, link_netlink_message_handler_t callback);
|
||||
|
||||
@ -459,7 +459,6 @@ Manager* manager_free(Manager *m) {
|
||||
|
||||
m->dirty_links = set_free_with_destructor(m->dirty_links, link_unref);
|
||||
m->links_requesting_uuid = set_free_with_destructor(m->links_requesting_uuid, link_unref);
|
||||
m->links_by_name = hashmap_free(m->links_by_name);
|
||||
m->links = hashmap_free_with_destructor(m->links, link_unref);
|
||||
|
||||
m->networks = ordered_hashmap_free_with_destructor(m->networks, network_unref);
|
||||
|
||||
@ -45,7 +45,6 @@ struct Manager {
|
||||
LinkOnlineState online_state;
|
||||
|
||||
Hashmap *links;
|
||||
Hashmap *links_by_name;
|
||||
Hashmap *netdevs;
|
||||
OrderedHashmap *networks;
|
||||
Hashmap *dhcp6_prefixes;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user