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.
This commit is contained in:
Lennart Poettering 2021-10-13 12:38:37 +02:00
parent 5222651ecc
commit 2f82562bad
60 changed files with 164 additions and 131 deletions

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

@ -387,7 +387,7 @@ static int run(int argc, char *argv[]) {
if (!sysname)
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++;

View File

@ -194,3 +194,19 @@ void* greedy_realloc0(void **p, size_t need, size_t size);
__builtin_types_compatible_p(typeof(x), typeof(&*(x))), \
MALLOC_SIZEOF_SAFE(x)/sizeof((x)[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)
return -ENXIO;
c = strndupa(cgroup, n);
c = strndupa_safe(cgroup, n);
c = cg_unescape(c);
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;
}
name = strndupa(p, t - p);
name = strndupa_safe(p, t - p);
STRV_FOREACH(f, *l)
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) {
const char *t;
t = strndupa(name, k);
t = strndupa_safe(name, k);
return getenv(t);
};
@ -804,7 +804,7 @@ int putenv_dup(const char *assignment, bool override) {
if (!e)
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[]. */
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))
return -EINVAL;
p = strdupa(path);
p = strdupa_safe(path);
for (;;) {
char *slash = NULL;

View File

@ -1073,8 +1073,10 @@ int log_struct_iovec_internal(
for (size_t i = 0; i < n_input_iovec; i++)
if (memory_startswith(input_iovec[i].iov_base, input_iovec[i].iov_len, "MESSAGE=")) {
char *m = strndupa(input_iovec[i].iov_base + STRLEN("MESSAGE="),
input_iovec[i].iov_len - STRLEN("MESSAGE="));
char *m;
m = strndupa_safe((char*) input_iovec[i].iov_base + STRLEN("MESSAGE="),
input_iovec[i].iov_len - STRLEN("MESSAGE="));
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 == '/');
/* drop the last component */
path = strndupa(path, e - path);
path = strndupa_safe(path, e - path);
r = is_dir(path, true);
if (r > 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 */
return false;
copied = strndupa(s, slash - s);
copied = strndupa_safe(s, slash - s);
return filename_is_valid(copied);
}

View File

@ -704,7 +704,7 @@ int parse_dev(const char *s, dev_t *ret) {
if (s[n] != ':')
return -EINVAL;
major = strndupa(s, n);
major = strndupa_safe(s, n);
r = safe_atou(major, &x);
if (r < 0)
return r;
@ -765,7 +765,7 @@ int parse_loadavg_fixed_point(const char *s, loadavg_t *ret) {
if (!d)
return -EINVAL;
i_str = strndupa(s, d - s);
i_str = strndupa_safe(s, d - s);
f_str = d + 1;
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, ":");
if (k) {
e = strndupa(e, k - e);
e = strndupa_safe(e, k - e);
*append = true;
}

View File

@ -12,7 +12,7 @@ static int parse_parts_value_whole(const char *p, const char *symbol) {
if (!pc)
return -EINVAL;
n = strndupa(p, pc - p);
n = strndupa_safe(p, pc - p);
r = safe_atoi(n, &v);
if (r < 0)
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')
return -EINVAL;
q = dot[1] - '0';
n = strndupa(p, dot - p);
n = strndupa_safe(p, dot - p);
} else {
q = 0;
n = strndupa(p, pc - p);
n = strndupa_safe(p, pc - p);
}
r = safe_atoi(n, &v);
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 */
return -EINVAL;
n = strndupa(p, dot - p);
n = strndupa_safe(p, dot - p);
} else {
q = 0;
n = strndupa(p, pc - p);
n = strndupa_safe(p, pc - p);
}
r = safe_atoi(n, &v);
if (r < 0)

View File

@ -135,7 +135,7 @@ int procfs_tasks_get_current(uint64_t *ret) {
p++;
n = strspn(p, DIGITS);
nr = strndupa(p, n);
nr = strndupa_safe(p, n);
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;
} else if ((k = endswith(t, " ago"))) {
t = strndupa(t, k - t);
t = strndupa_safe(t, k - t);
r = parse_sec(t, &minus);
if (r < 0)
@ -680,7 +680,7 @@ static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
goto finish;
} else if ((k = endswith(t, " left"))) {
t = strndupa(t, k - t);
t = strndupa_safe(t, k - t);
r = parse_sec(t, &plus);
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 */
utc = endswith_no_case(t, " UTC");
if (utc)
t = strndupa(t, utc - t);
t = strndupa_safe(t, utc - t);
else {
const char *e = NULL;
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)) {
/* Found one of the two timezones specified. */
t = strndupa(t, e - t - 1);
t = strndupa_safe(t, e - t - 1);
dst = 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. */
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);

View File

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

View File

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

View File

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

View File

@ -117,7 +117,7 @@ int bus_set_transient_usec_internal(
else
*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));
}

