1
0
mirror of https://github.com/systemd/systemd synced 2026-03-30 19:54:51 +02:00

Compare commits

...

12 Commits

Author SHA1 Message Date
Yu Watanabe
81218ac1e1
Merge pull request #21001 from poettering/alloca-safe
honour ALLOCA_MAX limit on all alloca() allocations, not just some
2021-10-15 00:57:27 +09:00
Lennart Poettering
82fb0911fc homework: fix incorrect error variable use 2021-10-15 00:56:57 +09:00
Yu Watanabe
3780f3993f
Merge pull request #21006 from DaanDeMeyer/mkosi-ordering
mkosi: Add number prefixes to per-distro files for easier overriding
2021-10-15 00:07:21 +09:00
Lennart Poettering
e3bde91293 doc: document that alloca_safe() and friends are the APIs to use 2021-10-14 15:57:52 +02:00
Lennart Poettering
2f82562bad alloc-util: add strdupa_safe() + strndupa_safe() and use it everywhere
Let's define two helpers strdupa_safe() + strndupa_safe() which do the
same as their non-safe counterparts, except that they abort if called
with allocations larger than ALLOCA_MAX.

This should ensure that all our alloca() based allocations are subject
to this limit.

afaics glibc offers three alloca() based APIs: alloca() itself,
strndupa() + strdupa(). With this we have now replacements for all of
them, that take the limit into account.
2021-10-14 15:57:52 +02:00
Lennart Poettering
5222651ecc journal: drop unnecessary +1 in newa() expression
newa() does this internally anyway, no need to do this explicitly.
2021-10-14 15:57:52 +02:00
Lennart Poettering
698cec65c4 tree-wide: port all calls to alloca() to alloca_safe() 2021-10-14 15:57:52 +02:00
Lennart Poettering
5e76324eea alloca-util: drop two unnecessary casts
memset() already returns void*, no need to cast it to that.
2021-10-14 15:57:52 +02:00
Lennart Poettering
9e1a759903 alloc-util: introduce new helper alloca_safe()
This is like alloca(), but does two things:

1. Verifies the allocation is smaller than ALLOCA_MAX
2. Ensures we allocate at least one byte

This was previously done manually in all invocations. This adds a handy
helper that does that implicitly.
2021-10-14 15:57:52 +02:00
Dan Streetman
a69f1dd9ca cgroup: when checking for legacy controllers, ignore any we don't care about 2021-10-14 14:57:49 +02:00
Daan De Meyer
6da99d33a4 Ignore local files in subdirectories of mkosi.default.d/ as well 2021-10-14 14:07:16 +02:00
Daan De Meyer
1427e56dfd mkosi: Add number prefixes to per-distro files for easier overriding
This allows developers to add override files to override per-distro settings.
2021-10-14 14:06:53 +02:00
74 changed files with 216 additions and 173 deletions

2
.gitignore vendored
View File

@ -37,5 +37,5 @@ __pycache__/
/mkosi.output/ /mkosi.output/
/mkosi.default /mkosi.default
# Ignore any mkosi config files with "local" in the name # Ignore any mkosi config files with "local" in the name
/mkosi.default.d/*local*.conf /mkosi.default.d/**/*local*.conf
/tags /tags

11
coccinelle/strdupa.cocci Normal file
View File

@ -0,0 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
@@
expression x;
@@
- strdupa(x)
+ strdupa_safe(x)
@@
expression x, n;
@@
- strndupa(x, n)
+ strndupa_safe(x, n)

View File

@ -365,10 +365,11 @@ SPDX-License-Identifier: LGPL-2.1-or-later
- Avoid fixed-size string buffers, unless you really know the maximum size and - Avoid fixed-size string buffers, unless you really know the maximum size and
that maximum size is small. It is often nicer to use dynamic memory, that maximum size is small. It is often nicer to use dynamic memory,
`alloca()` or VLAs. If you do allocate fixed-size strings on the stack, then `alloca_safe()` or VLAs. If you do allocate fixed-size strings on the stack,
it is probably only OK if you either use a maximum size such as `LINE_MAX`, then it is probably only OK if you either use a maximum size such as
or count in detail the maximum size a string can have. (`DECIMAL_STR_MAX` and `LINE_MAX`, or count in detail the maximum size a string can
`DECIMAL_STR_WIDTH` macros are your friends for this!) have. (`DECIMAL_STR_MAX` and `DECIMAL_STR_WIDTH` macros are your friends for
this!)
Or in other words, if you use `char buf[256]` then you are likely doing Or in other words, if you use `char buf[256]` then you are likely doing
something wrong! something wrong!
@ -376,13 +377,20 @@ SPDX-License-Identifier: LGPL-2.1-or-later
- Make use of `_cleanup_free_` and friends. It makes your code much nicer to - Make use of `_cleanup_free_` and friends. It makes your code much nicer to
read (and shorter)! read (and shorter)!
- Use `alloca()`, but never forget that it is not OK to invoke `alloca()` - Do not use `alloca()`, `strdupa()` or `strndupa()` directly. Use
within a loop or within function call parameters. `alloca()` memory is `alloca_safe()`, `strdupa_safe()` or `strndupa_safe()` instead. (The
released at the end of a function, and not at the end of a `{}` block. Thus, difference is that the latter include an assertion that the specified size is
if you invoke it in a loop, you keep increasing the stack pointer without below a safety threshold, so that the program rather aborts than runs into
ever releasing memory again. (VLAs have better behavior in this case, so possible stack overruns.)
consider using them as an alternative.) Regarding not using `alloca()`
within function parameters, see the BUGS section of the `alloca(3)` man page. - Use `alloca_safe()`, but never forget that it is not OK to invoke
`alloca_safe()` within a loop or within function call
parameters. `alloca_safe()` memory is released at the end of a function, and
not at the end of a `{}` block. Thus, if you invoke it in a loop, you keep
increasing the stack pointer without ever releasing memory again. (VLAs have
better behavior in this case, so consider using them as an alternative.)
Regarding not using `alloca_safe()` within function parameters, see the BUGS
section of the `alloca(3)` man page.
- If you want to concatenate two or more strings, consider using `strjoina()` - If you want to concatenate two or more strings, consider using `strjoina()`
or `strjoin()` rather than `asprintf()`, as the latter is a lot slower. This or `strjoin()` rather than `asprintf()`, as the latter is a lot slower. This

View File

@ -387,7 +387,7 @@ static int run(int argc, char *argv[]) {
if (!sysname) if (!sysname)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Requires a subsystem and sysname pair specifying a backlight device."); return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Requires a subsystem and sysname pair specifying a backlight device.");
ss = strndupa(argv[2], sysname - argv[2]); ss = strndupa_safe(argv[2], sysname - argv[2]);
sysname++; sysname++;

View File

