1
0
mirror of https://github.com/systemd/systemd synced 2026-03-16 10:04:47 +01:00

Compare commits

...

22 Commits

Author SHA1 Message Date
Lennart Poettering
f5e775973a sd-device: use strjoina() more again in sd_device_new_from_subsystem_sysname()
This reverts a major part of: e17c95af8e450caacde692875b30675cea75211f

Using format strings for concatenating strings is pretty unefficient,
and using PATH_MAX buffers unpretty as well. Let's revert to using
strjoina() as before.

However, to fix the fuzz issue at hand, let's explicitly verify the two
input strings ensuring they are valid path names. This includes a length
check (to 2K each), thus making things prettier, faster and using less
memory again.
2021-05-21 17:52:57 +02:00
Lennart Poettering
a6383f1e93
Merge pull request #19676 from bluca/coverity
Fix two new coverity issues
2021-05-21 17:52:36 +02:00
Lennart Poettering
2c80660557
Merge pull request #19672 from yuwata/strextend
tree-wide: introduce strextendf_with_separator() and use strextend() or freinds
2021-05-21 17:52:14 +02:00
Lennart Poettering
674d8dcc47
Merge pull request #19647 from ddstreet/test-oomd-failure
handle lack of kernel support for some cgroup files
2021-05-21 16:35:16 +02:00
Dan Streetman
135400276c oom: log one-time warning if kernel doesn't provide memory.swap.current
The kernel can be compiled without support for any memory.swap.* files, or
it can be disabled at boot time with the 'swapaccount=0' boot parameter,
so if the file doesn't exist log warning indicating the kernel doesn't
support the file and the user may need to try using the 'swapaccount=1'
boot param.

Note that the actual error from the call to fopen() is ENOENT, but
that is translated into ENODATA in cg_get_attribute_as_uint64()
2021-05-20 15:40:29 -04:00
Dan Streetman
0de2fd1870 psi: update is_pressure_supported to read file
The kernel still provides the /proc and cgroup pressure files even
if its psi support is disabled, so we need to actually read the files
to verify they don't return -EOPNOTSUPP
2021-05-20 15:40:21 -04:00
Dan Streetman
264f0afe0d log: add log_once() and log_once_errno() macros
These macros will log a message at the specified level only the first time
they are called. On all later calls, if the specified level is debug, the
logs will be suppressed; otherwise the message will be logged at debug.
2021-05-20 15:39:15 -04:00
Dan Streetman
ea42da3825 macro: add ONCE macro that evaluates to 1 one time
Every location that this macro is used, it will be true the first
time it's checked, then false each time after that.

This can be useful for things such as one-time logging.
2021-05-20 15:39:15 -04:00
Lennart Poettering
f267c3142a fileio: make return parameters of read_virtual_file() optional
Prompted by: #19647
2021-05-20 15:39:03 -04:00
Yu Watanabe
580bf61304 sysv-generator: use strextend_with_separator() 2021-05-20 21:57:09 +09:00
Yu Watanabe
742a011a3a systemctl: use strextend_with_separator() 2021-05-20 21:57:09 +09:00
Yu Watanabe
eda397c966 run: use strextend_with_separator() 2021-05-20 21:57:09 +09:00
Yu Watanabe
cfea7618f2 nspawn: use strextendf_with_separator() 2021-05-20 21:57:04 +09:00
Luca Boccassi
f09e336b3a resolved: check return value of gcrypt APIs
Coverity complains about missing error check.

CID #1453234
2021-05-20 10:47:41 +01:00
Luca Boccassi
06a368e819 journal: fix uninitialized variable use
If the journal file being processed is archivied, seqnum_id will not be
initialized before being passed on, and coverity complains.
Initialize it to zero.

CID #1453235
2021-05-20 10:47:41 +01:00
Yu Watanabe
4ff6ff9a91 networkctl: use strextend() 2021-05-20 18:18:56 +09:00
Yu Watanabe
03c324c578 sd-bus: use strextend() 2021-05-20 18:18:56 +09:00
Yu Watanabe
f8abe13f32 escape: use strextend() 2021-05-20 18:18:56 +09:00
Yu Watanabe
a2a7b77260 pid1: use strextend_with_separator() 2021-05-20 18:18:56 +09:00
Yu Watanabe
2b070200f1 env-util: use strextend() 2021-05-20 18:18:56 +09:00
Yu Watanabe
4304f68d15 network: route: make log_route_debug() show weight for multipath route 2021-05-20 18:18:52 +09:00
Yu Watanabe
6b13ca8ada string-util: introduce strextendf_with_separator() 2021-05-20 18:16:51 +09:00
22 changed files with 214 additions and 177 deletions

