1
0
mirror of https://github.com/systemd/systemd synced 2025-11-21 09:44:44 +01:00

Compare commits

..

4 Commits

Author SHA1 Message Date
Christian Hesse
468cc02045 measure: silence warning on TCG protocol
This pops up for some people, and adds a delay on boot.

The proper fix is in #38701, but technically it is a new feature. So
let's just silence the message in v258-stable.
2025-10-12 20:52:10 +02:00
Aleksandr Mezin
d4e5aa0397 nspawn: don't try to connect to D-Bus when it's not necessary (#39045)
`runtime_bus` is only used if `!arg_keep_unit`.

`system_bus` is additionally used if `arg_register`.

So for `!arg_register && arg_keep_unit`, none of them should be
necessary, and nspawn should be able to work without any D-Bus
connections.

Fixes https://github.com/systemd/systemd/issues/39044

Follow-up for f2f26f1527529b1ea7dcb0dba85456ac98800627

(cherry picked from commit c3d5f5f165ce7ccf8d57c4272c39d83a08279db7)
2025-10-12 20:52:10 +02:00
Yu Watanabe
d0f5c2f2c7 login: update ACL on static device nodes again
In the commit c960ca2be1cfd183675df581f049a0c022c1c802, the logic of
updating ACL on device node was moved from logind to udevd, but at that
time, mistakenly removed the logic for static nodes.

Fixes a regression caused by c960ca2be1cfd183675df581f049a0c022c1c802 (v258).
Fixes #39043.

(cherry picked from commit 2c762d90cfe7d67f10af87986ed2e6f0005eabfb)
2025-10-12 20:52:10 +02:00
Yu Watanabe
1415e3a647 udev: move devnode_acl() back to libshared
This effectively reverts 1abb592f2f886913492e4967cc96816c167177a9.
No functional change, preparation for the next commit.

(cherry picked from commit 41c4a69653f7ca48a449de172e73acd43eda81a4)
2025-10-12 20:52:10 +02:00
7 changed files with 207 additions and 114 deletions

View File

@ -198,7 +198,7 @@ uint32_t tpm_get_active_pcr_banks(void) {
/* GetActivePcrBanks() was added only in version 1.1 of the spec */ /* GetActivePcrBanks() was added only in version 1.1 of the spec */
if (version.Major < 1 || (version.Major == 1 && version.Minor < 1)) { if (version.Major < 1 || (version.Major == 1 && version.Minor < 1)) {
log_debug("TCG protocol too old for GetActivePcrBanks(), claiming no active banks."); /* log_debug("TCG protocol too old for GetActivePcrBanks(), claiming no active banks."); */
return 0; return 0;
} }

View File

@ -6,8 +6,10 @@
#include "sd-messages.h" #include "sd-messages.h"
#include "acl-util.h"
#include "alloc-util.h" #include "alloc-util.h"
#include "device-util.h" #include "device-util.h"
#include "dirent-util.h"
#include "errno-util.h" #include "errno-util.h"
#include "fd-util.h" #include "fd-util.h"
#include "format-util.h" #include "format-util.h"
@ -26,6 +28,7 @@
#include "mkdir-label.h" #include "mkdir-label.h"
#include "path-util.h" #include "path-util.h"
#include "set.h" #include "set.h"
#include "stat-util.h"
#include "stdio-util.h" #include "stdio-util.h"
#include "string-util.h" #include "string-util.h"
#include "terminal-util.h" #include "terminal-util.h"
@ -321,12 +324,88 @@ static int seat_trigger_devices(Seat *s) {
return r; return r;
} }
seat_triggered_uevents_done(s);
return 0; return 0;
} }
static int static_node_acl(Seat *s) {
#if HAVE_ACL
int r, ret = 0;
uid_t uid;
assert(s);
if (s->active)
uid = s->active->user->user_record->uid;
else
uid = 0;
_cleanup_closedir_ DIR *dir = opendir("/run/udev/static_node-tags/uaccess/");
if (!dir) {
if (errno == ENOENT)
return 0;
return log_debug_errno(errno, "Failed to open /run/udev/static_node-tags/uaccess/: %m");
}
FOREACH_DIRENT(de, dir, return -errno) {
_cleanup_close_ int fd = RET_NERRNO(openat(dirfd(dir), de->d_name, O_CLOEXEC|O_PATH));
if (ERRNO_IS_NEG_DEVICE_ABSENT_OR_EMPTY(fd))
continue;
if (fd < 0) {
RET_GATHER(ret, log_debug_errno(fd, "Failed to open '/run/udev/static_node-tags/uaccess/%s': %m", de->d_name));
continue;
}
struct stat st;
if (fstat(fd, &st) < 0) {
RET_GATHER(ret, log_debug_errno(errno, "Failed to stat '/run/udev/static_node-tags/uaccess/%s': %m", de->d_name));
continue;
}
r = stat_verify_device_node(&st);
if (r < 0) {
RET_GATHER(ret, log_debug_errno(fd, "'/run/udev/static_node-tags/uaccess/%s' points to a non-device node: %m", de->d_name));
continue;
}
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
r = sd_device_new_from_stat_rdev(&dev, &st);
if (r >= 0) {
log_device_debug(dev, "'/run/udev/static_node-tags/uaccess/%s' points to a non-static device node, ignoring.", de->d_name);
continue;
}
if (!ERRNO_IS_NEG_DEVICE_ABSENT_OR_EMPTY(r))
log_debug_errno(r, "Failed to check if '/run/udev/static_node-tags/uaccess/%s' points to a static device node, ignoring: %m", de->d_name);
r = devnode_acl(fd, uid);
if (r >= 0 || r == -ENOENT)
continue;
/* de->d_name is escaped, like "snd\x2ftimer", hence let's use the path to node, if possible. */
_cleanup_free_ char *node = NULL;
(void) fd_get_path(fd, &node);
if (uid != 0) {
RET_GATHER(ret, log_debug_errno(r, "Failed to apply ACL on '%s': %m", node ?: de->d_name));
/* Better be safe than sorry and reset ACL */
r = devnode_acl(fd, /* uid = */ 0);
if (r >= 0 || r == -ENOENT)
continue;
}
if (r < 0)
RET_GATHER(ret, log_debug_errno(r, "Failed to flush ACL on '%s': %m", node ?: de->d_name));
}
return ret;
#else
return 0;
#endif
}
int seat_set_active(Seat *s, Session *session) { int seat_set_active(Seat *s, Session *session) {
Session *old_active; Session *old_active;
int r;
assert(s); assert(s);
assert(!session || session->seat == s); assert(!session || session->seat == s);
@ -358,7 +437,16 @@ int seat_set_active(Seat *s, Session *session) {
session_send_changed(old_active, "Active"); session_send_changed(old_active, "Active");
} }
return seat_trigger_devices(s); r = seat_trigger_devices(s);
if (r < 0)
return r;
r = static_node_acl(s);
if (r < 0)
return r;
seat_triggered_uevents_done(s);
return 0;
} }
static Session* seat_get_position(Seat *s, unsigned pos) { static Session* seat_get_position(Seat *s, unsigned pos) {

View File

@ -49,6 +49,7 @@ executables += [
'include_directories' : [libexec_template['include_directories'], include_directories('.')], 'include_directories' : [libexec_template['include_directories'], include_directories('.')],
'extract' : systemd_logind_extract_sources, 'extract' : systemd_logind_extract_sources,
'dependencies' : [ 'dependencies' : [
libacl,
threads, threads,
], ],
}, },

View File

@ -5383,7 +5383,7 @@ static int run_container(
/* Registration always happens on the system bus */ /* Registration always happens on the system bus */
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *system_bus = NULL; _cleanup_(sd_bus_flush_close_unrefp) sd_bus *system_bus = NULL;
if (arg_register || arg_privileged) { if (arg_register || (arg_privileged && !arg_keep_unit)) {
r = sd_bus_default_system(&system_bus); r = sd_bus_default_system(&system_bus);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to open system bus: %m"); return log_error_errno(r, "Failed to open system bus: %m");
@ -5398,21 +5398,21 @@ static int run_container(
/* Scope allocation happens on the user bus if we are unpriv, otherwise system bus. */ /* Scope allocation happens on the user bus if we are unpriv, otherwise system bus. */
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *user_bus = NULL; _cleanup_(sd_bus_flush_close_unrefp) sd_bus *user_bus = NULL;
_cleanup_(sd_bus_unrefp) sd_bus *runtime_bus = NULL; _cleanup_(sd_bus_unrefp) sd_bus *runtime_bus = NULL;
if (arg_privileged)
runtime_bus = sd_bus_ref(system_bus);
else {
r = sd_bus_default_user(&user_bus);
if (r < 0)
return log_error_errno(r, "Failed to open user bus: %m");
r = sd_bus_set_close_on_exit(user_bus, false);
if (r < 0)
return log_error_errno(r, "Failed to disable close-on-exit behaviour: %m");
runtime_bus = sd_bus_ref(user_bus);
}
if (!arg_keep_unit) { if (!arg_keep_unit) {
if (arg_privileged)
runtime_bus = sd_bus_ref(system_bus);
else {
r = sd_bus_default_user(&user_bus);
if (r < 0)
return log_error_errno(r, "Failed to open user bus: %m");
r = sd_bus_set_close_on_exit(user_bus, false);
if (r < 0)
return log_error_errno(r, "Failed to disable close-on-exit behaviour: %m");
runtime_bus = sd_bus_ref(user_bus);
}
/* When a new scope is created for this container, then we'll be registered as its controller, in which /* When a new scope is created for this container, then we'll be registered as its controller, in which
* case PID 1 will send us a friendly RequestStop signal, when it is asked to terminate the * case PID 1 will send us a friendly RequestStop signal, when it is asked to terminate the
* scope. Let's hook into that, and cleanly shut down the container, and print a friendly message. */ * scope. Let's hook into that, and cleanly shut down the container, and print a friendly message. */

View File

@ -6,12 +6,106 @@
#include "alloc-util.h" #include "alloc-util.h"
#include "errno-util.h" #include "errno-util.h"
#include "extract-word.h" #include "extract-word.h"
#include "fd-util.h"
#include "string-util.h" #include "string-util.h"
#include "strv.h" #include "strv.h"
#include "user-util.h" #include "user-util.h"
#if HAVE_ACL #if HAVE_ACL
int devnode_acl(int fd, uid_t uid) {
bool changed = false, found = false;
int r;
assert(fd >= 0);
_cleanup_(acl_freep) acl_t acl = NULL;
acl = acl_get_file(FORMAT_PROC_FD_PATH(fd), ACL_TYPE_ACCESS);
if (!acl)
return -errno;
acl_entry_t entry;
for (r = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
r > 0;
r = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry)) {
acl_tag_t tag;
if (acl_get_tag_type(entry, &tag) < 0)
return -errno;
if (tag != ACL_USER)
continue;
if (uid > 0) {
uid_t *u = acl_get_qualifier(entry);
if (!u)
return -errno;
if (*u == uid) {
acl_permset_t permset;
if (acl_get_permset(entry, &permset) < 0)
return -errno;
int rd = acl_get_perm(permset, ACL_READ);
if (rd < 0)
return -errno;
int wt = acl_get_perm(permset, ACL_WRITE);
if (wt < 0)
return -errno;
if (!rd || !wt) {
if (acl_add_perm(permset, ACL_READ|ACL_WRITE) < 0)
return -errno;
changed = true;
}
found = true;
continue;
}
}
if (acl_delete_entry(acl, entry) < 0)
return -errno;
changed = true;
}
if (r < 0)
return -errno;
if (!found && uid > 0) {
if (acl_create_entry(&acl, &entry) < 0)
return -errno;
if (acl_set_tag_type(entry, ACL_USER) < 0)
return -errno;
if (acl_set_qualifier(entry, &uid) < 0)
return -errno;
acl_permset_t permset;
if (acl_get_permset(entry, &permset) < 0)
return -errno;
if (acl_add_perm(permset, ACL_READ|ACL_WRITE) < 0)
return -errno;
changed = true;
}
if (!changed)
return 0;
if (acl_calc_mask(&acl) < 0)
return -errno;
if (acl_set_file(FORMAT_PROC_FD_PATH(fd), ACL_TYPE_ACCESS, acl) < 0)
return -errno;
return 0;
}
static int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *ret_entry) { static int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *ret_entry) {
acl_entry_t i; acl_entry_t i;
int r; int r;

View File

@ -10,6 +10,8 @@ int fd_acl_make_writable_fallback(int fd);
#include <acl/libacl.h> /* IWYU pragma: export */ #include <acl/libacl.h> /* IWYU pragma: export */
#include <sys/acl.h> /* IWYU pragma: export */ #include <sys/acl.h> /* IWYU pragma: export */
int devnode_acl(int fd, uid_t uid);
int calc_acl_mask_if_needed(acl_t *acl_p); int calc_acl_mask_if_needed(acl_t *acl_p);
int add_base_acls_if_needed(acl_t *acl_p, const char *path); int add_base_acls_if_needed(acl_t *acl_p, const char *path);
int acl_search_groups(const char* path, char ***ret_groups); int acl_search_groups(const char* path, char ***ret_groups);
@ -40,6 +42,10 @@ DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(gid_t*, acl_free_gid_tp, NULL);
#define ACL_WRITE 0x02 #define ACL_WRITE 0x02
#define ACL_EXECUTE 0x01 #define ACL_EXECUTE 0x01
static inline int devnode_acl(int fd, uid_t uid) {
return -EOPNOTSUPP;
}
static inline int fd_add_uid_acl_permission(int fd, uid_t uid, unsigned mask) { static inline int fd_add_uid_acl_permission(int fd, uid_t uid, unsigned mask) {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }

View File

@ -1,7 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */ /* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* manage device node user ACL
*/
#include "sd-login.h" #include "sd-login.h"
@ -12,99 +9,6 @@
#include "login-util.h" #include "login-util.h"
#include "udev-builtin.h" #include "udev-builtin.h"
static int devnode_acl(int fd, uid_t uid) {
bool changed = false, found = false;
int r;
assert(fd >= 0);
_cleanup_(acl_freep) acl_t acl = NULL;
acl = acl_get_file(FORMAT_PROC_FD_PATH(fd), ACL_TYPE_ACCESS);
if (!acl)
return -errno;
acl_entry_t entry;
for (r = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
r > 0;
r = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry)) {
acl_tag_t tag;
if (acl_get_tag_type(entry, &tag) < 0)
return -errno;
if (tag != ACL_USER)
continue;
if (uid > 0) {
uid_t *u = acl_get_qualifier(entry);
if (!u)
return -errno;
if (*u == uid) {
acl_permset_t permset;
if (acl_get_permset(entry, &permset) < 0)
return -errno;
int rd = acl_get_perm(permset, ACL_READ);
if (rd < 0)
return -errno;
int wt = acl_get_perm(permset, ACL_WRITE);
if (wt < 0)
return -errno;
if (!rd || !wt) {
if (acl_add_perm(permset, ACL_READ|ACL_WRITE) < 0)
return -errno;
changed = true;
}
found = true;
continue;
}
}
if (acl_delete_entry(acl, entry) < 0)
return -errno;
changed = true;
}
if (r < 0)
return -errno;
if (!found && uid > 0) {
if (acl_create_entry(&acl, &entry) < 0)
return -errno;
if (acl_set_tag_type(entry, ACL_USER) < 0)
return -errno;
if (acl_set_qualifier(entry, &uid) < 0)
return -errno;
acl_permset_t permset;
if (acl_get_permset(entry, &permset) < 0)
return -errno;
if (acl_add_perm(permset, ACL_READ|ACL_WRITE) < 0)
return -errno;
changed = true;
}
if (!changed)
return 0;
if (acl_calc_mask(&acl) < 0)
return -errno;
if (acl_set_file(FORMAT_PROC_FD_PATH(fd), ACL_TYPE_ACCESS, acl) < 0)
return -errno;
return 0;
}
static int builtin_uaccess(UdevEvent *event, int argc, char *argv[]) { static int builtin_uaccess(UdevEvent *event, int argc, char *argv[]) {
sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
int r, k; int r, k;