1
0
mirror of https://github.com/systemd/systemd synced 2026-03-18 19:14:46 +01:00

Compare commits

..

No commits in common. "fd8a1deb0b17f040ca14c5d3c293dffdb7024ceb" and "cf79f61238fa812d1850987e04d3767ce71dd972" have entirely different histories.

28 changed files with 125 additions and 341 deletions

View File

@ -90,7 +90,7 @@
socket passing (i.e. sockets passed in via standard input and output, using
<varname>StandardInput=socket</varname> in the service file).</para>
<para>By default, network sockets allocated through <filename>.socket</filename> units are allocated in the host's network
<para>All network sockets allocated through <filename>.socket</filename> units are allocated in the host's network
namespace (see <citerefentry
project='man-pages'><refentrytitle>network_namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>). This
does not mean however that the service activated by a configured socket unit has to be part of the host's network
@ -101,11 +101,6 @@
the host's network namespace is only permitted through the activation sockets passed in while all sockets allocated
from the service code itself will be associated with the service's own namespace, and thus possibly subject to a
restrictive configuration.</para>
<para>Alternatively, it is possible to run a <filename>.socket</filename> unit in another network namespace
by setting <option>PrivateNetwork=yes</option> in combination with <varname>JoinsNamespaceOf=</varname>, see
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> and
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details.</para>
</refsect1>
<refsect1>

View File