@ -22,20 +22,25 @@ typedef void (*free_func_t)(void *p);
#define new0(t, n) ((t*) calloc((n) ?: 1, sizeof(t))) #define new0(t, n) ((t*) calloc((n) ?: 1, sizeof(t)))
#define alloca_safe(n) \
({ \
size_t _nn_ = n; \
assert(_nn_ <= ALLOCA_MAX); \
alloca(_nn_ == 0 ? 1 : _nn_); \
}) \
#define newa(t, n) \ #define newa(t, n) \
({ \ ({ \
size_t _n_ = n; \ size_t _n_ = n; \
assert(!size_multiply_overflow(sizeof(t), _n_)); \ assert(!size_multiply_overflow(sizeof(t), _n_)); \
assert(sizeof(t)*_n_ <= ALLOCA_MAX); \ (t*) alloca_safe(sizeof(t)*_n_); \
(t*) alloca((sizeof(t)*_n_) ?: 1); \
}) })
#define newa0(t, n) \ #define newa0(t, n) \
({ \ ({ \
size_t _n_ = n; \ size_t _n_ = n; \
assert(!size_multiply_overflow(sizeof(t), _n_)); \ assert(!size_multiply_overflow(sizeof(t), _n_)); \
assert(sizeof(t)*_n_ <= ALLOCA_MAX); \ (t*) alloca0((sizeof(t)*_n_)); \
(t*) alloca0((sizeof(t)*_n_) ?: 1); \
}) })
#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n))) #define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
@ -67,8 +72,7 @@ void* memdup_suffix0(const void *p, size_t l); /* We can't use _alloc_() here, s
({ \ ({ \
void *_q_; \ void *_q_; \
size_t _l_ = l; \ size_t _l_ = l; \
assert(_l_ <= ALLOCA_MAX); \ _q_ = alloca_safe(_l_); \
_q_ = alloca(_l_ ?: 1); \
memcpy_safe(_q_, p, _l_); \ memcpy_safe(_q_, p, _l_); \
}) })
@ -76,8 +80,7 @@ void* memdup_suffix0(const void *p, size_t l); /* We can't use _alloc_() here, s
({ \ ({ \
void *_q_; \ void *_q_; \
size_t _l_ = l; \ size_t _l_ = l; \
assert(_l_ <= ALLOCA_MAX); \ _q_ = alloca_safe(_l_ + 1); \
_q_ = alloca(_l_ + 1); \
((uint8_t*) _q_)[_l_] = 0; \ ((uint8_t*) _q_)[_l_] = 0; \
memcpy_safe(_q_, p, _l_); \ memcpy_safe(_q_, p, _l_); \
}) })
@ -144,9 +147,8 @@ void* greedy_realloc0(void **p, size_t need, size_t size);
({ \ ({ \
char *_new_; \ char *_new_; \
size_t _len_ = n; \ size_t _len_ = n; \
assert(_len_ <= ALLOCA_MAX); \ _new_ = alloca_safe(_len_); \
_new_ = alloca(_len_ ?: 1); \ memset(_new_, 0, _len_); \
(void *) memset(_new_, 0, _len_); \
}) })
/* It's not clear what alignment glibc/gcc alloca() guarantee, hence provide a guaranteed safe version */ /* It's not clear what alignment glibc/gcc alloca() guarantee, hence provide a guaranteed safe version */
@ -155,8 +157,7 @@ void* greedy_realloc0(void **p, size_t need, size_t size);
void *_ptr_; \ void *_ptr_; \
size_t _mask_ = (align) - 1; \ size_t _mask_ = (align) - 1; \
size_t _size_ = size; \ size_t _size_ = size; \
assert(_size_ <= ALLOCA_MAX); \ _ptr_ = alloca_safe(_size_ + _mask_); \
_ptr_ = alloca((_size_ + _mask_) ?: 1); \
(void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_); \ (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_); \
}) })
@ -165,7 +166,7 @@ void* greedy_realloc0(void **p, size_t need, size_t size);
void *_new_; \ void *_new_; \
size_t _xsize_ = (size); \ size_t _xsize_ = (size); \
_new_ = alloca_align(_xsize_, (align)); \ _new_ = alloca_align(_xsize_, (align)); \
(void*)memset(_new_, 0, _xsize_); \ memset(_new_, 0, _xsize_); \
}) })
#if HAS_FEATURE_MEMORY_SANITIZER #if HAS_FEATURE_MEMORY_SANITIZER
@ -193,3 +194,19 @@ void* greedy_realloc0(void **p, size_t need, size_t size);
__builtin_types_compatible_p(typeof(x), typeof(&*(x))), \ __builtin_types_compatible_p(typeof(x), typeof(&*(x))), \
MALLOC_SIZEOF_SAFE(x)/sizeof((x)[0]), \ MALLOC_SIZEOF_SAFE(x)/sizeof((x)[0]), \
VOID_0)) VOID_0))
/* These are like strdupa()/strndupa(), but honour ALLOCA_MAX */
#define strdupa_safe(s) \
({ \
const char *_t = (s); \
(char*) memdupa_suffix0(_t, strlen(_t)); \
})
#define strndupa_safe(s, n) \
({ \
const char *_t = (s); \
(char*) memdupa_suffix0(_t, strnlen(_t, (n))); \
})
#include "memory-util.h"

View File