View File

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

View File

@ -61,7 +61,7 @@ static int uid_from_file_name(const char *filename, uid_t *uid) {
if (!e)
return -EINVAL;
u = strndupa(p, e-p);
u = strndupa_safe(p, e - p);
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)
return 0;
n = strndupa(event->name, e - event->name);
n = strndupa_safe(event->name, e - event->name);
if (!suitable_user_name(n))
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.");
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);
if (r < 0)

View File

@ -39,10 +39,10 @@ int home_activate_directory(
assert(ret_home);
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));
hd = strdupa(hdo);
hd = strdupa_safe(hdo);
r = home_prepare(h, false, cache, &setup, &header_home);
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, '-');
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);
if (r <= 0)
@ -1354,7 +1354,7 @@ int home_activate_luks(
return r;
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);
if (r < 0)
@ -2709,7 +2709,7 @@ int home_resize_luks(
return r;
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);
if (image_fd < 0)

View File

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

View File

@ -439,7 +439,7 @@ static int setup_uploader(Uploader *u, const char *url, const char *state_file)
char *t;
size_t x;
t = strdupa(url);
t = strdupa_safe(url);
x = strlen(t);
while (x > 0 && t[x - 1] == '/')
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) {
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);
if (r >= 0)
x += SD_ID128_STRING_MAX - 1;

View File

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

View File

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

View File

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

View File

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

View File

@ -1468,7 +1468,7 @@ static int dirname_is_machine_id(const char *fn) {
if (!log_namespace_name_valid(e + 1))
return false;
k = strndupa(fn, e - fn);
k = strndupa_safe(fn, e - fn);
r = sd_id128_from_string(k, &id);
} else
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))
return false;
k = strndupa(fn, e - fn);
k = strndupa_safe(fn, e - fn);
return id128_is_valid(k);
}
@ -1530,7 +1530,7 @@ static bool dirent_is_journal_subdir(const struct dirent *de) {
if (!e)
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))
return false;

View File

