1
0
mirror of https://github.com/systemd/systemd synced 2026-03-15 17:44:49 +01:00

Compare commits

..

7 Commits

Author SHA1 Message Date
Mike Yuan
a8b099d663
sd-event: unpoison memory returned by epoll_pwait2() (#40464)
Fixes #40455

Alternative to #40463
Closes #40463
2026-01-25 00:50:18 +01:00
Lennart Poettering
3775fab341 CODING_STYLE: suggest a clear order for func params that combine fd and path 2026-01-24 20:52:00 +01:00
Lennart Poettering
ca088266bc loop-util: when open_flags is unspecified derive it from passed in fd 2026-01-24 20:51:45 +01:00
Mike Yuan
cc94dca5bc
sd-event: use FOREACH_ARRAY 2026-01-24 18:51:21 +01:00
Mike Yuan
21ebcb5814
sd-event: unpoison memory returned by epoll_pwait2()
Our fuzzer CI recently got bumped to Ubuntu 24.04 with
glibc >= 2.35. Apparently msan is not happy with the new
epoll_pwait2(), hence explicitly mark the memory region
as initialized.

Fixes #40455
Alternative to #40463
2026-01-24 18:36:24 +01:00
Mike Yuan
1b2ad38b2b
README: add epoll_pwait2() to the list of kernel APIs 2026-01-24 18:28:24 +01:00
Mike Yuan
5ad66a9b72
units/meson.build: rebreak lines 2026-01-24 18:07:15 +01:00
5 changed files with 43 additions and 26 deletions

3
README
View File

@ -58,7 +58,8 @@ REQUIREMENTS:
⛔ Kernel versions below 5.10 ("minimum baseline") are not supported at all, ⛔ Kernel versions below 5.10 ("minimum baseline") are not supported at all,
and are missing required functionality as listed above. and are missing required functionality as listed above.
Linux kernel ≥ 5.12 for idmapped mount Linux kernel ≥ 5.11 for epoll_pwait2()
≥ 5.12 for idmapped mount (mount_setattr())
≥ 5.14 for cgroup.kill and quotactl_fd() ≥ 5.14 for cgroup.kill and quotactl_fd()
⚠️ Kernel versions below 5.14 ("recommended baseline") have significant gaps ⚠️ Kernel versions below 5.14 ("recommended baseline") have significant gaps

View File

@ -437,6 +437,16 @@ SPDX-License-Identifier: LGPL-2.1-or-later
aren't, we are happy to use GNU or Linux APIs, and expect non-GNU aren't, we are happy to use GNU or Linux APIs, and expect non-GNU
implementations of libc to catch up with glibc. implementations of libc to catch up with glibc.
- Very often we pass a pair of file descriptor and a path to functions, which
are to be understood in combination. For example `openat()` style functions
typically take a directory fd and a filename relative to that as argument. In
other cases where operations operate relative to a root directory it makes
sense to have a pair of root path and root fd. Whenever possible the function
arguments should be in the order "fd first, path second" when the path shall
be understood relative to the fd. And an order "path first, fd second"
shall be used when the root path is the path of the referenced fd, i.e. two
references to the same object.
## Using C Constructs ## Using C Constructs
- Allocate local variables where it makes sense: at the top of the block, or at - Allocate local variables where it makes sense: at the top of the block, or at

View File

@ -4618,6 +4618,7 @@ static int process_epoll(sd_event *e, usec_t timeout, int64_t threshold, int64_t
return r; return r;
m = (size_t) r; m = (size_t) r;
msan_unpoison(e->event_queue, m * sizeof(struct epoll_event));
if (m < n_event_max) if (m < n_event_max)
break; break;
@ -4636,19 +4637,17 @@ static int process_epoll(sd_event *e, usec_t timeout, int64_t threshold, int64_t
if (threshold == INT64_MAX) if (threshold == INT64_MAX)
triple_timestamp_now(&e->timestamp); triple_timestamp_now(&e->timestamp);
for (size_t i = 0; i < m; i++) { FOREACH_ARRAY(i, e->event_queue, m) {
if (e->event_queue[i].data.ptr == INT_TO_PTR(SOURCE_WATCHDOG)) if (i->data.ptr == INT_TO_PTR(SOURCE_WATCHDOG))
r = flush_timer(e, e->watchdog_fd, e->event_queue[i].events, NULL); r = flush_timer(e, e->watchdog_fd, i->events, NULL);
else { else {
WakeupType *t = e->event_queue[i].data.ptr; WakeupType *t = ASSERT_PTR(i->data.ptr);
switch (*t) { switch (*t) {
case WAKEUP_EVENT_SOURCE: { case WAKEUP_EVENT_SOURCE: {
sd_event_source *s = e->event_queue[i].data.ptr; sd_event_source *s = i->data.ptr;
assert(s);
if (s->priority > threshold) if (s->priority > threshold)
continue; continue;
@ -4658,15 +4657,15 @@ static int process_epoll(sd_event *e, usec_t timeout, int64_t threshold, int64_t
switch (s->type) { switch (s->type) {
case SOURCE_IO: case SOURCE_IO:
r = process_io(e, s, e->event_queue[i].events); r = process_io(e, s, i->events);
break; break;
case SOURCE_CHILD: case SOURCE_CHILD:
r = process_pidfd(e, s, e->event_queue[i].events); r = process_pidfd(e, s, i->events);
break; break;
case SOURCE_MEMORY_PRESSURE: case SOURCE_MEMORY_PRESSURE:
r = process_memory_pressure(s, e->event_queue[i].events); r = process_memory_pressure(s, i->events);
break; break;
default: default:
@ -4677,20 +4676,18 @@ static int process_epoll(sd_event *e, usec_t timeout, int64_t threshold, int64_t
} }
case WAKEUP_CLOCK_DATA: { case WAKEUP_CLOCK_DATA: {
struct clock_data *d = e->event_queue[i].data.ptr; struct clock_data *d = i->data.ptr;
assert(d); r = flush_timer(e, d->fd, i->events, &d->next);
r = flush_timer(e, d->fd, e->event_queue[i].events, &d->next);
break; break;
} }
case WAKEUP_SIGNAL_DATA: case WAKEUP_SIGNAL_DATA:
r = process_signal(e, e->event_queue[i].data.ptr, e->event_queue[i].events, &min_priority); r = process_signal(e, i->data.ptr, i->events, &min_priority);
break; break;
case WAKEUP_INOTIFY_DATA: case WAKEUP_INOTIFY_DATA:
r = event_inotify_data_read(e, e->event_queue[i].data.ptr, e->event_queue[i].events, threshold); r = event_inotify_data_read(e, i->data.ptr, i->events, threshold);
break; break;
default: default:

View File

@ -431,10 +431,25 @@ static int loop_device_make_internal(
int r, f_flags; int r, f_flags;
struct stat st; struct stat st;
assert(fd >= 0);
assert(open_flags < 0 || IN_SET(open_flags, O_RDWR, O_RDONLY));
assert(ret); assert(ret);
assert(IN_SET(open_flags, O_RDWR, O_RDONLY));
if (fstat(ASSERT_FD(fd), &st) < 0) f_flags = fcntl(fd, F_GETFL);
if (f_flags < 0)
return -errno;
if (open_flags < 0) {
/* If open_flags is unset, initialize it from the open fd */
if (FLAGS_SET(f_flags, O_PATH))
return log_debug_errno(SYNTHETIC_ERRNO(EBADFD), "Access mode of image file indicates O_PATH, cannot determine read/write flags.");
open_flags = f_flags & O_ACCMODE_STRICT;
if (!IN_SET(open_flags, O_RDWR, O_RDONLY))
return log_debug_errno(SYNTHETIC_ERRNO(EBADFD), "Access mode of image file is write only (?)");
}
if (fstat(fd, &st) < 0)
return -errno; return -errno;
if (S_ISBLK(st.st_mode)) { if (S_ISBLK(st.st_mode)) {
@ -461,10 +476,6 @@ static int loop_device_make_internal(
return r; return r;
} }
f_flags = fcntl(fd, F_GETFL);
if (f_flags < 0)
return -errno;
if (FLAGS_SET(loop_flags, LO_FLAGS_DIRECT_IO) != FLAGS_SET(f_flags, O_DIRECT)) { if (FLAGS_SET(loop_flags, LO_FLAGS_DIRECT_IO) != FLAGS_SET(f_flags, O_DIRECT)) {
/* If LO_FLAGS_DIRECT_IO is requested, then make sure we have the fd open with O_DIRECT, as /* If LO_FLAGS_DIRECT_IO is requested, then make sure we have the fd open with O_DIRECT, as
* that's required. Conversely, if it's off require that O_DIRECT is off too (that's because * that's required. Conversely, if it's off require that O_DIRECT is off too (that's because

View File

@ -43,9 +43,7 @@ units = [
'file' : 'getty.target', 'file' : 'getty.target',
'symlinks' : ['multi-user.target.wants/'], 'symlinks' : ['multi-user.target.wants/'],
}, },
{ { 'file' : 'getty@.service.in' },
'file' : 'getty@.service.in',
},
{ {
'file' : 'graphical.target', 'file' : 'graphical.target',
'symlinks' : ['default.target'], 'symlinks' : ['default.target'],