@ -1131,7 +1131,7 @@ int cg_path_decode_unit(const char *cgroup, char **unit) {
if (n < 3) if (n < 3)
return -ENXIO; return -ENXIO;
c = strndupa(cgroup, n); c = strndupa_safe(cgroup, n);
c = cg_unescape(c); c = cg_unescape(c);
if (!unit_name_is_valid(c, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) if (!unit_name_is_valid(c, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))

View File

@ -394,7 +394,7 @@ int strv_env_replace_consume(char ***l, char *p) {
return -EINVAL; return -EINVAL;
} }
name = strndupa(p, t - p); name = strndupa_safe(p, t - p);
STRV_FOREACH(f, *l) STRV_FOREACH(f, *l)
if (env_entry_has_name(*f, name)) { if (env_entry_has_name(*f, name)) {
@ -481,7 +481,7 @@ char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) {
if (flags & REPLACE_ENV_USE_ENVIRONMENT) { if (flags & REPLACE_ENV_USE_ENVIRONMENT) {
const char *t; const char *t;
t = strndupa(name, k); t = strndupa_safe(name, k);
return getenv(t); return getenv(t);
}; };
@ -804,7 +804,7 @@ int putenv_dup(const char *assignment, bool override) {
if (!e) if (!e)
return -EINVAL; return -EINVAL;
n = strndupa(assignment, e - assignment); n = strndupa_safe(assignment, e - assignment);
/* This is like putenv(), but uses setenv() so that our memory doesn't become part of environ[]. */ /* This is like putenv(), but uses setenv() so that our memory doesn't become part of environ[]. */
if (setenv(n, e + 1, override) < 0) if (setenv(n, e + 1, override) < 0)

View File

@ -56,7 +56,7 @@ int rmdir_parents(const char *path, const char *stop) {
if (!path_is_safe(stop)) if (!path_is_safe(stop))
return -EINVAL; return -EINVAL;
p = strdupa(path); p = strdupa_safe(path);
for (;;) { for (;;) {
char *slash = NULL; char *slash = NULL;

View File

@ -1073,7 +1073,9 @@ int log_struct_iovec_internal(
for (size_t i = 0; i < n_input_iovec; i++) for (size_t i = 0; i < n_input_iovec; i++)
if (memory_startswith(input_iovec[i].iov_base, input_iovec[i].iov_len, "MESSAGE=")) { if (memory_startswith(input_iovec[i].iov_base, input_iovec[i].iov_len, "MESSAGE=")) {
char *m = strndupa(input_iovec[i].iov_base + STRLEN("MESSAGE="), char *m;
m = strndupa_safe((char*) input_iovec[i].iov_base + STRLEN("MESSAGE="),
input_iovec[i].iov_len - STRLEN("MESSAGE=")); input_iovec[i].iov_len - STRLEN("MESSAGE="));
return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, m); return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, m);

View File

@ -126,7 +126,7 @@ int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, ui
assert(*e == '/'); assert(*e == '/');
/* drop the last component */ /* drop the last component */
path = strndupa(path, e - path); path = strndupa_safe(path, e - path);
r = is_dir(path, true); r = is_dir(path, true);
if (r > 0) if (r > 0)
return 0; return 0;

View File

@ -156,7 +156,7 @@ static bool filename_possibly_with_slash_suffix(const char *s) {
if (slash[strspn(slash, "/")] != 0) /* Check that the suffix consist only of one or more slashes */ if (slash[strspn(slash, "/")] != 0) /* Check that the suffix consist only of one or more slashes */
return false; return false;
copied = strndupa(s, slash - s); copied = strndupa_safe(s, slash - s);
return filename_is_valid(copied); return filename_is_valid(copied);
} }

View File

@ -704,7 +704,7 @@ int parse_dev(const char *s, dev_t *ret) {
if (s[n] != ':') if (s[n] != ':')
return -EINVAL; return -EINVAL;
major = strndupa(s, n); major = strndupa_safe(s, n);
r = safe_atou(major, &x); r = safe_atou(major, &x);
if (r < 0) if (r < 0)
return r; return r;
@ -765,7 +765,7 @@ int parse_loadavg_fixed_point(const char *s, loadavg_t *ret) {
if (!d) if (!d)
return -EINVAL; return -EINVAL;
i_str = strndupa(s, d - s); i_str = strndupa_safe(s, d - s);
f_str = d + 1; f_str = d + 1;
r = safe_atolu_full(i_str, 10, &i); r = safe_atolu_full(i_str, 10, &i);

View File

@ -489,7 +489,7 @@ static int get_paths_from_environ(const char *var, char ***paths, bool *append)
k = endswith(e, ":"); k = endswith(e, ":");
if (k) { if (k) {
e = strndupa(e, k - e); e = strndupa_safe(e, k - e);
*append = true; *append = true;
} }

View File

@ -12,7 +12,7 @@ static int parse_parts_value_whole(const char *p, const char *symbol) {
if (!pc) if (!pc)
return -EINVAL; return -EINVAL;
n = strndupa(p, pc - p); n = strndupa_safe(p, pc - p);
r = safe_atoi(n, &v); r = safe_atoi(n, &v);
if (r < 0) if (r < 0)
return r; return r;
@ -37,10 +37,10 @@ static int parse_parts_value_with_tenths_place(const char *p, const char *symbol
if (dot[1] < '0' || dot[1] > '9') if (dot[1] < '0' || dot[1] > '9')
return -EINVAL; return -EINVAL;
q = dot[1] - '0'; q = dot[1] - '0';
n = strndupa(p, dot - p); n = strndupa_safe(p, dot - p);
} else { } else {
q = 0; q = 0;
n = strndupa(p, pc - p); n = strndupa_safe(p, pc - p);
} }
r = safe_atoi(n, &v); r = safe_atoi(n, &v);
if (r < 0) if (r < 0)
@ -81,10 +81,10 @@ static int parse_parts_value_with_hundredths_place(const char *p, const char *sy
/* We do not support zero or more than two places */ /* We do not support zero or more than two places */
return -EINVAL; return -EINVAL;
n = strndupa(p, dot - p); n = strndupa_safe(p, dot - p);
} else { } else {
q = 0; q = 0;
n = strndupa(p, pc - p); n = strndupa_safe(p, pc - p);
} }
r = safe_atoi(n, &v); r = safe_atoi(n, &v);
if (r < 0) if (r < 0)

View File

@ -135,7 +135,7 @@ int procfs_tasks_get_current(uint64_t *ret) {
p++; p++;
n = strspn(p, DIGITS); n = strspn(p, DIGITS);
nr = strndupa(p, n); nr = strndupa_safe(p, n);
return safe_atou64(nr, ret); return safe_atou64(nr, ret);
} }

View File

@ -671,7 +671,7 @@ static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
goto finish; goto finish;
} else if ((k = endswith(t, " ago"))) { } else if ((k = endswith(t, " ago"))) {
t = strndupa(t, k - t); t = strndupa_safe(t, k - t);
r = parse_sec(t, &minus); r = parse_sec(t, &minus);
if (r < 0) if (r < 0)
@ -680,7 +680,7 @@ static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
goto finish; goto finish;
} else if ((k = endswith(t, " left"))) { } else if ((k = endswith(t, " left"))) {
t = strndupa(t, k - t); t = strndupa_safe(t, k - t);
r = parse_sec(t, &plus); r = parse_sec(t, &plus);
if (r < 0) if (r < 0)
@ -692,7 +692,7 @@ static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
/* See if the timestamp is suffixed with UTC */ /* See if the timestamp is suffixed with UTC */
utc = endswith_no_case(t, " UTC"); utc = endswith_no_case(t, " UTC");
if (utc) if (utc)
t = strndupa(t, utc - t); t = strndupa_safe(t, utc - t);
else { else {
const char *e = NULL; const char *e = NULL;
int j; int j;
@ -723,7 +723,7 @@ static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
if (IN_SET(j, 0, 1)) { if (IN_SET(j, 0, 1)) {
/* Found one of the two timezones specified. */ /* Found one of the two timezones specified. */
t = strndupa(t, e - t - 1); t = strndupa_safe(t, e - t - 1);
dst = j; dst = j;
tzn = tzname[j]; tzn = tzname[j];
} }
@ -924,7 +924,7 @@ int parse_timestamp(const char *t, usec_t *usec) {
/* Cut off the timezone if we don't need it. */ /* Cut off the timezone if we don't need it. */
if (with_tz) if (with_tz)
t = strndupa(t, last_space - t); t = strndupa_safe(t, last_space - t);
shared->return_value = parse_timestamp_impl(t, &shared->usec, with_tz); shared->return_value = parse_timestamp_impl(t, &shared->usec, with_tz);

View File

@ -162,7 +162,7 @@ static int parse_counter(
"Can't parse empty 'tries left' counter from LoaderBootCountPath: %s", "Can't parse empty 'tries left' counter from LoaderBootCountPath: %s",
path); path);
z = strndupa(e, k); z = strndupa_safe(e, k);
r = safe_atou64(z, &left); r = safe_atou64(z, &left);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse 'tries left' counter from LoaderBootCountPath: %s", path); return log_error_errno(r, "Failed to parse 'tries left' counter from LoaderBootCountPath: %s", path);
@ -178,7 +178,7 @@ static int parse_counter(
"Can't parse empty 'tries done' counter from LoaderBootCountPath: %s", "Can't parse empty 'tries done' counter from LoaderBootCountPath: %s",
path); path);
z = strndupa(e, k); z = strndupa_safe(e, k);
r = safe_atou64(z, &done); r = safe_atou64(z, &done);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse 'tries done' counter from LoaderBootCountPath: %s", path); return log_error_errno(r, "Failed to parse 'tries done' counter from LoaderBootCountPath: %s", path);

View File

@ -365,7 +365,7 @@ static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) {
assert(where); assert(where);
l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1; l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
param = alloca(l); param = alloca_safe(l);
init_autofs_dev_ioctl(param); init_autofs_dev_ioctl(param);
param->size = l; param->size = l;

View File

@ -3437,7 +3437,7 @@ Unit* manager_get_unit_by_cgroup(Manager *m, const char *cgroup) {
if (u) if (u)
return u; return u;
p = strdupa(cgroup); p = strdupa_safe(cgroup);
for (;;) { for (;;) {
char *e; char *e;

View File

@ -3462,7 +3462,7 @@ int bus_exec_context_set_transient_property(
if (soft) { if (soft) {
const char *n; const char *n;
n = strndupa(suffix, soft - suffix); n = strndupa_safe(suffix, soft - suffix);
ri = rlimit_from_string(n); ri = rlimit_from_string(n);
if (ri >= 0) if (ri >= 0)
name = strjoina("Limit", n); name = strjoina("Limit", n);

View File

@ -117,7 +117,7 @@ int bus_set_transient_usec_internal(
else else
*p = v; *p = v;
char *n = strndupa(name, strlen(name) - 4); char *n = strndupa_safe(name, strlen(name) - 4);
unit_write_settingf(u, flags, name, "%sSec=%s", n, FORMAT_TIMESPAN(v, USEC_PER_MSEC)); unit_write_settingf(u, flags, name, "%sSec=%s", n, FORMAT_TIMESPAN(v, USEC_PER_MSEC));
} }

View File

@ -6524,7 +6524,7 @@ int exec_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds) {
assert(fds); assert(fds);
n = strcspn(v, " "); n = strcspn(v, " ");
id = strndupa(v, n); id = strndupa_safe(v, n);
if (v[n] != ' ') if (v[n] != ' ')
goto finalize; goto finalize;
p = v + n + 1; p = v + n + 1;
@ -6556,7 +6556,7 @@ int exec_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds) {
char *buf; char *buf;
n = strcspn(v, " "); n = strcspn(v, " ");
buf = strndupa(v, n); buf = strndupa_safe(v, n);
r = safe_atoi(buf, &netns_fdpair[0]); r = safe_atoi(buf, &netns_fdpair[0]);
if (r < 0) if (r < 0)
@ -6575,7 +6575,7 @@ int exec_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds) {
char *buf; char *buf;
n = strcspn(v, " "); n = strcspn(v, " ");
buf = strndupa(v, n); buf = strndupa_safe(v, n);
r = safe_atoi(buf, &netns_fdpair[1]); r = safe_atoi(buf, &netns_fdpair[1]);
if (r < 0) if (r < 0)
@ -6594,7 +6594,7 @@ int exec_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds) {
char *buf; char *buf;
n = strcspn(v, " "); n = strcspn(v, " ");
buf = strndupa(v, n); buf = strndupa_safe(v, n);
r = safe_atoi(buf, &ipcns_fdpair[0]); r = safe_atoi(buf, &ipcns_fdpair[0]);
if (r < 0) if (r < 0)
@ -6613,7 +6613,7 @@ int exec_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds) {
char *buf; char *buf;
n = strcspn(v, " "); n = strcspn(v, " ");
buf = strndupa(v, n); buf = strndupa_safe(v, n);
r = safe_atoi(buf, &ipcns_fdpair[1]); r = safe_atoi(buf, &ipcns_fdpair[1]);
if (r < 0) if (r < 0)

View File

@ -61,7 +61,7 @@ static int uid_from_file_name(const char *filename, uid_t *uid) {
if (!e) if (!e)
return -EINVAL; return -EINVAL;
u = strndupa(p, e-p); u = strndupa_safe(p, e - p);
return parse_uid(u, uid); return parse_uid(u, uid);
} }

View File

@ -149,7 +149,7 @@ static int on_home_inotify(sd_event_source *s, const struct inotify_event *event
if (!e) if (!e)
return 0; return 0;
n = strndupa(event->name, e - event->name); n = strndupa_safe(event->name, e - event->name);
if (!suitable_user_name(n)) if (!suitable_user_name(n))
return 0; return 0;

View File

@ -115,7 +115,7 @@ int home_activate_cifs(
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks CIFS service, refusing."); return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks CIFS service, refusing.");
assert_se(hdo = user_record_home_directory(h)); assert_se(hdo = user_record_home_directory(h));
hd = strdupa(hdo); /* copy the string out, since it might change later in the home record object */ hd = strdupa_safe(hdo); /* copy the string out, since it might change later in the home record object */
r = home_prepare_cifs(h, false, &setup); r = home_prepare_cifs(h, false, &setup);
if (r < 0) if (r < 0)

View File

@ -39,10 +39,10 @@ int home_activate_directory(
assert(ret_home); assert(ret_home);
assert_se(ipo = user_record_image_path(h)); assert_se(ipo = user_record_image_path(h));
ip = strdupa(ipo); /* copy out, since reconciliation might cause changing of the field */ ip = strdupa_safe(ipo); /* copy out, since reconciliation might cause changing of the field */
assert_se(hdo = user_record_home_directory(h)); assert_se(hdo = user_record_home_directory(h));
hd = strdupa(hdo); hd = strdupa_safe(hdo);
r = home_prepare(h, false, cache, &setup, &header_home); r = home_prepare(h, false, cache, &setup, &header_home);
if (r < 0) if (r < 0)

View File

@ -662,7 +662,7 @@ static int crypt_device_to_evp_cipher(struct crypt_device *cd, const EVP_CIPHER
e = strchr(cipher_mode, '-'); e = strchr(cipher_mode, '-');
if (e) if (e)
cipher_mode = strndupa(cipher_mode, e - cipher_mode); cipher_mode = strndupa_safe(cipher_mode, e - cipher_mode);
r = sym_crypt_get_volume_key_size(cd); r = sym_crypt_get_volume_key_size(cd);
if (r <= 0) if (r <= 0)
@ -1188,7 +1188,7 @@ int home_prepare_luks(
root_fd = open(user_record_home_directory(h), O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW); root_fd = open(user_record_home_directory(h), O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
if (root_fd < 0) { if (root_fd < 0) {
r = log_error_errno(r, "Failed to open home directory: %m"); r = log_error_errno(errno, "Failed to open home directory: %m");
goto fail; goto fail;
} }
} else { } else {
@ -1279,7 +1279,7 @@ int home_prepare_luks(
root_fd = open(subdir, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW); root_fd = open(subdir, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
if (root_fd < 0) { if (root_fd < 0) {
r = log_error_errno(r, "Failed to open home directory: %m"); r = log_error_errno(errno, "Failed to open home directory: %m");
goto fail; goto fail;
} }
@ -1354,7 +1354,7 @@ int home_activate_luks(
return r; return r;
assert_se(hdo = user_record_home_directory(h)); assert_se(hdo = user_record_home_directory(h));
hd = strdupa(hdo); /* copy the string out, since it might change later in the home record object */ hd = strdupa_safe(hdo); /* copy the string out, since it might change later in the home record object */
r = make_dm_names(h->user_name, &setup.dm_name, &setup.dm_node); r = make_dm_names(h->user_name, &setup.dm_name, &setup.dm_node);
if (r < 0) if (r < 0)
@ -2709,7 +2709,7 @@ int home_resize_luks(
return r; return r;
assert_se(ipo = user_record_image_path(h)); assert_se(ipo = user_record_image_path(h));
ip = strdupa(ipo); /* copy out since original might change later in home record object */ ip = strdupa_safe(ipo); /* copy out since original might change later in home record object */
image_fd = open(ip, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK); image_fd = open(ip, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
if (image_fd < 0) if (image_fd < 0)

View File

@ -662,7 +662,7 @@ static int create_remoteserver(
else else
url = strjoina(arg_url, "/entries"); url = strjoina(arg_url, "/entries");
} else } else
url = strdupa(arg_url); url = strdupa_safe(arg_url);
log_info("Spawning curl %s...", url); log_info("Spawning curl %s...", url);
fd = spawn_curl(url); fd = spawn_curl(url);
@ -673,7 +673,7 @@ static int create_remoteserver(
if (!hostname) if (!hostname)
hostname = arg_url; hostname = arg_url;
hostname = strndupa(hostname, strcspn(hostname, "/:")); hostname = strndupa_safe(hostname, strcspn(hostname, "/:"));
r = journal_remote_add_source(s, fd, (char *) hostname, false); r = journal_remote_add_source(s, fd, (char *) hostname, false);
if (r < 0) if (r < 0)

View File

@ -439,7 +439,7 @@ static int setup_uploader(Uploader *u, const char *url, const char *state_file)
char *t; char *t;
size_t x; size_t x;
t = strdupa(url); t = strdupa_safe(url);
x = strlen(t); x = strlen(t);
while (x > 0 && t[x - 1] == '/') while (x > 0 && t[x - 1] == '/')
t[x - 1] = '\0'; t[x - 1] = '\0';

View File

@ -280,7 +280,7 @@ static int parse_boot_descriptor(const char *x, sd_id128_t *boot_id, int *offset
} else if (strlen(x) >= SD_ID128_STRING_MAX - 1) { } else if (strlen(x) >= SD_ID128_STRING_MAX - 1) {
char *t; char *t;
t = strndupa(x, SD_ID128_STRING_MAX - 1); t = strndupa_safe(x, SD_ID128_STRING_MAX - 1);
r = sd_id128_from_string(t, &id); r = sd_id128_from_string(t, &id);
if (r >= 0) if (r >= 0)
x += SD_ID128_STRING_MAX - 1; x += SD_ID128_STRING_MAX - 1;
@ -1874,13 +1874,13 @@ static int setup_keys(void) {
return log_oom(); return log_oom();
mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR); mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR);
mpk = alloca(mpk_size); mpk = alloca_safe(mpk_size);
seed_size = FSPRG_RECOMMENDED_SEEDLEN; seed_size = FSPRG_RECOMMENDED_SEEDLEN;
seed = alloca(seed_size); seed = alloca_safe(seed_size);
state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR); state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
state = alloca(state_size); state = alloca_safe(state_size);
log_info("Generating seed..."); log_info("Generating seed...");
r = genuine_random_bytes(seed, seed_size, RANDOM_BLOCK); r = genuine_random_bytes(seed, seed_size, RANDOM_BLOCK);

View File

@ -4636,7 +4636,7 @@ _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
if (r < 0) if (r < 0)
return r; return r;
types = strndupa(c->signature + c->index, l); types = strndupa_safe(c->signature + c->index, l);
} }
switch (*types) { switch (*types) {

View File

@ -1513,7 +1513,7 @@ static struct node *bus_node_allocate(sd_bus *bus, const char *path) {
e = strrchr(path, '/'); e = strrchr(path, '/');
assert(e); assert(e);
p = strndupa(path, MAX(1, e - path)); p = strndupa_safe(path, MAX(1, e - path));
parent = bus_node_allocate(bus, p); parent = bus_node_allocate(bus, p);
if (!parent) if (!parent)

View File

@ -726,7 +726,8 @@ static int bus_socket_inotify_setup(sd_bus *b) {
} }
/* Make sure the path is NUL terminated */ /* Make sure the path is NUL terminated */
p = strndupa(b->sockaddr.un.sun_path, sizeof(b->sockaddr.un.sun_path)); p = strndupa_safe(b->sockaddr.un.sun_path,
sizeof(b->sockaddr.un.sun_path));
/* Make sure the path is absolute */ /* Make sure the path is absolute */
r = path_make_absolute_cwd(p, &absolute); r = path_make_absolute_cwd(p, &absolute);

View File

@ -1407,7 +1407,7 @@ int bus_set_address_system_remote(sd_bus *b, const char *host) {
rbracket = strchr(host, ']'); rbracket = strchr(host, ']');
if (!rbracket) if (!rbracket)
return -EINVAL; return -EINVAL;
t = strndupa(host + 1, rbracket - host - 1); t = strndupa_safe(host + 1, rbracket - host - 1);
e = bus_address_escape(t); e = bus_address_escape(t);
if (!e) if (!e)
return -ENOMEM; return -ENOMEM;
@ -1440,7 +1440,7 @@ int bus_set_address_system_remote(sd_bus *b, const char *host) {
t = strchr(p, '/'); t = strchr(p, '/');
if (t) { if (t) {
p = strndupa(p, t - p); p = strndupa_safe(p, t - p);
got_forward_slash = true; got_forward_slash = true;
} }
@ -1467,7 +1467,7 @@ interpret_port_as_machine_old_syntax:
if (!e) { if (!e) {
char *t; char *t;
t = strndupa(host, strcspn(host, ":/")); t = strndupa_safe(host, strcspn(host, ":/"));
e = bus_address_escape(t); e = bus_address_escape(t);
if (!e) if (!e)

View File

@ -369,7 +369,7 @@ _public_ int sd_device_new_from_subsystem_sysname(
} }
/* translate sysname back to sysfs filename */ /* translate sysname back to sysfs filename */
name = strdupa(sysname); name = strdupa_safe(sysname);
for (size_t i = 0; name[i]; i++) for (size_t i = 0; name[i]; i++)
if (name[i] == '/') if (name[i] == '/')
name[i] = '!'; name[i] = '!';

View File

@ -182,14 +182,13 @@ int journal_file_fsprg_seek(JournalFile *f, uint64_t goal) {
} else { } else {
f->fsprg_state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR); f->fsprg_state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
f->fsprg_state = malloc(f->fsprg_state_size); f->fsprg_state = malloc(f->fsprg_state_size);
if (!f->fsprg_state) if (!f->fsprg_state)
return -ENOMEM; return -ENOMEM;
} }
log_debug("Seeking FSPRG key to %"PRIu64".", goal); log_debug("Seeking FSPRG key to %"PRIu64".", goal);
msk = alloca(FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR)); msk = alloca_safe(FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR));
FSPRG_GenMK(msk, NULL, f->fsprg_seed, f->fsprg_seed_size, FSPRG_RECOMMENDED_SECPAR); FSPRG_GenMK(msk, NULL, f->fsprg_seed, f->fsprg_seed_size, FSPRG_RECOMMENDED_SECPAR);
FSPRG_Seek(f->fsprg_state, goal, msk, f->fsprg_seed, f->fsprg_seed_size); FSPRG_Seek(f->fsprg_state, goal, msk, f->fsprg_seed, f->fsprg_seed_size);
return 0; return 0;

View File

@ -2146,8 +2146,7 @@ int journal_file_append_entry(
return r; return r;
#endif #endif
/* alloca() can't take 0, hence let's allocate at least one */ items = newa(EntryItem, n_iovec);
items = newa(EntryItem, MAX(1u, n_iovec));
for (unsigned i = 0; i < n_iovec; i++) { for (unsigned i = 0; i < n_iovec; i++) {
uint64_t p; uint64_t p;
@ -3873,8 +3872,7 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
boot_id = &o->entry.boot_id; boot_id = &o->entry.boot_id;
n = journal_file_entry_n_items(o); n = journal_file_entry_n_items(o);
/* alloca() can't take 0, hence let's allocate at least one */ items = newa(EntryItem, n);
items = newa(EntryItem, MAX(1u, n));
for (uint64_t i = 0; i < n; i++) { for (uint64_t i = 0; i < n; i++) {
uint64_t l, h; uint64_t l, h;

View File

@ -96,7 +96,7 @@ _public_ int sd_journal_printv(int priority, const char *format, va_list ap) {
/* Allocate large buffer to accommodate big message */ /* Allocate large buffer to accommodate big message */
if (len >= LINE_MAX) { if (len >= LINE_MAX) {
buffer = alloca(len + 9); buffer = alloca_safe(len + 9);
memcpy(buffer, "MESSAGE=", 8); memcpy(buffer, "MESSAGE=", 8);
assert_se(vsnprintf(buffer + 8, len + 1, format, ap) == len); assert_se(vsnprintf(buffer + 8, len + 1, format, ap) == len);
} }
@ -472,7 +472,7 @@ _public_ int sd_journal_printv_with_location(int priority, const char *file, con
/* Allocate large buffer to accommodate big message */ /* Allocate large buffer to accommodate big message */
if (len >= LINE_MAX) { if (len >= LINE_MAX) {
buffer = alloca(len + 9); buffer = alloca_safe(len + 9);
memcpy(buffer, "MESSAGE=", 8); memcpy(buffer, "MESSAGE=", 8);
assert_se(vsnprintf(buffer + 8, len + 1, format, ap) == len); assert_se(vsnprintf(buffer + 8, len + 1, format, ap) == len);
} }

View File

@ -1468,7 +1468,7 @@ static int dirname_is_machine_id(const char *fn) {
if (!log_namespace_name_valid(e + 1)) if (!log_namespace_name_valid(e + 1))
return false; return false;
k = strndupa(fn, e - fn); k = strndupa_safe(fn, e - fn);
r = sd_id128_from_string(k, &id); r = sd_id128_from_string(k, &id);
} else } else
r = sd_id128_from_string(fn, &id); r = sd_id128_from_string(fn, &id);
@ -1493,7 +1493,7 @@ static int dirname_has_namespace(const char *fn, const char *namespace) {
if (!streq(e + 1, namespace)) if (!streq(e + 1, namespace))
return false; return false;
k = strndupa(fn, e - fn); k = strndupa_safe(fn, e - fn);
return id128_is_valid(k); return id128_is_valid(k);
} }
@ -1530,7 +1530,7 @@ static bool dirent_is_journal_subdir(const struct dirent *de) {
if (!e) if (!e)
return id128_is_valid(de->d_name); /* No namespace */ return id128_is_valid(de->d_name); /* No namespace */
n = strndupa(de->d_name, e - de->d_name); n = strndupa_safe(de->d_name, e - de->d_name);
if (!id128_is_valid(n)) if (!id128_is_valid(n))
return false; return false;

View File

@ -648,9 +648,10 @@ int find_legacy_keymap(Context *c, char **ret) {
*/ */
char *l, *v = NULL, *converted; char *l, *v = NULL, *converted;
l = strndupa(c->x11_layout, strcspn(c->x11_layout, ",")); l = strndupa_safe(c->x11_layout, strcspn(c->x11_layout, ","));
if (c->x11_variant) if (c->x11_variant)
v = strndupa(c->x11_variant, strcspn(c->x11_variant, ",")); v = strndupa_safe(c->x11_variant,
strcspn(c->x11_variant, ","));
r = find_converted_keymap(l, v, &converted); r = find_converted_keymap(l, v, &converted);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -929,7 +929,7 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro
host_basename = basename(host_path); host_basename = basename(host_path);
container_basename = basename(container_path); container_basename = basename(container_path);
t = strdupa(container_path); t = strdupa_safe(container_path);
container_dirname = dirname(t); container_dirname = dirname(t);
hostfd = open_parent(host_path, O_CLOEXEC, 0); hostfd = open_parent(host_path, O_CLOEXEC, 0);

View File

@ -475,7 +475,7 @@ static int parse_cmdline_ip_mtu_mac(Context *context, const char *ifname, int fa
if (!p) if (!p)
mtu = value; mtu = value;
else else
mtu = strndupa(value, p - value); mtu = strndupa_safe(value, p - value);
r = network_set_mtu(context, ifname, family, mtu); r = network_set_mtu(context, ifname, family, mtu);
if (r < 0) if (r < 0)
@ -511,14 +511,14 @@ static int parse_ip_address_one(int family, const char **value, union in_addr_un
if (q[1] != ':') if (q[1] != ':')
return -EINVAL; return -EINVAL;
buf = strndupa(p + 1, q - p - 1); buf = strndupa_safe(p + 1, q - p - 1);
p = q + 2; p = q + 2;
} else { } else {
q = strchr(p, ':'); q = strchr(p, ':');
if (!q) if (!q)
return -EINVAL; return -EINVAL;
buf = strndupa(p, q - p); buf = strndupa_safe(p, q - p);
p = q + 1; p = q + 1;
} }
@ -549,7 +549,7 @@ static int parse_netmask_or_prefixlen(int family, const char **value, unsigned c
if (!p) if (!p)
return -EINVAL; return -EINVAL;
q = strndupa(*value, p - *value); q = strndupa_safe(*value, p - *value);
r = safe_atou8(q, ret); r = safe_atou8(q, ret);
if (r < 0) if (r < 0)
return r; return r;
@ -588,7 +588,7 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va
return -EINVAL; return -EINVAL;
if (p != value) { if (p != value) {
hostname = strndupa(value, p - value); hostname = strndupa_safe(value, p - value);
if (!hostname_is_valid(hostname, 0)) if (!hostname_is_valid(hostname, 0))
return -EINVAL; return -EINVAL;
} }
@ -600,7 +600,7 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va
if (!p) if (!p)
return -EINVAL; return -EINVAL;
ifname = strndupa(value, p - value); ifname = strndupa_safe(value, p - value);
value = p + 1; value = p + 1;
@ -609,7 +609,7 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va
if (!p) if (!p)
dhcp_type = value; dhcp_type = value;
else else
dhcp_type = strndupa(value, p - value); dhcp_type = strndupa_safe(value, p - value);
r = network_set_dhcp_type(context, ifname, dhcp_type); r = network_set_dhcp_type(context, ifname, dhcp_type);
if (r < 0) if (r < 0)
@ -644,7 +644,7 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va
if (r < 0) if (r < 0)
return r; return r;
} else { } else {
dns = strndupa(value, p - value); dns = strndupa_safe(value, p - value);
r = network_set_dns(context, ifname, dns); r = network_set_dns(context, ifname, dns);
if (r < 0) if (r < 0)
return r; return r;
@ -666,14 +666,14 @@ static int parse_cmdline_ip_interface(Context *context, const char *value) {
if (!p) if (!p)
return -EINVAL; return -EINVAL;
ifname = strndupa(value, p - value); ifname = strndupa_safe(value, p - value);
value = p + 1; value = p + 1;
p = strchr(value, ':'); p = strchr(value, ':');
if (!p) if (!p)
dhcp_type = value; dhcp_type = value;
else else
dhcp_type = strndupa(value, p - value); dhcp_type = strndupa_safe(value, p - value);
r = network_set_dhcp_type(context, ifname, dhcp_type); r = network_set_dhcp_type(context, ifname, dhcp_type);
if (r < 0) if (r < 0)
@ -726,7 +726,7 @@ static int parse_cmdline_rd_route(Context *context, const char *key, const char
if (p[1] != ':') if (p[1] != ':')
return -EINVAL; return -EINVAL;
buf = strndupa(value + 1, p - value - 1); buf = strndupa_safe(value + 1, p - value - 1);
value = p + 2; value = p + 2;
family = AF_INET6; family = AF_INET6;
} else { } else {
@ -734,7 +734,7 @@ static int parse_cmdline_rd_route(Context *context, const char *key, const char
if (!p) if (!p)
return -EINVAL; return -EINVAL;
buf = strndupa(value, p - value); buf = strndupa_safe(value, p - value);
value = p + 1; value = p + 1;
family = AF_INET; family = AF_INET;
} }
@ -786,7 +786,7 @@ static int parse_cmdline_vlan(Context *context, const char *key, const char *val
if (!p) if (!p)
return -EINVAL; return -EINVAL;
name = strndupa(value, p - value); name = strndupa_safe(value, p - value);
netdev = netdev_get(context, name); netdev = netdev_get(context, name);
if (!netdev) { if (!netdev) {
@ -810,7 +810,7 @@ static int parse_cmdline_bridge(Context *context, const char *key, const char *v
if (!p) if (!p)
return -EINVAL; return -EINVAL;
name = strndupa(value, p - value); name = strndupa_safe(value, p - value);
netdev = netdev_get(context, name); netdev = netdev_get(context, name);
if (!netdev) { if (!netdev) {
@ -848,7 +848,7 @@ static int parse_cmdline_bond(Context *context, const char *key, const char *val
if (!p) if (!p)
return -EINVAL; return -EINVAL;
name = strndupa(value, p - value); name = strndupa_safe(value, p - value);
netdev = netdev_get(context, name); netdev = netdev_get(context, name);
if (!netdev) { if (!netdev) {
@ -862,7 +862,7 @@ static int parse_cmdline_bond(Context *context, const char *key, const char *val
if (!p) if (!p)
slaves = value; slaves = value;
else else
slaves = strndupa(value, p - value); slaves = strndupa_safe(value, p - value);
if (isempty(slaves)) if (isempty(slaves))
return -EINVAL; return -EINVAL;
@ -907,7 +907,7 @@ static int parse_cmdline_ifname(Context *context, const char *key, const char *v
if (!p) if (!p)
return -EINVAL; return -EINVAL;
name = strndupa(value, p - value); name = strndupa_safe(value, p - value);
r = ether_addr_from_string(p + 1, &mac); r = ether_addr_from_string(p + 1, &mac);
if (r < 0) if (r < 0)

View File

@ -609,7 +609,7 @@ int config_parse_private_users(
range = strchr(rvalue, ':'); range = strchr(rvalue, ':');
if (range) { if (range) {
shift = strndupa(rvalue, range - rvalue); shift = strndupa_safe(rvalue, range - rvalue);
range++; range++;
r = safe_atou32(range, &rn); r = safe_atou32(range, &rn);

View File

@ -718,7 +718,7 @@ static int unit_file_is_active(
at = strchr(name, '@'); at = strchr(name, '@');
assert(at); assert(at);
prefix = strndupa(name, at + 1 - name); prefix = strndupa_safe(name, at + 1 - name);
joined = strjoina(prefix, "*", at + 1); joined = strjoina(prefix, "*", at + 1);
r = sd_bus_message_append_strv(m, STRV_MAKE(joined)); r = sd_bus_message_append_strv(m, STRV_MAKE(joined));

View File

@ -623,7 +623,7 @@ static int resolve_rfc4501(sd_bus *bus, const char *name) {
q = strchr(p, '?'); q = strchr(p, '?');
if (q) { if (q) {
n = strndupa(p, q - p); n = strndupa_safe(p, q - p);
q++; q++;
for (;;) { for (;;) {
@ -1001,7 +1001,7 @@ static int resolve_tlsa(sd_bus *bus, const char *family, const char *address) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Invalid port \"%s\".", port + 1); return log_error_errno(r, "Invalid port \"%s\".", port + 1);
address = strndupa(address, port - address); address = strndupa_safe(address, port - address);
} }
r = asprintf(&full, "_%u._%s.%s", r = asprintf(&full, "_%u._%s.%s",

View File

@ -130,7 +130,7 @@ int bus_property_get_rlimit(
int z; int z;
/* Chop off "Soft" suffix */ /* Chop off "Soft" suffix */
s = is_soft ? strndupa(property, is_soft - property) : property; s = is_soft ? strndupa_safe(property, is_soft - property) : property;
/* Skip over any prefix, such as "Default" */ /* Skip over any prefix, such as "Default" */
assert_se(p = strstr(s, "Limit")); assert_se(p = strstr(s, "Limit"));

View File

@ -46,7 +46,7 @@ static int add_cgroup(Hashmap *cgroups, const char *path, bool is_const, struct
if (!e) if (!e)
return -EINVAL; return -EINVAL;
pp = strndupa(path, e - path); pp = strndupa_safe(path, e - path);
r = add_cgroup(cgroups, pp, false, &parent); r = add_cgroup(cgroups, pp, false, &parent);
if (r < 0) if (r < 0)

View File

@ -605,7 +605,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
e = strchr(eq, ' '); e = strchr(eq, ' ');
if (e) { if (e) {
path = strndupa(eq, e - eq); path = strndupa_safe(eq, e - eq);
rwm = e+1; rwm = e+1;
} }
@ -631,7 +631,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
"Failed to parse %s value %s.", "Failed to parse %s value %s.",
field, eq); field, eq);
path = strndupa(eq, e - eq); path = strndupa_safe(eq, e - eq);
bandwidth = e+1; bandwidth = e+1;
if (streq(bandwidth, "infinity")) if (streq(bandwidth, "infinity"))
@ -665,7 +665,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
"Failed to parse %s value %s.", "Failed to parse %s value %s.",
field, eq); field, eq);
path = strndupa(eq, e - eq); path = strndupa_safe(eq, e - eq);
weight = e+1; weight = e+1;
r = safe_atou64(weight, &u); r = safe_atou64(weight, &u);
@ -696,7 +696,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
"Failed to parse %s value %s.", "Failed to parse %s value %s.",
field, eq); field, eq);
path = strndupa(eq, e - eq); path = strndupa_safe(eq, e - eq);
target = e+1; target = e+1;
r = parse_sec(target, &usec); r = parse_sec(target, &usec);
@ -2402,7 +2402,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, UnitType t, const cha
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Not an assignment: %s", assignment); "Not an assignment: %s", assignment);
field = strndupa(assignment, eq - assignment); field = strndupa_safe(assignment, eq - assignment);
eq++; eq++;
switch (t) { switch (t) {

View File

@ -63,6 +63,10 @@ static int cg_any_controller_used_for_v1(void) {
if (streq(enabled, "0")) if (streq(enabled, "0"))
continue; continue;
/* Ignore controllers we don't care about. */
if (cgroup_controller_from_string(name) < 0)
continue;
/* Since the unified cgroup doesn't use multiple hierarchies, if any controller has a /* Since the unified cgroup doesn't use multiple hierarchies, if any controller has a
* non-zero hierarchy_id that means it's in use already in a legacy (or hybrid) cgroup v1 * non-zero hierarchy_id that means it's in use already in a legacy (or hybrid) cgroup v1
* hierarchy, and can't be used in a unified cgroup. */ * hierarchy, and can't be used in a unified cgroup. */

View File

@ -680,7 +680,7 @@ int dns_name_change_suffix(const char *name, const char *old_suffix, const char
} }
/* Found it! Now generate the new name */ /* Found it! Now generate the new name */
prefix = strndupa(name, saved_before - name); prefix = strndupa_safe(name, saved_before - name);
r = dns_name_concat(prefix, new_suffix, 0, ret); r = dns_name_concat(prefix, new_suffix, 0, ret);
if (r < 0) if (r < 0)
@ -1028,7 +1028,7 @@ static bool dns_service_name_label_is_valid(const char *label, size_t n) {
if (memchr(label, 0, n)) if (memchr(label, 0, n))
return false; return false;
s = strndupa(label, n); s = strndupa_safe(label, n);
return dns_service_name_is_valid(s); return dns_service_name_is_valid(s);
} }

View File

@ -128,7 +128,7 @@ int fw_iptables_add_masquerade(
mr->rangesize = 1; mr->rangesize = 1;
/* Create a search mask entry */ /* Create a search mask entry */
mask = alloca(sz); mask = alloca_safe(sz);
memset(mask, 0xFF, sz); memset(mask, 0xFF, sz);
if (add) { if (add) {

View File

@ -316,7 +316,7 @@ int journal_importer_process_data(JournalImporter *imp) {
if (!journal_field_valid(line, sep - line, true)) { if (!journal_field_valid(line, sep - line, true)) {
char buf[64], *t; char buf[64], *t;
t = strndupa(line, sep - line); t = strndupa_safe(line, sep - line);
log_debug("Ignoring invalid field: \"%s\"", log_debug("Ignoring invalid field: \"%s\"",
cellescape(buf, sizeof buf, t)); cellescape(buf, sizeof buf, t));
@ -335,7 +335,7 @@ int journal_importer_process_data(JournalImporter *imp) {
if (!journal_field_valid(line, n - 1, true)) { if (!journal_field_valid(line, n - 1, true)) {
char buf[64], *t; char buf[64], *t;
t = strndupa(line, n - 1); t = strndupa_safe(line, n - 1);
log_debug("Ignoring invalid field: \"%s\"", log_debug("Ignoring invalid field: \"%s\"",
cellescape(buf, sizeof buf, t)); cellescape(buf, sizeof buf, t));

View File

@ -190,7 +190,7 @@ static int field_set_test(const Set *fields, const char *name, size_t n) {
if (!fields) if (!fields)
return 1; return 1;
s = strndupa(name, n); s = strndupa_safe(name, n);
return set_contains(fields, s); return set_contains(fields, s);
} }
@ -972,7 +972,7 @@ static int update_json_data_split(
if (!journal_field_valid(data, fieldlen, true)) if (!journal_field_valid(data, fieldlen, true))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid field."); return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid field.");
name = strndupa(data, fieldlen); name = strndupa_safe(data, fieldlen);
if (output_fields && !set_contains(output_fields, name)) if (output_fields && !set_contains(output_fields, name))
return 0; return 0;

View File

@ -35,7 +35,7 @@ static int nscd_flush_cache_one(const char *database, usec_t end) {
l = strlen(database); l = strlen(database);
req_size = offsetof(struct nscdInvalidateRequest, dbname) + l + 1; req_size = offsetof(struct nscdInvalidateRequest, dbname) + l + 1;
req = alloca(req_size); req = alloca_safe(req_size);
*req = (struct nscdInvalidateRequest) { *req = (struct nscdInvalidateRequest) {
.version = 2, .version = 2,
.type = 10, .type = 10,

View File

@ -309,8 +309,8 @@ int show_man_page(const char *desc, bool null_stdio) {
if (e) { if (e) {
char *page = NULL, *section = NULL; char *page = NULL, *section = NULL;
page = strndupa(desc, e - desc); page = strndupa_safe(desc, e - desc);
section = strndupa(e + 1, desc + k - e - 2); section = strndupa_safe(e + 1, desc + k - e - 2);
args[1] = section; args[1] = section;
args[2] = page; args[2] = page;

View File

@ -647,7 +647,8 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
if (un->sun_path[0] == 0) if (un->sun_path[0] == 0)
goto skipped; goto skipped;
path = strndupa(un->sun_path, addrlen - offsetof(struct sockaddr_un, sun_path)); path = strndupa_safe(un->sun_path,
addrlen - offsetof(struct sockaddr_un, sun_path));
/* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */ /* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */
mac_selinux_maybe_reload(); mac_selinux_maybe_reload();

View File

@ -151,7 +151,7 @@ static int tpm2_init(const char *device, struct tpm2_context *ret) {
param = strchr(device, ':'); param = strchr(device, ':');
if (param) { if (param) {
driver = strndupa(device, param - device); driver = strndupa_safe(device, param - device);
param++; param++;
} else { } else {
driver = "device"; driver = "device";

View File

@ -114,7 +114,7 @@ int uid_range_add_str(UidRange **p, unsigned *n, const char *s) {
char *b; char *b;
uid_t end; uid_t end;
b = strndupa(s, t - s); b = strndupa_safe(s, t - s);
r = parse_uid(b, &start); r = parse_uid(b, &start);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -438,7 +438,8 @@ static int resolve_remote(Connection *c) {
service = strrchr(arg_remote_host, ':'); service = strrchr(arg_remote_host, ':');
if (service) { if (service) {
node = strndupa(arg_remote_host, service - arg_remote_host); node = strndupa_safe(arg_remote_host,
service - arg_remote_host);
service++; service++;
} else { } else {
node = arg_remote_host; node = arg_remote_host;

View File

@ -289,7 +289,7 @@ static int sysv_translate_facility(SysvStub *s, unsigned line, const char *name,
} }
/* Strip ".sh" suffix from file name for comparison */ /* Strip ".sh" suffix from file name for comparison */
filename_no_sh = strdupa(filename); filename_no_sh = strdupa_safe(filename);
e = endswith(filename_no_sh, ".sh"); e = endswith(filename_no_sh, ".sh");
if (e) { if (e) {
*e = '\0'; *e = '\0';

View File

@ -40,7 +40,7 @@ static void _test_next(int line, const char *input, const char *new_tz, usec_t a
old_tz = getenv("TZ"); old_tz = getenv("TZ");
if (old_tz) if (old_tz)
old_tz = strdupa(old_tz); old_tz = strdupa_safe(old_tz);
if (!isempty(new_tz)) if (!isempty(new_tz))
new_tz = strjoina(":", new_tz); new_tz = strjoina(":", new_tz);

View File

@ -85,7 +85,7 @@ static void test_unhexmem_one(const char *s, size_t l, int retval) {
l = strlen(s); l = strlen(s);
assert_se(hex = hexmem(mem, len)); assert_se(hex = hexmem(mem, len));
answer = strndupa(strempty(s), l); answer = strndupa_safe(strempty(s), l);
assert_se(streq(delete_chars(answer, WHITESPACE), hex)); assert_se(streq(delete_chars(answer, WHITESPACE), hex));
} }
} }
@ -191,7 +191,7 @@ static void test_unbase32hexmem_one(const char *hex, bool padding, int retval, c
if (retval == 0) { if (retval == 0) {
char *str; char *str;
str = strndupa(mem, len); str = strndupa_safe(mem, len);
assert_se(streq(str, ans)); assert_se(streq(str, ans));
} }
} }

View File

@ -53,45 +53,45 @@ static void test_hostname_cleanup(void) {
log_info("/* %s */", __func__); log_info("/* %s */", __func__);
s = strdupa("foobar"); s = strdupa_safe("foobar");
assert_se(streq(hostname_cleanup(s), "foobar")); assert_se(streq(hostname_cleanup(s), "foobar"));
s = strdupa("foobar.com"); s = strdupa_safe("foobar.com");
assert_se(streq(hostname_cleanup(s), "foobar.com")); assert_se(streq(hostname_cleanup(s), "foobar.com"));
s = strdupa("foobar.com."); s = strdupa_safe("foobar.com.");
assert_se(streq(hostname_cleanup(s), "foobar.com")); assert_se(streq(hostname_cleanup(s), "foobar.com"));
s = strdupa("foo-bar.-com-."); s = strdupa_safe("foo-bar.-com-.");
assert_se(streq(hostname_cleanup(s), "foo-bar.com")); assert_se(streq(hostname_cleanup(s), "foo-bar.com"));
s = strdupa("foo-bar-.-com-."); s = strdupa_safe("foo-bar-.-com-.");
assert_se(streq(hostname_cleanup(s), "foo-bar--com")); assert_se(streq(hostname_cleanup(s), "foo-bar--com"));
s = strdupa("--foo-bar.-com"); s = strdupa_safe("--foo-bar.-com");
assert_se(streq(hostname_cleanup(s), "foo-bar.com")); assert_se(streq(hostname_cleanup(s), "foo-bar.com"));
s = strdupa("fooBAR"); s = strdupa_safe("fooBAR");
assert_se(streq(hostname_cleanup(s), "fooBAR")); assert_se(streq(hostname_cleanup(s), "fooBAR"));
s = strdupa("fooBAR.com"); s = strdupa_safe("fooBAR.com");
assert_se(streq(hostname_cleanup(s), "fooBAR.com")); assert_se(streq(hostname_cleanup(s), "fooBAR.com"));
s = strdupa("fooBAR."); s = strdupa_safe("fooBAR.");
assert_se(streq(hostname_cleanup(s), "fooBAR")); assert_se(streq(hostname_cleanup(s), "fooBAR"));
s = strdupa("fooBAR.com."); s = strdupa_safe("fooBAR.com.");
assert_se(streq(hostname_cleanup(s), "fooBAR.com")); assert_se(streq(hostname_cleanup(s), "fooBAR.com"));
s = strdupa("fööbar"); s = strdupa_safe("fööbar");
assert_se(streq(hostname_cleanup(s), "fbar")); assert_se(streq(hostname_cleanup(s), "fbar"));
s = strdupa(""); s = strdupa_safe("");
assert_se(isempty(hostname_cleanup(s))); assert_se(isempty(hostname_cleanup(s)));
s = strdupa("."); s = strdupa_safe(".");
assert_se(isempty(hostname_cleanup(s))); assert_se(isempty(hostname_cleanup(s)));
s = strdupa(".."); s = strdupa_safe("..");
assert_se(isempty(hostname_cleanup(s))); assert_se(isempty(hostname_cleanup(s)));
s = strdupa("foobar."); s = strdupa_safe("foobar.");
assert_se(streq(hostname_cleanup(s), "foobar")); assert_se(streq(hostname_cleanup(s), "foobar"));
s = strdupa(".foobar"); s = strdupa_safe(".foobar");
assert_se(streq(hostname_cleanup(s), "foobar")); assert_se(streq(hostname_cleanup(s), "foobar"));
s = strdupa("foo..bar"); s = strdupa_safe("foo..bar");
assert_se(streq(hostname_cleanup(s), "foo.bar")); assert_se(streq(hostname_cleanup(s), "foo.bar"));
s = strdupa("foo.bar.."); s = strdupa_safe("foo.bar..");
assert_se(streq(hostname_cleanup(s), "foo.bar")); assert_se(streq(hostname_cleanup(s), "foo.bar"));
s = strdupa("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); s = strdupa_safe("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
assert_se(streq(hostname_cleanup(s), "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")); assert_se(streq(hostname_cleanup(s), "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
s = strdupa("xxxx........xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); s = strdupa_safe("xxxx........xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
assert_se(streq(hostname_cleanup(s), "xxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")); assert_se(streq(hostname_cleanup(s), "xxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
} }

View File

@ -59,7 +59,7 @@ static void test_path(void) {
static void test_path_simplify_one(const char *in, const char *out) { static void test_path_simplify_one(const char *in, const char *out) {
char *p; char *p;
p = strdupa(in); p = strdupa_safe(in);
path_simplify(p); path_simplify(p);
log_debug("/* test_path_simplify(%s) → %s (expected: %s) */", in, p, out); log_debug("/* test_path_simplify(%s) → %s (expected: %s) */", in, p, out);
assert_se(streq(p, out)); assert_se(streq(p, out));

View File

@ -13,13 +13,13 @@ static void test_string_erase(void) {
log_info("/* %s */", __func__); log_info("/* %s */", __func__);
char *x; char *x;
x = strdupa(""); x = strdupa_safe("");
assert_se(streq(string_erase(x), "")); assert_se(streq(string_erase(x), ""));
x = strdupa("1"); x = strdupa_safe("1");
assert_se(streq(string_erase(x), "")); assert_se(streq(string_erase(x), ""));
x = strdupa("123456789"); x = strdupa_safe("123456789");
assert_se(streq(string_erase(x), "")); assert_se(streq(string_erase(x), ""));
assert_se(x[1] == '\0'); assert_se(x[1] == '\0');

View File

@ -77,7 +77,7 @@ static int print_status_info(const StatusInfo *i) {
/* Save the old $TZ */ /* Save the old $TZ */
tz = getenv("TZ"); tz = getenv("TZ");
if (tz) if (tz)
old_tz = strdupa(tz); old_tz = strdupa_safe(tz);
/* Set the new $TZ */ /* Set the new $TZ */
tz_colon = strjoina(":", isempty(i->timezone) ? "UTC" : i->timezone); tz_colon = strjoina(":", isempty(i->timezone) ? "UTC" : i->timezone);

View File

@ -183,7 +183,7 @@ static void dmi_memory_device_string(
const struct dmi_header *h, uint8_t s) { const struct dmi_header *h, uint8_t s) {
char *str; char *str;
str = strdupa(dmi_string(h, s)); str = strdupa_safe(dmi_string(h, s));
str = strstrip(str); str = strstrip(str);
if (!isempty(str)) if (!isempty(str))
printf("MEMORY_DEVICE_%u_%s=%s\n", slot_num, attr_suffix, str); printf("MEMORY_DEVICE_%u_%s=%s\n", slot_num, attr_suffix, str);

View File

@ -337,7 +337,7 @@ static sd_device *handle_scsi_default(sd_device *parent, char **path) {
if (!pos) if (!pos)
return NULL; return NULL;
base = strndupa(base, pos - base); base = strndupa_safe(base, pos - base);
dir = opendir(base); dir = opendir(base);
if (!dir) if (!dir)
return NULL; return NULL;

View File

@ -223,7 +223,7 @@ static int safe_atou_optional_plus(const char *s, unsigned *ret) {
p = endswith(s, "+"); p = endswith(s, "+");
if (p) if (p)
s = strndupa(s, p - s); s = strndupa_safe(s, p - s);
r = safe_atou(s, ret); r = safe_atou(s, ret);
if (r < 0) if (r < 0)