1
0
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.

147 changed files with 854 additions and 886 deletions

View File

@ -6,7 +6,6 @@ ADDITIONAL_DEPS=(
clang
expect
fdisk
jekyll
libfdisk-dev
libfido2-dev
libp11-kit-dev

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;
}
}
}
void* greedy_realloc0(
void **p,
size_t need,
size_t size) {
*p = q;
*allocated = newalloc;
return q;
}
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;
}

View File

@ -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))

View File

@ -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;

View File

@ -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 */

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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] = ' ';

View File

@ -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);

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -57,6 +57,7 @@ struct PullJob {
uint8_t *payload;
size_t payload_size;
size_t payload_allocated;
int disk_fd;

View File

@ -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);

View File

@ -23,6 +23,7 @@ struct MHDDaemonWrapper {
struct RemoteServer {
RemoteSource **sources;
size_t sources_size;
size_t active;
sd_event *events;

View File

@ -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;
}
}

View File

@ -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

View File

@ -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);

View File

@ -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++) {

View File

@ -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))

View File

@ -95,6 +95,7 @@ struct Server {
uint64_t seqnum;
char *buffer;
size_t buffer_size;
JournalRateLimit *ratelimit;
usec_t sync_interval_usec;

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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 */

View File

@ -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;
}

View File

@ -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))

View File

@ -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];

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
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;
}

View File

@ -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)

View File

@ -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 ((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,
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,
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

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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));

View File

@ -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);

View File

@ -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);

View File

@ -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,
_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);
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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
@ -66,4 +66,3 @@ lt.baltic 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

View File

@ -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);

View File

@ -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");

View File

@ -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;

View File

@ -19,6 +19,7 @@ struct Seat {
LIST_HEAD(Session, sessions);
Session **positions;
size_t position_count;
bool in_gc_queue:1;
bool started:1;

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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");

View File

@ -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));

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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;
}
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;

View File

@ -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);

View File

@ -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);

View File

@ -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