@ -648,9 +648,10 @@ int find_legacy_keymap(Context *c, char **ret) {
*/
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)
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);
if (r < 0)
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);
container_basename = basename(container_path);
t = strdupa(container_path);
t = strdupa_safe(container_path);
container_dirname = dirname(t);
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)
mtu = value;
else
mtu = strndupa(value, p - value);
mtu = strndupa_safe(value, p - value);
r = network_set_mtu(context, ifname, family, mtu);
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] != ':')
return -EINVAL;
buf = strndupa(p + 1, q - p - 1);
buf = strndupa_safe(p + 1, q - p - 1);
p = q + 2;
} else {
q = strchr(p, ':');
if (!q)
return -EINVAL;
buf = strndupa(p, q - p);
buf = strndupa_safe(p, q - p);
p = q + 1;
}
@ -549,7 +549,7 @@ static int parse_netmask_or_prefixlen(int family, const char **value, unsigned c
if (!p)
return -EINVAL;
q = strndupa(*value, p - *value);
q = strndupa_safe(*value, p - *value);
r = safe_atou8(q, ret);
if (r < 0)
return r;
@ -588,7 +588,7 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va
return -EINVAL;
if (p != value) {
hostname = strndupa(value, p - value);
hostname = strndupa_safe(value, p - value);
if (!hostname_is_valid(hostname, 0))
return -EINVAL;
}
@ -600,7 +600,7 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va
if (!p)
return -EINVAL;
ifname = strndupa(value, p - value);
ifname = strndupa_safe(value, p - value);
value = p + 1;
@ -609,7 +609,7 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va
if (!p)
dhcp_type = value;
else
dhcp_type = strndupa(value, p - value);
dhcp_type = strndupa_safe(value, p - value);
r = network_set_dhcp_type(context, ifname, dhcp_type);
if (r < 0)
@ -644,7 +644,7 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va
if (r < 0)
return r;
} else {
dns = strndupa(value, p - value);
dns = strndupa_safe(value, p - value);
r = network_set_dns(context, ifname, dns);
if (r < 0)
return r;
@ -666,14 +666,14 @@ static int parse_cmdline_ip_interface(Context *context, const char *value) {
if (!p)
return -EINVAL;
ifname = strndupa(value, p - value);
ifname = strndupa_safe(value, p - value);
value = p + 1;
p = strchr(value, ':');
if (!p)
dhcp_type = value;
else
dhcp_type = strndupa(value, p - value);
dhcp_type = strndupa_safe(value, p - value);
r = network_set_dhcp_type(context, ifname, dhcp_type);
if (r < 0)
@ -726,7 +726,7 @@ static int parse_cmdline_rd_route(Context *context, const char *key, const char
if (p[1] != ':')
return -EINVAL;
buf = strndupa(value + 1, p - value - 1);
buf = strndupa_safe(value + 1, p - value - 1);
value = p + 2;
family = AF_INET6;
} else {
@ -734,7 +734,7 @@ static int parse_cmdline_rd_route(Context *context, const char *key, const char
if (!p)
return -EINVAL;
buf = strndupa(value, p - value);
buf = strndupa_safe(value, p - value);
value = p + 1;
family = AF_INET;
}
@ -786,7 +786,7 @@ static int parse_cmdline_vlan(Context *context, const char *key, const char *val
if (!p)
return -EINVAL;
name = strndupa(value, p - value);
name = strndupa_safe(value, p - value);
netdev = netdev_get(context, name);
if (!netdev) {
@ -810,7 +810,7 @@ static int parse_cmdline_bridge(Context *context, const char *key, const char *v
if (!p)
return -EINVAL;
name = strndupa(value, p - value);
name = strndupa_safe(value, p - value);
netdev = netdev_get(context, name);
if (!netdev) {
@ -848,7 +848,7 @@ static int parse_cmdline_bond(Context *context, const char *key, const char *val
if (!p)
return -EINVAL;
name = strndupa(value, p - value);
name = strndupa_safe(value, p - value);
netdev = netdev_get(context, name);
if (!netdev) {
@ -862,7 +862,7 @@ static int parse_cmdline_bond(Context *context, const char *key, const char *val
if (!p)
slaves = value;
else
slaves = strndupa(value, p - value);
slaves = strndupa_safe(value, p - value);
if (isempty(slaves))
return -EINVAL;
@ -907,7 +907,7 @@ static int parse_cmdline_ifname(Context *context, const char *key, const char *v
if (!p)
return -EINVAL;
name = strndupa(value, p - value);
name = strndupa_safe(value, p - value);
r = ether_addr_from_string(p + 1, &mac);
if (r < 0)

View File

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

View File

@ -718,7 +718,7 @@ static int unit_file_is_active(
at = strchr(name, '@');
assert(at);
prefix = strndupa(name, at + 1 - name);
prefix = strndupa_safe(name, at + 1 - name);
joined = strjoina(prefix, "*", at + 1);
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, '?');
if (q) {
n = strndupa(p, q - p);
n = strndupa_safe(p, q - p);
q++;
for (;;) {
@ -1001,7 +1001,7 @@ static int resolve_tlsa(sd_bus *bus, const char *family, const char *address) {
if (r < 0)
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",

View File

@ -130,7 +130,7 @@ int bus_property_get_rlimit(
int z;
/* 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" */
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)
return -EINVAL;
pp = strndupa(path, e - path);
pp = strndupa_safe(path, e - path);
r = add_cgroup(cgroups, pp, false, &parent);
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, ' ');
if (e) {
path = strndupa(eq, e - eq);
path = strndupa_safe(eq, e - eq);
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.",
field, eq);
path = strndupa(eq, e - eq);
path = strndupa_safe(eq, e - eq);
bandwidth = e+1;
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.",
field, eq);
path = strndupa(eq, e - eq);
path = strndupa_safe(eq, e - eq);
weight = e+1;
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.",
field, eq);
path = strndupa(eq, e - eq);
path = strndupa_safe(eq, e - eq);
target = e+1;
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),
"Not an assignment: %s", assignment);
field = strndupa(assignment, eq - assignment);
field = strndupa_safe(assignment, eq - assignment);
eq++;
switch (t) {

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 */
prefix = strndupa(name, saved_before - name);
prefix = strndupa_safe(name, saved_before - name);
r = dns_name_concat(prefix, new_suffix, 0, ret);
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))
return false;
s = strndupa(label, n);
s = strndupa_safe(label, n);
return dns_service_name_is_valid(s);
}

View File

@ -316,7 +316,7 @@ int journal_importer_process_data(JournalImporter *imp) {
if (!journal_field_valid(line, sep - line, true)) {
char buf[64], *t;
t = strndupa(line, sep - line);
t = strndupa_safe(line, sep - line);
log_debug("Ignoring invalid field: \"%s\"",
cellescape(buf, sizeof buf, t));
@ -335,7 +335,7 @@ int journal_importer_process_data(JournalImporter *imp) {
if (!journal_field_valid(line, n - 1, true)) {
char buf[64], *t;
t = strndupa(line, n - 1);
t = strndupa_safe(line, n - 1);
log_debug("Ignoring invalid field: \"%s\"",
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)
return 1;
s = strndupa(name, n);
s = strndupa_safe(name, n);
return set_contains(fields, s);
}
@ -972,7 +972,7 @@ static int update_json_data_split(
if (!journal_field_valid(data, fieldlen, true))
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))
return 0;

View File

@ -309,8 +309,8 @@ int show_man_page(const char *desc, bool null_stdio) {
if (e) {
char *page = NULL, *section = NULL;
page = strndupa(desc, e - desc);
section = strndupa(e + 1, desc + k - e - 2);
page = strndupa_safe(desc, e - desc);
section = strndupa_safe(e + 1, desc + k - e - 2);
args[1] = section;
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)
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 */
mac_selinux_maybe_reload();

View File

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

View File

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

View File

@ -438,7 +438,8 @@ static int resolve_remote(Connection *c) {
service = strrchr(arg_remote_host, ':');
if (service) {
node = strndupa(arg_remote_host, service - arg_remote_host);
node = strndupa_safe(arg_remote_host,
service - arg_remote_host);
service++;
} else {
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 */
filename_no_sh = strdupa(filename);
filename_no_sh = strdupa_safe(filename);
e = endswith(filename_no_sh, ".sh");
if (e) {
*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");
if (old_tz)
old_tz = strdupa(old_tz);
old_tz = strdupa_safe(old_tz);
if (!isempty(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);
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));
}
}
@ -191,7 +191,7 @@ static void test_unbase32hexmem_one(const char *hex, bool padding, int retval, c
if (retval == 0) {
char *str;
str = strndupa(mem, len);
str = strndupa_safe(mem, len);
assert_se(streq(str, ans));
}
}

View File

@ -53,45 +53,45 @@ static void test_hostname_cleanup(void) {
log_info("/* %s */", __func__);
s = strdupa("foobar");
s = strdupa_safe("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"));
s = strdupa("foobar.com.");
s = strdupa_safe("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"));
s = strdupa("foo-bar-.-com-.");
s = strdupa_safe("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"));
s = strdupa("fooBAR");
s = strdupa_safe("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"));
s = strdupa("fooBAR.");
s = strdupa_safe("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"));
s = strdupa("fööbar");
s = strdupa_safe("fööbar");
assert_se(streq(hostname_cleanup(s), "fbar"));
s = strdupa("");
s = strdupa_safe("");
assert_se(isempty(hostname_cleanup(s)));
s = strdupa(".");
s = strdupa_safe(".");
assert_se(isempty(hostname_cleanup(s)));
s = strdupa("..");
s = strdupa_safe("..");
assert_se(isempty(hostname_cleanup(s)));
s = strdupa("foobar.");
s = strdupa_safe("foobar.");
assert_se(streq(hostname_cleanup(s), "foobar"));
s = strdupa(".foobar");
s = strdupa_safe(".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"));
s = strdupa("foo.bar..");
s = strdupa_safe("foo.bar..");
assert_se(streq(hostname_cleanup(s), "foo.bar"));
s = strdupa("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
s = strdupa_safe("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
assert_se(streq(hostname_cleanup(s), "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
s = strdupa("xxxx........xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
s = strdupa_safe("xxxx........xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
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) {
char *p;
p = strdupa(in);
p = strdupa_safe(in);
path_simplify(p);
log_debug("/* test_path_simplify(%s) → %s (expected: %s) */", in, p, out);
assert_se(streq(p, out));

View File

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

View File

@ -77,7 +77,7 @@ static int print_status_info(const StatusInfo *i) {
/* Save the old $TZ */
tz = getenv("TZ");
if (tz)
old_tz = strdupa(tz);
old_tz = strdupa_safe(tz);
/* Set the new $TZ */
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) {
char *str;
str = strdupa(dmi_string(h, s));
str = strdupa_safe(dmi_string(h, s));
str = strstrip(str);
if (!isempty(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)
return NULL;
base = strndupa(base, pos - base);
base = strndupa_safe(base, pos - base);
dir = opendir(base);
if (!dir)
return NULL;

View File

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