@ -389,6 +389,11 @@ int container_get_leader(const char *machine, pid_t *pid) {
}
int pid_is_kernel_thread(pid_t pid) {
_cleanup_free_ char *line = NULL;
unsigned long long flags;
size_t l, i;
const char *p;
char *q;
int r;
if (IN_SET(pid, 0, 1) || pid == getpid_cached()) /* pid 1, and we ourselves certainly aren't a kernel thread */
@ -396,8 +401,7 @@ int pid_is_kernel_thread(pid_t pid) {
if (!pid_is_valid(pid))
return -EINVAL;
const char *p = procfs_file_alloca(pid, "stat");
_cleanup_free_ char *line = NULL;
p = procfs_file_alloca(pid, "stat");
r = read_one_line_file(p, &line);
if (r == -ENOENT)
return -ESRCH;
@ -405,14 +409,14 @@ int pid_is_kernel_thread(pid_t pid) {
return r;
/* Skip past the comm field */
char *q = strrchr(line, ')');
q = strrchr(line, ')');
if (!q)
return -EINVAL;
q++;
/* Skip 6 fields to reach the flags field */
for (size_t i = 0; i < 6; i++) {
size_t l = strspn(q, WHITESPACE);
for (i = 0; i < 6; i++) {
l = strspn(q, WHITESPACE);
if (l < 1)
return -EINVAL;
q += l;
@ -424,7 +428,7 @@ int pid_is_kernel_thread(pid_t pid) {
}
/* Skip preceding whitespace */
size_t l = strspn(q, WHITESPACE);
l = strspn(q, WHITESPACE);
if (l < 1)
return -EINVAL;
q += l;
@ -435,7 +439,6 @@ int pid_is_kernel_thread(pid_t pid) {
return -EINVAL;
q[l] = 0;
unsigned long long flags;
r = safe_atollu(q, &flags);
if (r < 0)
return r;
@ -880,23 +883,25 @@ int pidref_wait_for_terminate_and_check(const char *name, PidRef *pidref, WaitFl
siginfo_t status;
r = pidref_wait_for_terminate(pidref, &status);
if (r < 0)
return log_full_errno(prio, r, "Failed to wait for '%s': %m", strna(name));
return log_full_errno(prio, r, "Failed to wait for %s: %m", strna(name));
if (status.si_code == CLD_EXITED) {
if (status.si_status != EXIT_SUCCESS)
log_full(flags & WAIT_LOG_NON_ZERO_EXIT_STATUS ? LOG_ERR : LOG_DEBUG,
"'%s' failed with exit status %i.", strna(name), status.si_status);
"%s failed with exit status %i.", strna(name), status.si_status);
else
log_debug("'%s' succeeded.", name);
log_debug("%s succeeded.", name);
return status.si_status;
} else if (IN_SET(status.si_code, CLD_KILLED, CLD_DUMPED))
return log_full_errno(prio, SYNTHETIC_ERRNO(EPROTO),
"'%s' terminated by signal %s.", strna(name), signal_to_string(status.si_status));
} else if (IN_SET(status.si_code, CLD_KILLED, CLD_DUMPED)) {
return log_full_errno(prio, SYNTHETIC_ERRNO(EPROTO),
"'%s' failed due to unknown reason.", strna(name));
log_full(prio, "%s terminated by signal %s.", strna(name), signal_to_string(status.si_status));
return -EPROTO;
}
log_full(prio, "%s failed due to unknown reason.", strna(name));
return -EPROTO;
}
int kill_and_sigcont(pid_t pid, int sig) {

View File

@ -15,71 +15,51 @@
#include "virt.h"
static int parse_timeout(const char *arg1, char16_t **ret_timeout, size_t *ret_timeout_size) {
char buf[DECIMAL_STR_MAX(usec_t)];
char utf8[DECIMAL_STR_MAX(usec_t)];
char16_t *encoded;
usec_t timeout;
uint64_t loader_features = 0;
bool menu_disabled = false;
int r;
assert(arg1);
assert(ret_timeout);
assert(ret_timeout_size);
assert_cc(STRLEN("menu-force") < ELEMENTSOF(buf));
assert_cc(STRLEN("menu-hidden") < ELEMENTSOF(buf));
assert_cc(STRLEN("menu-disabled") < ELEMENTSOF(buf));
assert_cc(STRLEN("menu-disabled") < ELEMENTSOF(utf8));
/* Use feature EFI_LOADER_FEATURE_MENU_DISABLE as a mark that the boot loader supports the other
* string values too. When unsupported, convert to the timeout with the closest meaning.
/* Note: Since there is no way to query if the bootloader supports the string tokens, we explicitly
* set their numerical value(s) instead. This means that some of the sd-boot internal ABI has leaked
* although the ship has sailed and the side-effects are self-contained.
*/
if (streq(arg1, "menu-force"))
timeout = USEC_INFINITY;
else if (streq(arg1, "menu-hidden"))
timeout = 0;
else if (streq(arg1, "menu-disabled")) {
uint64_t loader_features = 0;
if (streq(arg1, "menu-force")) {
(void) efi_loader_get_features(&loader_features);
if (!(loader_features & EFI_LOADER_FEATURE_MENU_DISABLE)) {
log_debug("Using maximum timeout instead of '%s'.", arg1);
timeout = USEC_INFINITY;
arg1 = NULL;
}
} else if (streq(arg1, "menu-hidden")) {
(void) efi_loader_get_features(&loader_features);
if (!(loader_features & EFI_LOADER_FEATURE_MENU_DISABLE)) {
log_debug("Using zero timeout instead of '%s'.", arg1);
timeout = 0;
arg1 = NULL; /* replace the arg by printed timeout value later */
}
} else if (streq(arg1, "menu-disabled")) {
(void) efi_loader_get_features(&loader_features);
if (!(loader_features & EFI_LOADER_FEATURE_MENU_DISABLE)) {
if (arg_graceful() == ARG_GRACEFUL_NO)
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"Loader does not support '%s'.", arg1);
log_warning("Using zero timeout instead of '%s'.", arg1);
timeout = 0;
arg1 = NULL;
}
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Loader does not support 'menu-disabled'.");
log_warning("Loader does not support 'menu-disabled', setting anyway.");
}
menu_disabled = true;
} else {
r = parse_time(arg1, &timeout, USEC_PER_SEC);
if (r < 0)
return log_error_errno(r, "Failed to parse timeout '%s': %m", arg1);
assert_cc(USEC_INFINITY > UINT32_MAX * USEC_PER_SEC);
if (timeout > UINT32_MAX * USEC_PER_SEC && timeout != USEC_INFINITY)
log_debug("Timeout is too long and will be clamped to maximum timeout.");
arg1 = NULL;
if (timeout != USEC_INFINITY && timeout > UINT32_MAX * USEC_PER_SEC)
log_warning("Timeout is too long and will be treated as 'menu-force' instead.");
}
if (!arg1) {
timeout = DIV_ROUND_UP(timeout, USEC_PER_SEC);
xsprintf(buf, USEC_FMT, MIN(timeout, UINT32_MAX));
}
if (menu_disabled)
xsprintf(utf8, "menu-disabled");
else
xsprintf(utf8, USEC_FMT, MIN(timeout / USEC_PER_SEC, UINT32_MAX));
char16_t *encoded = utf8_to_utf16(arg1 ?: buf, SIZE_MAX);
encoded = utf8_to_utf16(utf8, SIZE_MAX);
if (!encoded)
return log_oom();

View File

@ -804,6 +804,10 @@ static int automount_start(Unit *u) {
if (path_is_mount_point(a->where) > 0)
return log_unit_error_errno(u, SYNTHETIC_ERRNO(EEXIST), "Path %s is already a mount point, refusing start.", a->where);
r = unit_test_trigger_loaded(u);
if (r < 0)
return r;
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@ -1043,10 +1047,6 @@ static int automount_test_startable(Unit *u) {
Automount *a = ASSERT_PTR(AUTOMOUNT(u));
int r;
r = unit_test_trigger_loaded(u);
if (r < 0)
return r;
r = unit_test_start_limit(u);
if (r < 0) {
automount_enter_dead(a, AUTOMOUNT_FAILURE_START_LIMIT_HIT);

View File

@ -5463,14 +5463,17 @@ int exec_invoke(
.sched_flags = context->cpu_sched_reset_on_fork ? SCHED_FLAG_RESET_ON_FORK : 0,
};
r = RET_NERRNO(sched_setattr(/* pid= */ 0, &attr, /* flags= */ 0));
if (r == -EINVAL && !sched_policy_supported(context->cpu_sched_policy)) {
r = sched_setattr(/* pid= */ 0, &attr, /* flags= */ 0);
if (r < 0) {
if (errno != EINVAL || sched_policy_supported(attr.sched_policy)) {
*exit_status = EXIT_SETSCHEDULER;
return log_error_errno(errno, "Failed to set up CPU scheduling: %m");
}
_cleanup_free_ char *s = NULL;
(void) sched_policy_to_string_alloc(context->cpu_sched_policy, &s);
log_warning_errno(r, "CPU scheduling policy %s is not supported, proceeding without.", strna(s));
} else if (r < 0) {
*exit_status = EXIT_SETSCHEDULER;
return log_error_errno(r, "Failed to set up CPU scheduling: %m");
log_warning_errno(errno, "CPU scheduling policy %s is not supported, proceeding without.", strna(s));
}
}

View File

@ -2605,7 +2605,6 @@ int setup_namespace(const NamespaceParameters *p, char **reterr_path) {
r = dissected_image_decrypt(
dissected_image,
/* root= */ NULL,
/* passphrase= */ NULL,
p->verity,
p->root_image_policy,

View File

@ -632,6 +632,10 @@ static int path_start(Unit *u) {
assert(IN_SET(p->state, PATH_DEAD, PATH_FAILED));
r = unit_test_trigger_loaded(u);
if (r < 0)
return r;
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@ -898,10 +902,6 @@ static int path_test_startable(Unit *u) {
Path *p = ASSERT_PTR(PATH(u));
int r;
r = unit_test_trigger_loaded(u);
if (r < 0)
return r;
r = unit_test_start_limit(u);
if (r < 0) {
path_enter_dead(p, PATH_FAILURE_START_LIMIT_HIT);

View File

@ -2623,6 +2623,20 @@ static int socket_start(Unit *u) {
Socket *s = ASSERT_PTR(SOCKET(u));
int r;
/* Cannot run this without the service being around */
if (UNIT_ISSET(s->service)) {
Service *service = ASSERT_PTR(SERVICE(UNIT_DEREF(s->service)));
if (UNIT(service)->load_state != UNIT_LOADED)
return log_unit_error_errno(u, SYNTHETIC_ERRNO(ENOENT),
"Socket service %s not loaded, refusing.", UNIT(service)->id);
/* If the service is already active we cannot start the socket */
if (SOCKET_SERVICE_IS_ACTIVE(service, /* allow_finalize= */ false))
return log_unit_error_errno(u, SYNTHETIC_ERRNO(EBUSY),
"Socket service %s already active, refusing.", UNIT(service)->id);
}
assert(IN_SET(s->state, SOCKET_DEAD, SOCKET_FAILED));
r = unit_acquire_invocation_id(u);
@ -3628,20 +3642,6 @@ static int socket_test_startable(Unit *u) {
SOCKET_START_POST))
return false;
/* Cannot run this without the service being around */
if (UNIT_ISSET(s->service)) {
Service *service = ASSERT_PTR(SERVICE(UNIT_DEREF(s->service)));
if (UNIT(service)->load_state != UNIT_LOADED)
return log_unit_error_errno(u, SYNTHETIC_ERRNO(ENOENT),
"Socket service %s not loaded, refusing.", UNIT(service)->id);
/* If the service is already active we cannot start the socket */
if (SOCKET_SERVICE_IS_ACTIVE(service, /* allow_finalize= */ false))
return log_unit_error_errno(u, SYNTHETIC_ERRNO(EBUSY),
"Socket service %s already active, refusing.", UNIT(service)->id);
}
r = unit_test_start_limit(u);
if (r < 0) {
socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT);

View File

@ -668,6 +668,10 @@ static int timer_start(Unit *u) {
assert(IN_SET(t->state, TIMER_DEAD, TIMER_FAILED));
r = unit_test_trigger_loaded(u);
if (r < 0)
return r;
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@ -913,10 +917,6 @@ static int timer_test_startable(Unit *u) {
Timer *t = ASSERT_PTR(TIMER(u));
int r;
r = unit_test_trigger_loaded(u);
if (r < 0)
return r;
r = unit_test_start_limit(u);
if (r < 0) {
timer_enter_dead(t, TIMER_FAILURE_START_LIMIT_HIT);

View File

@ -1178,28 +1178,6 @@ static bool shall_stop_on_isolate(Transaction *tr, Unit *u) {
if (hashmap_contains(tr->jobs, u))
return false;
/* Keep units that are triggered by units we want to keep around. */
Unit *other;
UNIT_FOREACH_DEPENDENCY(other, u, UNIT_ATOM_TRIGGERED_BY) {
if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
continue;
/* Is the trigger about to go down? */
Job *other_job = hashmap_get(tr->jobs, other);
bool has_stop = false;
LIST_FOREACH(transaction, j, other_job)
if (j->type == JOB_STOP) {
has_stop = true;
break;
}
if (has_stop)
continue;
if (other->ignore_on_isolate || other_job)
return false;
}
return true;
}
@ -1213,6 +1191,7 @@ int transaction_add_isolate_jobs(Transaction *tr, Manager *m) {
HASHMAP_FOREACH_KEY(u, k, m->units) {
_cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
Unit *o;
/* Ignore aliases. */
if (u->id != k)
@ -1225,6 +1204,16 @@ int transaction_add_isolate_jobs(Transaction *tr, Manager *m) {
if (!shall_stop_on_isolate(tr, u))
continue;
/* Keep units that are triggered by units we want to keep around. */
bool keep = false;
UNIT_FOREACH_DEPENDENCY(o, u, UNIT_ATOM_TRIGGERED_BY)
if (!shall_stop_on_isolate(tr, o)) {
keep = true;
break;
}
if (keep)
continue;
r = transaction_add_job_and_dependencies(tr, JOB_STOP, u, tr->anchor_job, TRANSACTION_MATTERS, &e);
if (r < 0)
log_unit_warning_errno(u, r, "Cannot add isolate job, ignoring: %s", bus_error_message(&e, r));

View File

@ -3927,7 +3927,8 @@ bool unit_active_or_pending(Unit *u) {
if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
return true;
if (u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART))
if (u->job &&
IN_SET(u->job->type, JOB_START, JOB_RELOAD_OR_START, JOB_RESTART))
return true;
return false;

View File

@ -368,11 +368,11 @@ static int run(int argc, char *argv[]) {
/* Child */
execvp(arguments[0], arguments);
log_open();
log_error_errno(errno, "Failed to execute '%s': %m", arguments[0]);
log_error_errno(errno, "Failed to execute %s: %m", argv[optind]);
_exit(EXIT_FAILURE);
}
return pidref_wait_for_terminate_and_check(argv[optind], &pidref, WAIT_LOG_ABNORMAL);
return pidref_wait_for_terminate_and_check(argv[optind], &pidref, WAIT_LOG);
}
}

View File

@ -295,7 +295,7 @@ int bus_image_method_get_hostname(
int r;
if (!image->metadata_valid) {
r = image_read_metadata(image, /* root= */ NULL, &image_policy_container, m->runtime_scope);
r = image_read_metadata(image, &image_policy_container, m->runtime_scope);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
}
@ -314,7 +314,7 @@ int bus_image_method_get_machine_id(
int r;
if (!image->metadata_valid) {
r = image_read_metadata(image, /* root= */ NULL, &image_policy_container, m->runtime_scope);
r = image_read_metadata(image, &image_policy_container, m->runtime_scope);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
}
@ -343,7 +343,7 @@ int bus_image_method_get_machine_info(
int r;
if (!image->metadata_valid) {
r = image_read_metadata(image, /* root= */ NULL, &image_policy_container, m->runtime_scope);
r = image_read_metadata(image, &image_policy_container, m->runtime_scope);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
}
@ -361,7 +361,7 @@ int bus_image_method_get_os_release(
int r;
if (!image->metadata_valid) {
r = image_read_metadata(image, /* root= */ NULL, &image_policy_container, m->runtime_scope);
r = image_read_metadata(image, &image_policy_container, m->runtime_scope);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
}

View File

@ -627,7 +627,7 @@ static int list_image_one_and_maybe_read_metadata(Manager *m, sd_varlink *link,
assert(image);
if (should_acquire_metadata(am) && !image->metadata_valid) {
r = image_read_metadata(image, /* root= */ NULL, &image_policy_container, m->runtime_scope);
r = image_read_metadata(image, &image_policy_container, m->runtime_scope);
if (r < 0 && am != ACQUIRE_METADATA_GRACEFUL)
return log_debug_errno(r, "Failed to read image metadata: %m");
if (r < 0)

View File

@ -540,7 +540,6 @@ static int vl_method_mount_image(
r = dissected_image_decrypt(
di,
/* root= */ NULL,
p.password,
&verity,
use_policy,

View File

@ -75,8 +75,6 @@ static const struct group root_group = {
static const struct sgrp root_sgrp = {
.sg_namp = (char*) "root",
.sg_passwd = (char*) PASSWORD_LOCKED_AND_INVALID,
.sg_adm = (char*[]) { NULL },
.sg_mem = (char*[]) { NULL },
};
static const struct group nobody_group = {
@ -89,8 +87,6 @@ static const struct group nobody_group = {
static const struct sgrp nobody_sgrp = {
.sg_namp = (char*) NOBODY_GROUP_NAME,
.sg_passwd = (char*) PASSWORD_LOCKED_AND_INVALID,
.sg_adm = (char*[]) { NULL },
.sg_mem = (char*[]) { NULL },
};
typedef struct GetentData {
@ -261,18 +257,12 @@ static enum nss_status copy_synthesized_sgrp(
assert(src);
assert(src->sg_namp);
assert(src->sg_passwd);
assert(src->sg_adm);
assert(!*src->sg_adm); /* Our synthesized records' sg_adm is always just NULL... */
assert(src->sg_mem);
assert(!*src->sg_mem); /* Our synthesized records' sg_mem is always just NULL... */
size_t required =
strlen(src->sg_namp) + 1 +
strlen(src->sg_passwd) + 1 +
sizeof(char*) + /* NULL terminator storage for src->sg_adm */
sizeof(char*); /* NULL terminator storage for src->sg_mem */
strlen(src->sg_passwd) + 1;
if (buflen < ALIGN(required)) {
if (buflen < required) {
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
@ -284,10 +274,7 @@ static enum nss_status copy_synthesized_sgrp(
/* String fields point into the user-provided buffer */
dest->sg_namp = buffer;
dest->sg_passwd = stpcpy(dest->sg_namp, src->sg_namp) + 1;
dest->sg_adm = ALIGN_PTR(stpcpy(dest->sg_passwd, src->sg_passwd) + 1);
*dest->sg_adm = NULL;
dest->sg_mem = dest->sg_adm + 1;
*dest->sg_mem = NULL;
strcpy(dest->sg_passwd, src->sg_passwd);
return NSS_STATUS_SUCCESS;
}

View File

@ -411,40 +411,6 @@ enum nss_status userdb_getgrgid(
return NSS_STATUS_SUCCESS;
}
/* Counts string pointers (including terminating NULL element) of given
* string vector strv and stores amount of pointers in n and total
* length of all contained strings including NUL bytes in len. */
static void nss_count_strv(char * const *strv, size_t *n, size_t *len) {
STRV_FOREACH(str, strv) {
(*len) += sizeof(char*); /* space for array entry */
(*len) += strlen(*str) + 1;
(*n)++;
}
(*len) += sizeof(char*); /* trailing NULL in array entry */
(*n)++;
}
/* Performs deep copy of given string vector src and stores content
* of contained strings into buf with references to these strings
* in dst. At dst location, a new NULL-terminated string vector is
* created. The dst and buf locations are updated to point just behind
* the last pointer or char respectively. Returns total amount of
* pointers in newly created string vector in dst, including the
* terminating NULL element. */
static size_t nss_deep_copy_strv(char * const *src, char ***dst, char **buf) {
char *p = *buf;
size_t i = 0;
STRV_FOREACH(str, src) {
(*dst)[i++] = p;
p = stpcpy(p, *str) + 1;
}
(*dst)[i++] = NULL;
*dst += i;
*buf = p;
return i;
}
int nss_pack_group_record_shadow(
GroupRecord *hr,
struct sgrp *sgrp,
@ -452,8 +418,7 @@ int nss_pack_group_record_shadow(
size_t buflen) {
const char *hashed;
char **array = NULL, *p;
size_t i = 0, n = 0, required;
size_t required;
assert(hr);
assert(sgrp);
@ -464,26 +429,15 @@ int nss_pack_group_record_shadow(
assert_se(hashed = strv_isempty(hr->hashed_password) ? PASSWORD_LOCKED_AND_INVALID : hr->hashed_password[0]);
required += strlen(hashed) + 1;
nss_count_strv(hr->administrators, &n, &required);
nss_count_strv(hr->members, &n, &required);
if (buflen < required)
return -ERANGE;
*sgrp = (struct sgrp) {
.sg_namp = buffer,
};
assert(buffer);
p = buffer + sizeof(void*) * (n + 1); /* place member strings right after the ptr array */
array = (char**) buffer; /* place ptr array at beginning of buffer, under assumption buffer is aligned */
sgrp->sg_mem = array;
i += nss_deep_copy_strv(hr->members, &array, &p);
sgrp->sg_adm = array;
i += nss_deep_copy_strv(hr->administrators, &array, &p);
assert_se(i == n);
sgrp->sg_namp = p;
sgrp->sg_passwd = stpcpy(sgrp->sg_namp, hr->group_name) + 1;
strcpy(sgrp->sg_passwd, hashed);

View File

@ -61,7 +61,7 @@ int bus_image_common_get_os_release(
return 1;
if (!image->metadata_valid) {
r = image_read_metadata(image, /* root= */ NULL, &image_policy_service, m->runtime_scope);
r = image_read_metadata(image, &image_policy_service, m->runtime_scope);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
}

View File

@ -2027,7 +2027,7 @@ int image_setup_pool(RuntimeScope scope, ImageClass class, bool use_btrfs_subvol
return 0;
}
int image_read_metadata(Image *i, const char *root, const ImagePolicy *image_policy, RuntimeScope scope) {
int image_read_metadata(Image *i, const ImagePolicy *image_policy, RuntimeScope scope) {
_cleanup_(release_lock_file) LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT;
int r;
@ -2153,7 +2153,6 @@ int image_read_metadata(Image *i, const char *root, const ImagePolicy *image_pol
r = dissected_image_decrypt(
m,
root,
/* passphrase= */ NULL,
&verity,
image_policy,

View File

@ -71,7 +71,7 @@ int image_get_pool_usage(RuntimeScope scope, ImageClass class, uint64_t *ret);
int image_get_pool_limit(RuntimeScope scope, ImageClass class, uint64_t *ret);
int image_setup_pool(RuntimeScope scope, ImageClass class, bool use_btrfs_subvol, bool use_btrfs_quota);
int image_read_metadata(Image *i, const char *root, const ImagePolicy *image_policy, RuntimeScope scope);
int image_read_metadata(Image *i, const ImagePolicy *image_policy, RuntimeScope scope);
bool image_in_search_path(RuntimeScope scope, ImageClass class, const char *root, const char *image);

View File

@ -3093,7 +3093,7 @@ static char* dm_deferred_remove_clean(char *name) {
}
DEFINE_TRIVIAL_CLEANUP_FUNC(char *, dm_deferred_remove_clean);
static int validate_signature_userspace(const VeritySettings *verity, const char *root, DissectImageFlags flags) {
static int validate_signature_userspace(const VeritySettings *verity, DissectImageFlags flags) {
int r;
/* Returns > 0 if signature checks out, == 0 if not, < 0 on unexpected errors */
@ -3138,7 +3138,7 @@ static int validate_signature_userspace(const VeritySettings *verity, const char
/* Because installing a signature certificate into the kernel chain is so messy, let's optionally do
* userspace validation. */
r = conf_files_list_nulstr(&certs, ".crt", root, CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED, CONF_PATHS_NULSTR("verity.d"));
r = conf_files_list_nulstr(&certs, ".crt", NULL, CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED, CONF_PATHS_NULSTR("verity.d"));
if (r < 0)
return log_debug_errno(r, "Failed to enumerate certificates: %m");
if (strv_isempty(certs)) {
@ -3200,7 +3200,6 @@ static int validate_signature_userspace(const VeritySettings *verity, const char
static int do_crypt_activate_verity(
struct crypt_device *cd,
const char *root,
const char *name,
const VeritySettings *verity,
DissectImageFlags flags,
@ -3250,7 +3249,7 @@ static int do_crypt_activate_verity(
/* Preferably propagate the original kernel error, so that the fallback logic can work,
* as the device-mapper is finicky around concurrent activations of the same volume */
k = validate_signature_userspace(verity, root, flags);
k = validate_signature_userspace(verity, flags);
if (k < 0)
return k;
if (k == 0) {
@ -3310,7 +3309,6 @@ static int verity_partition(
PartitionDesignator designator,
DissectedPartition *m, /* data partition */
DissectedPartition *v, /* verity partition */
const char *root, /* The root to get user verity certs from (for a sysext) */
const VeritySettings *verity,
DissectImageFlags flags,
PartitionPolicyFlags policy_flags,
@ -3396,7 +3394,7 @@ static int verity_partition(
goto check; /* The device already exists. Let's check it. */
/* The symlink to the device node does not exist yet. Assume not activated, and let's activate it. */
r = do_crypt_activate_verity(cd, root, name, verity, flags, policy_flags);
r = do_crypt_activate_verity(cd, name, verity, flags, policy_flags);
if (r >= 0)
goto try_open; /* The device is activated. Let's open it. */
/* libdevmapper can return EINVAL when the device is already in the activation stage.
@ -3490,7 +3488,7 @@ static int verity_partition(
*/
sym_crypt_free(cd);
cd = NULL;
return verity_partition(designator, m, v, root, verity, flags & ~DISSECT_IMAGE_VERITY_SHARE, policy_flags, d);
return verity_partition(designator, m, v, verity, flags & ~DISSECT_IMAGE_VERITY_SHARE, policy_flags, d);
}
return log_debug_errno(SYNTHETIC_ERRNO(EBUSY), "All attempts to activate verity device %s failed.", name);
@ -3510,7 +3508,6 @@ success:
int dissected_image_decrypt(
DissectedImage *m,
const char *root, /* The root to get user verity certs from (for a sysext) */
const char *passphrase,
const VeritySettings *verity,
const ImagePolicy *policy,
@ -3567,7 +3564,7 @@ int dissected_image_decrypt(
k = partition_verity_hash_of(i);
if (k >= 0) {
r = verity_partition(i, p, m->partitions + k, root, verity, flags, fl, d);
r = verity_partition(i, p, m->partitions + k, verity, flags, fl, d);
if (r < 0)
return r;
}
@ -3600,7 +3597,7 @@ int dissected_image_decrypt_interactively(
n--;
for (;;) {
r = dissected_image_decrypt(m, /* root= */ NULL, passphrase, verity, image_policy, flags);
r = dissected_image_decrypt(m, passphrase, verity, image_policy, flags);
if (r >= 0)
return r;
if (r == -EKEYREJECTED)
@ -4865,8 +4862,7 @@ int verity_dissect_and_mount(
r = dissected_image_decrypt(
dissected_image,
/* root= */ NULL,
/* passphrase= */ NULL,
NULL,
verity,
image_policy,
dissect_image_flags);

View File

@ -171,7 +171,7 @@ void dissected_image_close(DissectedImage *m);
DissectedImage* dissected_image_unref(DissectedImage *m);
DEFINE_TRIVIAL_CLEANUP_FUNC(DissectedImage*, dissected_image_unref);
int dissected_image_decrypt(DissectedImage *m, const char *root, const char *passphrase, const VeritySettings *verity, const ImagePolicy *image_policy, DissectImageFlags flags);
int dissected_image_decrypt(DissectedImage *m, const char *passphrase, const VeritySettings *verity, const ImagePolicy *image_policy, DissectImageFlags flags);
int dissected_image_decrypt_interactively(DissectedImage *m, const char *passphrase, const VeritySettings *verity, const ImagePolicy *image_policy, DissectImageFlags flags);
int dissected_image_mount(DissectedImage *m, const char *where, uid_t uid_shift, uid_t uid_range, int userns_fd, DissectImageFlags flags);
int dissected_image_mount_and_warn(DissectedImage *m, const char *where, uid_t uid_shift, uid_t uid_range, int userns_fd, DissectImageFlags flags);

View File

@ -1942,7 +1942,6 @@ int unit_file_verify_alias(
static int install_info_symlink_alias(
RuntimeScope scope,
UnitFileFlags file_flags,
InstallInfo *info,
const LookupPaths *lp,
const char *config_path,
@ -1997,10 +1996,6 @@ static int install_info_symlink_alias(
broken = r == 0; /* symlink target does not exist? */
r = create_symlink(lp, alias_target ?: info->path, alias_path, force || broken, changes, n_changes);
if (r == -EEXIST && FLAGS_SET(file_flags, UNIT_FILE_IGNORE_AUXILIARY_FAILURE))
/* We cannot realize the alias because a conflicting alias exists.
* Do not propagate this as error. */
continue;
if (r != 0 && ret >= 0)
ret = r;
}
@ -2165,7 +2160,7 @@ static int install_info_apply(
* because they might would pointing to a non-existent or wrong unit. */
return r;
r = install_info_symlink_alias(scope, file_flags, info, lp, config_path, force, changes, n_changes);
r = install_info_symlink_alias(scope, info, lp, config_path, force, changes, n_changes);
q = install_info_symlink_wants(scope, file_flags, info, lp, config_path, info->wanted_by, ".wants/", changes, n_changes);
if (q != 0 && r >= 0)

View File

@ -2,7 +2,6 @@
#pragma once
#include <grp.h>
#include <gshadow.h>
#include <netdb.h>
#include <nss.h>
#include <pwd.h>
@ -292,9 +291,3 @@ typedef enum nss_status (*_nss_getgrgid_r_t)(
struct group *gr,
char *buffer, size_t buflen,
int *errnop);
typedef enum nss_status (*_nss_getsgnam_r_t)(
const char *name,
struct sgrp *sg,
char *buffer, size_t buflen,
int *errnop);

View File

@ -35,6 +35,6 @@ int vsock_get_local_cid_or_warn(unsigned *ret) {
return 0;
}
if (r < 0)
return log_error_errno(r, "Failed to query host's AF_VSOCK CID: %m");
return log_error_errno(r, "Failed to query local AF_VSOCK CID: %m");
return 1;
}

View File

@ -1923,7 +1923,7 @@ static int merge_subprocess(
if (r < 0)
return r;
r = dissected_image_decrypt(m, arg_root, /* passphrase= */ NULL, &verity_settings, pick_image_policy(img), flags);
r = dissected_image_decrypt(m, /* passphrase= */ NULL, &verity_settings, pick_image_policy(img), flags);
if (r < 0)
return r;
@ -2199,7 +2199,7 @@ static int image_discover_and_read_metadata(ImageClass image_class, Hashmap **re
return log_error_errno(r, "Failed to discover images: %m");
HASHMAP_FOREACH(img, images) {
r = image_read_metadata(img, arg_root, image_class_info[image_class].default_image_policy, RUNTIME_SCOPE_SYSTEM);
r = image_read_metadata(img, image_class_info[image_class].default_image_policy, RUNTIME_SCOPE_SYSTEM);
if (r < 0)
return log_error_errno(r, "Failed to read metadata for image %s: %m", img->name);
}

View File

@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <gshadow.h>
#include <pwd.h>
#include <stdlib.h>
@ -36,22 +35,7 @@ static void print_struct_group(const struct group *gr) {
gr->gr_name, gr->gr_gid);
log_info(" passwd=\"%s\"", gr->gr_passwd);
assert_se(members = strv_join(ASSERT_PTR(gr->gr_mem), ", "));
// FIXME: use shell_maybe_quote(SHELL_ESCAPE_EMPTY) when it becomes available
log_info(" members=%s", members);
}
static void print_struct_sgrp(const struct sgrp *sg) {
_cleanup_free_ char *administrators = NULL, *members = NULL;
log_info(" \"%s\"", sg->sg_namp);
log_info(" passwd=\"%s\"", sg->sg_passwd);
assert_se(administrators = strv_join(ASSERT_PTR(sg->sg_adm), ", "));
// FIXME: use shell_maybe_quote(SHELL_ESCAPE_EMPTY) when it becomes available
log_info(" administrators=%s", administrators);
assert_se(members = strv_join(ASSERT_PTR(sg->sg_mem), ", "));
assert_se(members = strv_join(gr->gr_mem, ", "));
// FIXME: use shell_maybe_quote(SHELL_ESCAPE_EMPTY) when it becomes available
log_info(" members=%s", members);
}
@ -108,32 +92,6 @@ static void test_getgrnam_r(void *handle, const char *module, const char *name)
print_struct_group(&gr);
}
static void test_getsgnam_r(void *handle, const char *module, const char *name) {
const char *fname;
_nss_getsgnam_r_t f;
char buffer[arg_bufsize];
int errno1 = 999; /* nss-dns doesn't set those */
enum nss_status status;
char pretty_status[DECIMAL_STR_MAX(enum nss_status)];
struct sgrp sg;
fname = strjoina("_nss_", module, "_getsgnam_r");
f = dlsym(handle, fname);
log_debug("dlsym(0x%p, %s) → 0x%p", handle, fname, f);
if (!f) {
log_info("%s not defined", fname);
return;
}
status = f(name, &sg, buffer, sizeof buffer, &errno1);
log_info("%s(\"%s\") → status=%s%-20serrno=%d/%s",
fname, name,
nss_status_to_string(status, pretty_status, sizeof pretty_status), "\n",
errno1, errno1 > 0 ? ERRNO_NAME(errno1) : "---");
if (status == NSS_STATUS_SUCCESS)
print_struct_sgrp(&sg);
}
static void test_getpwuid_r(void *handle, const char *module, uid_t uid) {
const char *fname;
_nss_getpwuid_r_t f;
@ -189,7 +147,6 @@ static void test_getgrgid_r(void *handle, const char *module, gid_t gid) {
static void test_byname(void *handle, const char *module, const char *name) {
test_getpwnam_r(handle, module, name);
test_getgrnam_r(handle, module, name);
test_getsgnam_r(handle, module, name);
puts("");
}

View File

@ -181,52 +181,6 @@ prepare_extension_image_raw() {
prepend_trap "rm -rf ${ext_dir@Q}.raw"
}
prepare_extension_image_raw_verity() {
local root=${1:-}
local hierarchy=${2:?}
local ext_dir ext_release name tmpcrt
name="test-extension"
ext_dir="$root/var/lib/extensions/$name"
ext_release="$ext_dir/usr/lib/extension-release.d/extension-release.$name"
tmpcrt=$(mktemp --directory "/tmp/test-sysext.crt.XXXXXXXXXX")
prepend_trap "rm -rf ${ext_dir@Q} ${ext_dir@Q}.raw '$root/etc/verity.d/test-ext.crt' '$tmpcrt'"
mkdir -p "${ext_release%/*}"
echo "ID=_any" >"$ext_release"
mkdir -p "$ext_dir/$hierarchy"
touch "$ext_dir$hierarchy/preexisting-file-in-extension-image"
tee >"$tmpcrt/verity.openssl.cnf" <<EOF
[ req ]
prompt = no
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
C = DE
ST = Test State
L = Test Locality
O = Org Name
OU = Org Unit Name
CN = Common Name
emailAddress = test@email.com
EOF
openssl req \
-config "$tmpcrt/verity.openssl.cnf" \
-new -x509 \
-newkey rsa:1024 \
-keyout "$tmpcrt/test-ext.key" \
-out "$tmpcrt/test-ext.crt" \
-days 365 \
-nodes
systemd-repart --make-ddi=sysext \
--private-key="$tmpcrt/test-ext.key" --certificate="$tmpcrt/test-ext.crt" \
--copy-source="$ext_dir" "$ext_dir.raw"
rm -rf "$ext_dir"
mkdir -p "$root/etc/verity.d"
mv "$tmpcrt/test-ext.crt" "$root/etc/verity.d/"
rm -rf "$tmpcrt"
}
prepare_extension_mutable_dir() {
local dir=${1:?}
@ -1285,28 +1239,6 @@ extension_verify_after_merge "$fake_root" "$hierarchy" -e -h
run_systemd_sysext "$fake_root" unmerge
)
( init_trap
: "Check if verity user certs get loaded from --root="
fake_root=${roots_dir:+"$roots_dir/verity-user-cert-from-root"}
hierarchy=/opt
# On OpenSUSE Tumbleweed EROFS is not supported
if [ -e /usr/lib/modprobe.d/60-blacklist_fs-erofs.conf ]; then
echo >&2 "Skipping test due to missing erofs support"
exit 0
fi
prepare_root "$fake_root" "$hierarchy"
prepare_extension_image_raw_verity "$fake_root" "$hierarchy"
prepare_read_only_hierarchy "$fake_root" "$hierarchy"
run_systemd_sysext "$fake_root" merge --image-policy=root=signed+absent:usr=signed+absent
extension_verify_after_merge "$fake_root" "$hierarchy" -e -h
run_systemd_sysext "$fake_root" unmerge
extension_verify_after_unmerge "$fake_root" "$hierarchy" -h
)
} # End of run_sysext_tests