View File

@ -572,12 +572,9 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) {
t = strv_env_get_n(env, word+2, e-word-2, flags);
k = strjoin(r, t);
if (!k)
if (!strextend(&r, t))
return NULL;
free_and_replace(r, k);
word = e+1;
state = WORD;
} else if (*e == ':') {
@ -627,12 +624,9 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) {
else if (!t && state == DEFAULT_VALUE)
t = v = replace_env_n(test_value, e-test_value, env, flags);
k = strjoin(r, t);
if (!k)
if (!strextend(&r, t))
return NULL;
free_and_replace(r, k);
word = e+1;
state = WORD;
}
@ -646,12 +640,9 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) {
t = strv_env_get_n(env, word+1, e-word-1, flags);
k = strjoin(r, t);
if (!k)
if (!strextend(&r, t))
return NULL;
free_and_replace(r, k);
word = e--;
i--;
state = WORD;

View File

@ -371,8 +371,6 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents
int n_retries;
bool truncated = false;
assert(ret_contents);
/* Virtual filesystems such as sysfs or procfs use kernfs, and kernfs can work with two sorts of
* virtual files. One sort uses "seq_file", and the results of the first read are buffered for the
* second read. The other sort uses "raw" reads which always go direct to the device. In the latter
@ -486,6 +484,8 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents
return -EBADMSG;
buf[n] = 0;
if (ret_contents)
*ret_contents = TAKE_PTR(buf);
return !truncated;

View File

@ -236,6 +236,29 @@ int log_emergency_level(void);
#define log_error_errno(error, ...) log_full_errno(LOG_ERR, error, __VA_ARGS__)
#define log_emergency_errno(error, ...) log_full_errno(log_emergency_level(), error, __VA_ARGS__)
/* This logs at the specified level the first time it is called, and then
* logs at debug. If the specified level is debug, this logs only the first
* time it is called. */
#define log_once(level, ...) \
({ \
if (ONCE) \
log_full(level, __VA_ARGS__); \
else if (LOG_PRI(level) != LOG_DEBUG) \
log_debug(__VA_ARGS__); \
})
#define log_once_errno(level, error, ...) \
({ \
int _err = (error); \
if (ONCE) \
_err = log_full_errno(level, _err, __VA_ARGS__); \
else if (LOG_PRI(level) != LOG_DEBUG) \
_err = log_debug_errno(_err, __VA_ARGS__); \
else \
_err = -ERRNO_VALUE(_err); \
_err; \
})
#if LOG_TRACE
# define log_trace(...) log_debug(__VA_ARGS__)
#else

View File

@ -790,8 +790,8 @@ char *strextend_with_separator_internal(char **x, const char *separator, ...) {
return p;
}
int strextendf(char **x, const char *format, ...) {
size_t m, a;
int strextendf_with_separator(char **x, const char *separator, const char *format, ...) {
size_t m, a, l_separator;
va_list ap;
int l;
@ -802,6 +802,8 @@ int strextendf(char **x, const char *format, ...) {
assert(x);
assert(format);
l_separator = isempty(*x) ? 0 : strlen_ptr(separator);
/* 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);
@ -810,13 +812,15 @@ int strextendf(char **x, const char *format, ...) {
} else
m = a = 0;
if (a - m < 17) { /* if there's less than 16 chars space, then enlarge the buffer first */
if (a - m < 17 + l_separator) { /* if there's less than 16 chars space, then enlarge the buffer first */
char *n;
if (_unlikely_(m > SIZE_MAX - 64)) /* overflow check */
if (_unlikely_(l_separator > SIZE_MAX - 64)) /* overflow check #1 */
return -ENOMEM;
if (_unlikely_(m > SIZE_MAX - 64 - l_separator)) /* overflow check #2 */
return -ENOMEM;
n = realloc(*x, m + 64);
n = realloc(*x, m + 64 + l_separator);
if (!n)
return -ENOMEM;
@ -825,19 +829,20 @@ int strextendf(char **x, const char *format, ...) {
}
/* Now, let's try to format the string into it */
memcpy_safe(*x + m, separator, l_separator);
va_start(ap, format);
l = vsnprintf(*x + m, a - m, format, ap);
l = vsnprintf(*x + m + l_separator, a - m - l_separator, format, ap);
va_end(ap);
assert(l >= 0);
if ((size_t) l < a - m) {
if ((size_t) l < a - m - l_separator) {
char *n;
/* Nice! This worked. We are done. But first, let's return the extra space we don't
* need. This should be a cheap operation, since we only lower the allocation size here,
* never increase. */
n = realloc(*x, m + (size_t) l + 1);
n = realloc(*x, m + (size_t) l + l_separator + 1);
if (n)
*x = n;
} else {
@ -845,22 +850,22 @@ int strextendf(char **x, const char *format, ...) {
/* Wasn't enough. Then let's allocate exactly what we need. */
if (_unlikely_((size_t) l > SIZE_MAX - 1)) /* overflow check #1 */
if (_unlikely_((size_t) l > SIZE_MAX - (l_separator + 1))) /* overflow check #1 */
goto oom;
if (_unlikely_(m > SIZE_MAX - ((size_t) l + 1))) /* overflow check #2 */
if (_unlikely_(m > SIZE_MAX - ((size_t) l + l_separator + 1))) /* overflow check #2 */
goto oom;
a = m + (size_t) l + 1;
a = m + (size_t) l + l_separator + 1;
n = realloc(*x, a);
if (!n)
goto oom;
*x = n;
va_start(ap, format);
l = vsnprintf(*x + m, a - m, format, ap);
l = vsnprintf(*x + m + l_separator, a - m - l_separator, format, ap);
va_end(ap);
assert((size_t) l < a - m);
assert((size_t) l < a - m - l_separator);
}
return 0;

View File

@ -156,11 +156,11 @@ char *strreplace(const char *text, const char *old_string, const char *new_strin
char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]);
char *strextend_with_separator_internal(char **x, const char *separator, ...) _sentinel_;
#define strextend_with_separator(x, separator, ...) strextend_with_separator_internal(x, separator, __VA_ARGS__, NULL)
#define strextend(x, ...) strextend_with_separator_internal(x, NULL, __VA_ARGS__, NULL)
int strextendf(char **x, const char *format, ...) _printf_(2,3);
int strextendf_with_separator(char **x, const char *separator, const char *format, ...) _printf_(3,4);
#define strextendf(x, ...) strextendf_with_separator(x, NULL, __VA_ARGS__)
char *strrep(const char *s, unsigned n);

View File

@ -181,7 +181,7 @@ int bus_read_mount_options(
return r;
while ((r = sd_bus_message_read(message, "(ss)", &partition, &mount_options)) > 0) {
_cleanup_free_ char *previous = NULL, *escaped = NULL;
_cleanup_free_ char *escaped = NULL;
_cleanup_free_ MountOptions *o = NULL;
PartitionDesignator partition_designator;
@ -198,9 +198,7 @@ int bus_read_mount_options(
if (!escaped)
return -ENOMEM;
previous = TAKE_PTR(format_str);
format_str = strjoin(previous, previous ? separator : "", partition, ":", escaped);
if (!format_str)
if (!strextend_with_separator(&format_str, separator, partition, ":", escaped))
return -ENOMEM;
o = new(MountOptions, 1);

View File

@ -188,13 +188,8 @@ static int run(int argc, char *argv[]) {
free_and_replace(e, x);
} else if (arg_suffix) {
char *x;
x = strjoin(e, ".", arg_suffix);
if (!x)
if (!strextend(&e, ".", arg_suffix))
return log_oom();
free_and_replace(e, x);
}
break;

View File

@ -50,6 +50,17 @@
#define UNIQ_T(x, uniq) CONCATENATE(__unique_prefix_, CONCATENATE(x, uniq))
#define UNIQ __COUNTER__
/* Note that this works differently from pthread_once(): this macro does
* not synchronize code execution, i.e. code that is run conditionalized
* on this macro will run concurrently to all other code conditionalized
* the same way, there's no ordering or completion enforced. */
#define ONCE __ONCE(UNIQ_T(_once_, UNIQ))
#define __ONCE(o) \
({ \
static bool (o) = false; \
__sync_bool_compare_and_swap(&(o), false, true); \
})
#undef MAX
#define MAX(a, b) __MAX(UNIQ, (a), UNIQ, (b))
#define __MAX(aq, a, bq, b) \

View File

@ -1574,18 +1574,12 @@ int bus_set_address_machine(sd_bus *b, bool user, const char *machine) {
return -ENOMEM;
if (user) {
char *k;
/* Ideally we'd use the "--user" switch to systemd-stdio-bridge here, but it's only
* available in recent systemd versions. Using the "-p" switch with the explicit path
* is a working alternative, and is compatible with older versions, hence that's what
* we use here. */
k = strjoin(a, ",argv7=-punix:path%3d%24%7bXDG_RUNTIME_DIR%7d/bus");
if (!k)
if (!strextend(&a, ",argv7=-punix:path%3d%24%7bXDG_RUNTIME_DIR%7d/bus"))
return -ENOMEM;
free_and_replace(a, k);
}
} else {
_cleanup_free_ char *e = NULL;

View File

@ -244,71 +244,103 @@ _public_ int sd_device_new_from_devnum(sd_device **ret, char type, dev_t devnum)
return sd_device_new_from_syspath(ret, syspath);
}
_public_ int sd_device_new_from_subsystem_sysname(sd_device **ret, const char *subsystem, const char *sysname) {
char syspath[PATH_MAX], *name;
static int device_strjoin_new(
const char *a,
const char *b,
const char *c,
const char *d,
sd_device **ret) {
const char *p;
int r;
p = strjoina(a, b, c, d);
if (access(p, F_OK) < 0)
return IN_SET(errno, ENOENT, ENAMETOOLONG) ? 0 : -errno; /* If this sysfs is too long then it doesn't exist either */
r = sd_device_new_from_syspath(ret, p);
if (r < 0)
return r;
return 1;
}
_public_ int sd_device_new_from_subsystem_sysname(
sd_device **ret,
const char *subsystem,
const char *sysname) {
const char *s;
char *name;
int r;
assert_return(ret, -EINVAL);
assert_return(subsystem, -EINVAL);
assert_return(sysname, -EINVAL);
assert_return(strlen(sysname) < PATH_MAX - strlen("/sys/bus/"), -ENAMETOOLONG);
assert_return(path_is_normalized(subsystem), -EINVAL);
assert_return(path_is_normalized(sysname), -EINVAL);
if (streq(subsystem, "subsystem")) {
if (snprintf_ok(syspath, sizeof syspath, "/sys/subsystem/%s", sysname) &&
access(syspath, F_OK) >= 0)
return sd_device_new_from_syspath(ret, syspath);
if (snprintf_ok(syspath, sizeof syspath, "/sys/bus/%s", sysname) &&
access(syspath, F_OK) >= 0)
return sd_device_new_from_syspath(ret, syspath);
if (snprintf_ok(syspath, sizeof syspath, "/sys/class/%s", sysname) &&
access(syspath, F_OK) >= 0)
return sd_device_new_from_syspath(ret, syspath);
FOREACH_STRING(s, "/sys/subsystem/", "/sys/bus/", "/sys/class/") {
r = device_strjoin_new(s, sysname, NULL, NULL, ret);
if (r < 0)
return r;
if (r > 0)
return 0;
}
} else if (streq(subsystem, "module")) {
if (snprintf_ok(syspath, sizeof syspath, "/sys/module/%s", sysname) &&
access(syspath, F_OK) >= 0)
return sd_device_new_from_syspath(ret, syspath);
r = device_strjoin_new("/sys/module/", sysname, NULL, NULL, ret);
if (r < 0)
return r;
if (r > 0)
return 0;
} else if (streq(subsystem, "drivers")) {
const char *subsys, *sep;
const char *sep;
sep = strchr(sysname, ':');
if (sep && sep[1] != '\0') { /* Require ":" and something non-empty after that. */
const char *subsys;
subsys = memdupa_suffix0(sysname, sep - sysname);
sep++;
if (snprintf_ok(syspath, sizeof syspath, "/sys/subsystem/%s/drivers/%s", subsys, sep + 1) &&
access(syspath, F_OK) >= 0)
return sd_device_new_from_syspath(ret, syspath);
if (snprintf_ok(syspath, sizeof syspath, "/sys/bus/%s/drivers/%s", subsys, sep + 1) &&
access(syspath, F_OK) >= 0)
return sd_device_new_from_syspath(ret, syspath);
FOREACH_STRING(s, "/sys/subsystem/", "/sys/bus/") {
r = device_strjoin_new(s, subsys, "/drivers/", sep, ret);
if (r < 0)
return r;
if (r > 0)
return 0;
}
}
}
/* translate sysname back to sysfs filename */
name = strdupa(sysname);
for (size_t i = 0; name[i]; i++)
if (name[i] == '/')
name[i] = '!';
if (snprintf_ok(syspath, sizeof syspath, "/sys/subsystem/%s/devices/%s", subsystem, name) &&
access(syspath, F_OK) >= 0)
return sd_device_new_from_syspath(ret, syspath);
FOREACH_STRING(s, "/sys/subsystem/", "/sys/bus/") {
r = device_strjoin_new(s, subsystem, "/devices/", name, ret);
if (r < 0)
return r;
if (r > 0)
return 0;
}
if (snprintf_ok(syspath, sizeof syspath, "/sys/bus/%s/devices/%s", subsystem, name) &&
access(syspath, F_OK) >= 0)
return sd_device_new_from_syspath(ret, syspath);
r = device_strjoin_new("/sys/class/", subsystem, "/", name, ret);
if (r < 0)
return r;
if (r > 0)
return 0;
if (snprintf_ok(syspath, sizeof syspath, "/sys/class/%s/%s", subsystem, name) &&
access(syspath, F_OK) >= 0)
return sd_device_new_from_syspath(ret, syspath);
if (snprintf_ok(syspath, sizeof syspath, "/sys/firmware/%s/%s", subsystem, sysname) &&
access(syspath, F_OK) >= 0)
return sd_device_new_from_syspath(ret, syspath);
r = device_strjoin_new("/sys/firmware/", subsystem, "/", sysname, ret);
if (r < 0)
return r;
if (r > 0)
return 0;
return -ENODEV;
}

View File

@ -206,6 +206,9 @@ int journal_directory_vacuum(
} else if (endswith(de->d_name, ".journal~")) {
unsigned long long tmp;
/* seqnum_id won't be initialised before use below, so set to 0 */
seqnum_id = SD_ID128_NULL;
/* Vacuum corrupted files */
if (q < 1 + 16 + 1 + 16 + 8 + 1) {

View File

@ -1046,26 +1046,25 @@ static int dump_gateways(
return n;
for (int i = 0; i < n; i++) {
_cleanup_free_ char *gateway = NULL, *description = NULL, *with_description = NULL;
_cleanup_free_ char *gateway = NULL, *description = NULL;
char name[IF_NAMESIZE+1];
r = in_addr_to_string(local[i].family, &local[i].address, &gateway);
if (r < 0)
return r;
return log_oom();
r = get_gateway_description(rtnl, hwdb, local[i].ifindex, local[i].family, &local[i].address, &description);
if (r < 0)
log_debug_errno(r, "Could not get description of gateway, ignoring: %m");
if (description) {
with_description = strjoin(gateway, " (", description, ")");
if (!with_description)
if (!strextend(&gateway, " (", description, ")"))
return log_oom();
}
/* Show interface name for the entry if we show entries for all interfaces */
r = strv_extendf(&buf, "%s%s%s",
with_description ?: gateway,
gateway,
ifindex <= 0 ? " on " : "",
ifindex <= 0 ? format_ifname_full(local[i].ifindex, name, FORMAT_IFNAME_IFINDEX_WITH_PERCENT) : "");
if (r < 0)

View File

@ -773,13 +773,17 @@ static void log_route_debug(const Route *route, const char *str, const Link *lin
MultipathRoute *m;
ORDERED_SET_FOREACH(m, route->multipath_routes) {
_cleanup_free_ char *buf = NULL, *joined = NULL;
_cleanup_free_ char *buf = NULL;
union in_addr_union a = m->gateway.address;
(void) in_addr_to_string(m->gateway.family, &a, &buf);
joined = strjoin(gw_alloc, gw_alloc ? "," : "", strna(buf), m->ifname ? "@" : "", strempty(m->ifname));
if (joined)
free_and_replace(gw_alloc, joined);
(void) strextend_with_separator(&gw_alloc, ",", strna(buf));
if (m->ifname)
(void) strextend(&gw_alloc, "@", m->ifname);
else if (m->ifindex > 0)
(void) strextendf(&gw_alloc, "@%"PRIu32, m->ifindex);
/* See comments in config_parse_multipath_route(). */
(void) strextendf(&gw_alloc, ":%"PRIu32, m->weight + 1);
}
gw = gw_alloc;
}

View File

@ -382,39 +382,28 @@ int tmpfs_patch_options(
const char *selinux_apifs_context,
char **ret) {
char *buf = NULL;
_cleanup_free_ char *buf = NULL;
if (uid_shift != UID_INVALID) {
if (asprintf(&buf, "%s%suid=" UID_FMT ",gid=" UID_FMT,
strempty(options), options ? "," : "",
uid_shift, uid_shift) < 0)
return -ENOMEM;
assert(ret);
options = buf;
}
#if HAVE_SELINUX
if (selinux_apifs_context) {
char *t;
t = strjoin(strempty(options), options ? "," : "",
"context=\"", selinux_apifs_context, "\"");
free(buf);
if (!t)
return -ENOMEM;
buf = t;
}
#endif
if (!buf && options) {
if (options) {
buf = strdup(options);
if (!buf)
return -ENOMEM;
}
*ret = buf;
return !!buf;
if (uid_shift != UID_INVALID)
if (strextendf_with_separator(&buf, ",", "uid=" UID_FMT ",gid=" UID_FMT, uid_shift, uid_shift) < 0)
return -ENOMEM;
#if HAVE_SELINUX
if (selinux_apifs_context)
if (!strextend_with_separator(&buf, ",", "context=\"", selinux_apifs_context, "\""))
return -ENOMEM;
#endif
*ret = TAKE_PTR(buf);
return !!*ret;
}
int mount_sysfs(const char *dest, MountSettingsMask mount_settings) {

View File

@ -333,7 +333,11 @@ int oomd_cgroup_context_acquire(const char *path, OomdCGroupContext **ret) {
return log_debug_errno(r, "Error getting memory.low from %s: %m", path);
r = cg_get_attribute_as_uint64(SYSTEMD_CGROUP_CONTROLLER, path, "memory.swap.current", &ctx->swap_usage);
if (r < 0)
if (r == -ENODATA)
/* The kernel can be compiled without support for memory.swap.* files,
* or it can be disabled with boot param 'swapaccount=0' */
log_once(LOG_WARNING, "No kernel support for memory.swap.current from %s (try boot param swapaccount=1), ignoring.", path);
else if (r < 0)
return log_debug_errno(r, "Error getting memory.swap.current from %s: %m", path);
r = cg_get_keyed_attribute(SYSTEMD_CGROUP_CONTROLLER, path, "memory.stat", STRV_MAKE("pgscan"), &val);

View File

@ -805,7 +805,9 @@ int dnssec_verify_rrset(
case DNSSEC_ALGORITHM_ED448:
*result = DNSSEC_UNSUPPORTED_ALGORITHM;
return 0;
default:
default: {
gcry_error_t err;
/* OK, the RRs are now in canonical order. Let's calculate the digest */
md_algorithm = algorithm_to_gcrypt_md(rrsig->rrsig.algorithm);
if (md_algorithm == -EOPNOTSUPP) {
@ -815,8 +817,8 @@ int dnssec_verify_rrset(
if (md_algorithm < 0)
return md_algorithm;
gcry_md_open(&md, md_algorithm, 0);
if (!md)
err = gcry_md_open(&md, md_algorithm, 0);
if (gcry_err_code(err) != GPG_ERR_NO_ERROR || !md)
return -EIO;
hash_size = gcry_md_get_algo_dlen(md_algorithm);
@ -828,6 +830,7 @@ int dnssec_verify_rrset(
if (!hash)
return -EIO;
}
}
switch (rrsig->rrsig.algorithm) {

View File

@ -667,15 +667,8 @@ static int transient_cgroup_set_properties(sd_bus_message *m) {
*end = 0;
}
if (!isempty(arg_slice)) {
if (name) {
char *j = strjoin(name, "-", arg_slice);
free_and_replace(name, j);
} else
name = strdup(arg_slice);
if (!name)
if (!isempty(arg_slice) && !strextend_with_separator(&name, "-", arg_slice))
return log_oom();
}
if (!name)
return 0;

View File

@ -4,6 +4,7 @@
#include <unistd.h>
#include "alloc-util.h"
#include "errno-util.h"
#include "extract-word.h"
#include "fd-util.h"
#include "fileio.h"
@ -107,11 +108,17 @@ int read_resource_pressure(const char *path, PressureType type, ResourcePressure
int is_pressure_supported(void) {
const char *p;
FOREACH_STRING(p, "/proc/pressure/cpu", "/proc/pressure/io", "/proc/pressure/memory")
if (access(p, F_OK) < 0) {
if (errno == ENOENT)
/* The pressure files, both under /proc and in cgroups, will exist
* even if the kernel has PSI support disabled; we have to read
* the file to make sure it doesn't return -EOPNOTSUPP */
FOREACH_STRING(p, "/proc/pressure/cpu", "/proc/pressure/io", "/proc/pressure/memory") {
int r;
r = read_virtual_file(p, 0, NULL, NULL);
if (r == -ENOENT || ERRNO_IS_NOT_SUPPORTED(r))
return 0;
return -errno;
if (r < 0)
return r;
}
return 1;

View File

@ -1659,14 +1659,9 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
if (r < 0)
return r;
while ((r = sd_bus_message_read(m, "(ss)", &partition, &mount_options)) > 0) {
_cleanup_free_ char *previous = NULL;
previous = TAKE_PTR(str);
str = strjoin(strempty(previous), previous ? ":" : "", partition, ":", mount_options);
if (!str)
while ((r = sd_bus_message_read(m, "(ss)", &partition, &mount_options)) > 0)
if (!strextend_with_separator(&str, ":", partition, ":", mount_options))
return log_oom();
}
if (r < 0)
return r;

View File

@ -533,7 +533,7 @@ static int load_sysv(SysvStub *s) {
* continuation */
size_t k;
char *j;
const char *j;
k = strlen(t);
if (k > 0 && t[k-1] == '\\')
@ -542,20 +542,9 @@ static int load_sysv(SysvStub *s) {
state = NORMAL;
j = strstrip(t);
if (!isempty(j)) {
char *d = NULL;
if (chkconfig_description)
d = strjoin(chkconfig_description, " ", j);
else
d = strdup(j);
if (!d)
if (!isempty(j) && !strextend_with_separator(&chkconfig_description, " ", j))
return log_oom();
free(chkconfig_description);
chkconfig_description = d;
}
} else if (IN_SET(state, LSB, LSB_DESCRIPTION)) {
if (startswith_no_case(t, "Provides:")) {
@ -604,20 +593,8 @@ static int load_sysv(SysvStub *s) {
const char *j;
j = strstrip(t);
if (!isempty(j)) {
char *d = NULL;
if (long_description)
d = strjoin(long_description, " ", t);
else
d = strdup(j);
if (!d)
if (!isempty(j) && !strextend_with_separator(&long_description, " ", j))
return log_oom();
free(long_description);
long_description = d;
}
} else
state = LSB;
}

View File

@ -984,6 +984,20 @@ static void test_strextendf(void) {
assert_se(strextendf(&p, "<%08x>", 0x1234) >= 0);
assert_se(streq(p, "<77><99>< 88><00001234>"));
p = mfree(p);
assert_se(strextendf_with_separator(&p, ",", "<%i>", 77) >= 0);
assert_se(streq(p, "<77>"));
assert_se(strextendf_with_separator(&p, ",", "<%i>", 99) >= 0);
assert_se(streq(p, "<77>,<99>"));
assert_se(strextendf_with_separator(&p, ",", "<%80i>", 88) >= 0);
assert_se(streq(p, "<77>,<99>,< 88>"));
assert_se(strextendf_with_separator(&p, ",", "<%08x>", 0x1234) >= 0);
assert_se(streq(p, "<77>,<99>,< 88>,<00001234>"));
}
int main(int argc, char *argv[]) {

View File

@ -252,7 +252,7 @@ static void test_udev_resolve_subsys_kernel(void) {
test_udev_resolve_subsys_kernel_one("hoge", false, -EINVAL, NULL);
test_udev_resolve_subsys_kernel_one("[hoge", false, -EINVAL, NULL);
test_udev_resolve_subsys_kernel_one("[hoge/foo", false, -EINVAL, NULL);
test_udev_resolve_subsys_kernel_one("[hoge/]", false, -ENODEV, NULL);
test_udev_resolve_subsys_kernel_one("[hoge/]", false, -EINVAL, NULL);
test_udev_resolve_subsys_kernel_one("[net/lo]", false, 0, "/sys/devices/virtual/net/lo");
test_udev_resolve_subsys_kernel_one("[net/lo]/", false, 0, "/sys/devices/virtual/net/lo");