Compare commits

..

No commits in common. "97033ba455c4c1e359835879eee2e3c690395792" and "45204921be610be839482a037985fd5a5052f2dd" have entirely different histories.

37 changed files with 143 additions and 338 deletions

View File

@ -7,8 +7,7 @@ about: A report of an error in a recent systemd version
**systemd version the issue has been seen with** **systemd version the issue has been seen with**
> ... > ...
<!-- **NOTE:** Do not submit bug reports about anything but the two most recently released (non-rc) systemd versions upstream! --> <!-- **NOTE:** Do not submit bug reports about anything but the two most recently released systemd versions upstream! -->
<!-- See https://github.com/systemd/systemd/releases for the list of most recent releases. -->
<!-- For older version please use distribution trackers (see https://systemd.io/CONTRIBUTING#filing-issues). --> <!-- For older version please use distribution trackers (see https://systemd.io/CONTRIBUTING#filing-issues). -->
**Used distribution** **Used distribution**

View File

@ -11,9 +11,6 @@ env:
- REPO_ROOT="$TRAVIS_BUILD_DIR" - REPO_ROOT="$TRAVIS_BUILD_DIR"
stages: stages:
- name: Build check
if: type != cron
- name: Build & test - name: Build & test
if: type != cron if: type != cron
@ -23,45 +20,6 @@ stages:
jobs: jobs:
include: include:
- stage: Build check
name: Fedora Rawhide (gcc)
language: bash
env:
- FEDORA_RELEASE="rawhide"
- CONT_NAME="systemd-fedora-$FEDORA_RELEASE"
- DOCKER_EXEC="docker exec -ti $CONT_NAME"
before_install:
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
- docker --version
install:
- $CI_MANAGERS/fedora.sh SETUP
script:
- set -e
# Build systemd
- $CI_MANAGERS/fedora.sh RUN_BUILD_CHECK_GCC
- set +e
after_script:
- $CI_MANAGERS/fedora.sh CLEANUP
- name: Fedora Rawhide (clang)
language: bash
env:
- FEDORA_RELEASE="rawhide"
- CONT_NAME="systemd-fedora-$FEDORA_RELEASE"
- DOCKER_EXEC="docker exec -ti $CONT_NAME"
before_install:
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
- docker --version
install:
- $CI_MANAGERS/fedora.sh SETUP
script:
- set -e
# Build systemd
- $CI_MANAGERS/fedora.sh RUN_BUILD_CHECK_CLANG
- set +e
after_script:
- $CI_MANAGERS/fedora.sh CLEANUP
- stage: Build & test - stage: Build & test
name: Debian Testing name: Debian Testing
language: bash language: bash

View File

@ -11,7 +11,7 @@ We welcome contributions from everyone. However, please follow the following gui
## Filing Issues ## Filing Issues
* We use [GitHub Issues](https://github.com/systemd/systemd/issues) **exclusively** for tracking **bugs** and **feature** **requests** of systemd. If you are looking for help, please contact [systemd-devel mailing list](https://lists.freedesktop.org/mailman/listinfo/systemd-devel) instead. * We use [GitHub Issues](https://github.com/systemd/systemd/issues) **exclusively** for tracking **bugs** and **feature** **requests** of systemd. If you are looking for help, please contact [systemd-devel mailing list](https://lists.freedesktop.org/mailman/listinfo/systemd-devel) instead.
* We only track bugs in the **two** **most** **recently** **released** (non-rc) **versions** of systemd in the GitHub Issue tracker. If you are using an older version of systemd, please contact your distribution's bug tracker instead (see below). See [GitHub Release Page](https://github.com/systemd/systemd/releases) for the list of most recent releases. * We only track bugs in the **two** **most** **recently** **released** **versions** of systemd in the GitHub Issue tracker. If you are using an older version of systemd, please contact your distribution's bug tracker instead.
* When filing an issue, specify the **systemd** **version** you are experiencing the issue with. Also, indicate which **distribution** you are using. * When filing an issue, specify the **systemd** **version** you are experiencing the issue with. Also, indicate which **distribution** you are using.
* Please include an explanation how to reproduce the issue you are pointing out. * Please include an explanation how to reproduce the issue you are pointing out.

View File

@ -33,12 +33,9 @@ int flush_fd(int fd) {
continue; continue;
return -errno; return -errno;
}
if (r == 0)
return count;
if (pollfd.revents & POLLNVAL) } else if (r == 0)
return -EBADF; return count;
l = read(fd, buf, sizeof(buf)); l = read(fd, buf, sizeof(buf));
if (l < 0) { if (l < 0) {
@ -172,9 +169,6 @@ int pipe_eof(int fd) {
if (r == 0) if (r == 0)
return 0; return 0;
if (pollfd.revents & POLLNVAL)
return -EBADF;
return pollfd.revents & POLLHUP; return pollfd.revents & POLLHUP;
} }
@ -194,9 +188,6 @@ int fd_wait_for_event(int fd, int event, usec_t t) {
if (r == 0) if (r == 0)
return 0; return 0;
if (pollfd.revents & POLLNVAL)
return -EBADF;
return pollfd.revents; return pollfd.revents;
} }

View File

@ -14,18 +14,11 @@
#include "stdio-util.h" #include "stdio-util.h"
#include "user-util.h" #include "user-util.h"
int mkdir_safe_internal( int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdir_func_t _mkdir) {
const char *path,
mode_t mode,
uid_t uid, gid_t gid,
MkdirFlags flags,
mkdir_func_t _mkdir) {
struct stat st; struct stat st;
int r; int r;
assert(path); assert(_mkdir != mkdir);
assert(_mkdir && _mkdir != mkdir);
if (_mkdir(path, mode) >= 0) { if (_mkdir(path, mode) >= 0) {
r = chmod_and_chown(path, mode, uid, gid); r = chmod_and_chown(path, mode, uid, gid);
@ -51,16 +44,19 @@ int mkdir_safe_internal(
return -errno; return -errno;
} }
if (!S_ISDIR(st.st_mode)) if (!S_ISDIR(st.st_mode)) {
return log_full_errno(flags & MKDIR_WARN_MODE ? LOG_WARNING : LOG_DEBUG, SYNTHETIC_ERRNO(ENOTDIR), log_full(flags & MKDIR_WARN_MODE ? LOG_WARNING : LOG_DEBUG,
"Path \"%s\" already exists and is not a directory, refusing.", path); "Path \"%s\" already exists and is not a directory, refusing.", path);
return -ENOTDIR;
}
if ((st.st_mode & 0007) > (mode & 0007) || if ((st.st_mode & 0007) > (mode & 0007) ||
(st.st_mode & 0070) > (mode & 0070) || (st.st_mode & 0070) > (mode & 0070) ||
(st.st_mode & 0700) > (mode & 0700)) (st.st_mode & 0700) > (mode & 0700)) {
return log_full_errno(flags & MKDIR_WARN_MODE ? LOG_WARNING : LOG_DEBUG, SYNTHETIC_ERRNO(EEXIST), log_full(flags & MKDIR_WARN_MODE ? LOG_WARNING : LOG_DEBUG,
"Directory \"%s\" already exists, but has mode %04o that is too permissive (%04o was requested), refusing.", "Directory \"%s\" already exists, but has mode %04o that is too permissive (%04o was requested), refusing.",
path, st.st_mode & 0777, mode); path, st.st_mode & 0777, mode);
return -EEXIST;
}
if ((uid != UID_INVALID && st.st_uid != uid) || if ((uid != UID_INVALID && st.st_uid != uid) ||
(gid != GID_INVALID && st.st_gid != gid)) { (gid != GID_INVALID && st.st_gid != gid)) {
char u[DECIMAL_STR_MAX(uid_t)] = "-", g[DECIMAL_STR_MAX(gid_t)] = "-"; char u[DECIMAL_STR_MAX(uid_t)] = "-", g[DECIMAL_STR_MAX(gid_t)] = "-";
@ -69,9 +65,10 @@ int mkdir_safe_internal(
xsprintf(u, UID_FMT, uid); xsprintf(u, UID_FMT, uid);
if (gid != UID_INVALID) if (gid != UID_INVALID)
xsprintf(g, GID_FMT, gid); xsprintf(g, GID_FMT, gid);
return log_full_errno(flags & MKDIR_WARN_MODE ? LOG_WARNING : LOG_DEBUG, SYNTHETIC_ERRNO(EEXIST), log_full(flags & MKDIR_WARN_MODE ? LOG_WARNING : LOG_DEBUG,
"Directory \"%s\" already exists, but is owned by "UID_FMT":"GID_FMT" (%s:%s was requested), refusing.", "Directory \"%s\" already exists, but is owned by "UID_FMT":"GID_FMT" (%s:%s was requested), refusing.",
path, st.st_uid, st.st_gid, u, g); path, st.st_uid, st.st_gid, u, g);
return -EEXIST;
} }
return 0; return 0;

View File

@ -1301,8 +1301,8 @@ int safe_fork_full(
r, "Failed to rename process, ignoring: %m"); r, "Failed to rename process, ignoring: %m");
} }
if (flags & (FORK_DEATHSIG|FORK_DEATHSIG_SIGINT)) if (flags & FORK_DEATHSIG)
if (prctl(PR_SET_PDEATHSIG, (flags & FORK_DEATHSIG_SIGINT) ? SIGINT : SIGTERM) < 0) { if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) {
log_full_errno(prio, errno, "Failed to set death signal: %m"); log_full_errno(prio, errno, "Failed to set death signal: %m");
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }

View File

@ -150,16 +150,15 @@ int must_be_root(void);
typedef enum ForkFlags { typedef enum ForkFlags {
FORK_RESET_SIGNALS = 1 << 0, /* Reset all signal handlers and signal mask */ FORK_RESET_SIGNALS = 1 << 0, /* Reset all signal handlers and signal mask */
FORK_CLOSE_ALL_FDS = 1 << 1, /* Close all open file descriptors in the child, except for 0,1,2 */ FORK_CLOSE_ALL_FDS = 1 << 1, /* Close all open file descriptors in the child, except for 0,1,2 */
FORK_DEATHSIG = 1 << 2, /* Set PR_DEATHSIG in the child to SIGTERM */ FORK_DEATHSIG = 1 << 2, /* Set PR_DEATHSIG in the child */
FORK_DEATHSIG_SIGINT = 1 << 3, /* Set PR_DEATHSIG in the child to SIGINT */ FORK_NULL_STDIO = 1 << 3, /* Connect 0,1,2 to /dev/null */
FORK_NULL_STDIO = 1 << 4, /* Connect 0,1,2 to /dev/null */ FORK_REOPEN_LOG = 1 << 4, /* Reopen log connection */
FORK_REOPEN_LOG = 1 << 5, /* Reopen log connection */ FORK_LOG = 1 << 5, /* Log above LOG_DEBUG log level about failures */
FORK_LOG = 1 << 6, /* Log above LOG_DEBUG log level about failures */ FORK_WAIT = 1 << 6, /* Wait until child exited */
FORK_WAIT = 1 << 7, /* Wait until child exited */ FORK_NEW_MOUNTNS = 1 << 7, /* Run child in its own mount namespace */
FORK_NEW_MOUNTNS = 1 << 8, /* Run child in its own mount namespace */ FORK_MOUNTNS_SLAVE = 1 << 8, /* Make child's mount namespace MS_SLAVE */
FORK_MOUNTNS_SLAVE = 1 << 9, /* Make child's mount namespace MS_SLAVE */ FORK_RLIMIT_NOFILE_SAFE = 1 << 9, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */
FORK_RLIMIT_NOFILE_SAFE = 1 << 10, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */ FORK_STDOUT_TO_STDERR = 1 << 10, /* Make stdout a copy of stderr */
FORK_STDOUT_TO_STDERR = 1 << 11, /* Make stdout a copy of stderr */
} ForkFlags; } ForkFlags;
int safe_fork_full(const char *name, const int except_fds[], size_t n_except_fds, ForkFlags flags, pid_t *ret_pid); int safe_fork_full(const char *name, const int except_fds[], size_t n_except_fds, ForkFlags flags, pid_t *ret_pid);

View File

@ -1002,9 +1002,6 @@ int flush_accept(int fd) {
if (r == 0) if (r == 0)
return 0; return 0;
if (pollfd.revents & POLLNVAL)
return -EBADF;
if (iteration >= MAX_FLUSH_ITERATIONS) if (iteration >= MAX_FLUSH_ITERATIONS)
return log_debug_errno(SYNTHETIC_ERRNO(EBUSY), return log_debug_errno(SYNTHETIC_ERRNO(EBUSY),
"Failed to flush connections within " STRINGIFY(MAX_FLUSH_ITERATIONS) " iterations."); "Failed to flush connections within " STRINGIFY(MAX_FLUSH_ITERATIONS) " iterations.");

View File

@ -347,7 +347,7 @@ static int property_set_kexec_watchdog(
void *userdata, void *userdata,
sd_bus_error *error) { sd_bus_error *error) {
_unused_ Manager *m = userdata; Manager *m = userdata;
assert(m); assert(m);
assert(bus); assert(bus);

View File

@ -535,9 +535,9 @@ int mount_setup(bool loaded_policy, bool leave_propagation) {
(void) mkdir_label("/run/systemd", 0755); (void) mkdir_label("/run/systemd", 0755);
(void) mkdir_label("/run/systemd/system", 0755); (void) mkdir_label("/run/systemd/system", 0755);
/* Also create /run/systemd/inaccessible nodes, so that we always have something to mount /* Also create /run/systemd/inaccessible nodes, so that we always have something to mount inaccessible nodes
* inaccessible nodes from. */ * from. */
(void) make_inaccessible_nodes(NULL, UID_INVALID, GID_INVALID); (void) make_inaccessible_nodes("/run/systemd", UID_INVALID, GID_INVALID);
return 0; return 0;
} }

View File

@ -939,10 +939,10 @@ static int apply_mount(
} }
if (geteuid() == 0) if (geteuid() == 0)
runtime_dir = "/run"; runtime_dir = "/run/systemd";
else { else {
if (asprintf(&tmp, "/run/user/" UID_FMT, geteuid()) < 0) if (asprintf(&tmp, "/run/user/"UID_FMT, geteuid()) < 0)
return -ENOMEM; log_oom();
runtime_dir = tmp; runtime_dir = tmp;
} }

View File

@ -932,8 +932,8 @@ static int run(int argc, char *argv[]) {
log_warning("Key file %s is world-readable. This is not a good idea!", key_file); log_warning("Key file %s is world-readable. This is not a good idea!", key_file);
} }
if (!arg_type || STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2)) { if (!arg_type || STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1)) {
r = crypt_load(cd, !arg_type || streq(arg_type, ANY_LUKS) ? CRYPT_LUKS : arg_type, NULL); r = crypt_load(cd, CRYPT_LUKS, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to load LUKS superblock on device %s: %m", crypt_get_device_name(cd)); return log_error_errno(r, "Failed to load LUKS superblock on device %s: %m", crypt_get_device_name(cd));
@ -957,7 +957,7 @@ static int run(int argc, char *argv[]) {
/* since cryptsetup 2.3.0 (Feb 2020) */ /* since cryptsetup 2.3.0 (Feb 2020) */
#ifdef CRYPT_BITLK #ifdef CRYPT_BITLK
if (streq_ptr(arg_type, CRYPT_BITLK)) { if (!arg_type || STR_IN_SET(arg_type, ANY_LUKS, CRYPT_BITLK)) {
r = crypt_load(cd, CRYPT_BITLK, NULL); r = crypt_load(cd, CRYPT_BITLK, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to load Bitlocker superblock on device %s: %m", crypt_get_device_name(cd)); return log_error_errno(r, "Failed to load Bitlocker superblock on device %s: %m", crypt_get_device_name(cd));

View File

@ -96,7 +96,7 @@ _public_ int sd_journal_printv(int priority, const char *format, va_list ap) {
/* Allocate large buffer to accommodate big message */ /* Allocate large buffer to accommodate big message */
if (len >= LINE_MAX) { if (len >= LINE_MAX) {
_unused_ int rlen; int rlen;
buffer = alloca(len + 9); buffer = alloca(len + 9);
memcpy(buffer, "MESSAGE=", 8); memcpy(buffer, "MESSAGE=", 8);
rlen = vsnprintf(buffer + 8, len + 1, format, ap); rlen = vsnprintf(buffer + 8, len + 1, format, ap);
@ -474,7 +474,7 @@ _public_ int sd_journal_printv_with_location(int priority, const char *file, con
/* Allocate large buffer to accommodate big message */ /* Allocate large buffer to accommodate big message */
if (len >= LINE_MAX) { if (len >= LINE_MAX) {
_unused_ int rlen; int rlen;
buffer = alloca(len + 9); buffer = alloca(len + 9);
memcpy(buffer, "MESSAGE=", 8); memcpy(buffer, "MESSAGE=", 8);
rlen = vsnprintf(buffer + 8, len + 1, format, ap); rlen = vsnprintf(buffer + 8, len + 1, format, ap);

View File

@ -2093,13 +2093,10 @@ static int wait_for_change(sd_journal *j, int poll_fd) {
return log_error_errno(errno, "Couldn't wait for journal event: %m"); return log_error_errno(errno, "Couldn't wait for journal event: %m");
} }
if (pollfds[1].revents & (POLLHUP|POLLERR|POLLNVAL)) /* STDOUT has been closed? */ if (pollfds[1].revents & (POLLHUP|POLLERR)) /* STDOUT has been closed? */
return log_debug_errno(SYNTHETIC_ERRNO(ECANCELED), return log_debug_errno(SYNTHETIC_ERRNO(ECANCELED),
"Standard output has been closed."); "Standard output has been closed.");
if (pollfds[0].revents & POLLNVAL)
return log_debug_errno(SYNTHETIC_ERRNO(EBADF), "Change fd closed?");
r = sd_journal_process(j); r = sd_journal_process(j);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to process journal events: %m"); return log_error_errno(r, "Failed to process journal events: %m");

View File

@ -1275,8 +1275,6 @@ int bus_socket_process_opening(sd_bus *b) {
r = poll(&p, 1, 0); r = poll(&p, 1, 0);
if (r < 0) if (r < 0)
return -errno; return -errno;
if (p.revents & POLLNVAL)
return -EBADF;
if (!(p.revents & (POLLOUT|POLLERR|POLLHUP))) if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
return 0; return 0;

View File

@ -3121,15 +3121,8 @@ static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) {
r = ppoll(p, n, m == USEC_INFINITY ? NULL : timespec_store(&ts, m), NULL); r = ppoll(p, n, m == USEC_INFINITY ? NULL : timespec_store(&ts, m), NULL);
if (r < 0) if (r < 0)
return -errno; return -errno;
if (r == 0)
return 0;
if (p[0].revents & POLLNVAL) return r > 0 ? 1 : 0;
return -EBADF;
if (n >= 2 && (p[1].revents & POLLNVAL))
return -EBADF;
return 1;
} }
_public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) { _public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) {

View File

@ -577,8 +577,6 @@ _public_ int sd_notify_barrier(int unset_environment, uint64_t timeout) {
return -errno; return -errno;
if (r == 0) if (r == 0)
return -ETIMEDOUT; return -ETIMEDOUT;
if (pfd.revents & POLLNVAL)
return -EBADF;
return 1; return 1;
} }

View File

@ -462,6 +462,7 @@ static usec_t calc_elapse(uint64_t usec) {
} }
static int rtnl_poll(sd_netlink *rtnl, bool need_more, uint64_t timeout_usec) { static int rtnl_poll(sd_netlink *rtnl, bool need_more, uint64_t timeout_usec) {
struct pollfd p[1] = {};
struct timespec ts; struct timespec ts;
usec_t m = USEC_INFINITY; usec_t m = USEC_INFINITY;
int r, e; int r, e;
@ -494,21 +495,14 @@ static int rtnl_poll(sd_netlink *rtnl, bool need_more, uint64_t timeout_usec) {
if (timeout_usec != (uint64_t) -1 && (m == (uint64_t) -1 || timeout_usec < m)) if (timeout_usec != (uint64_t) -1 && (m == (uint64_t) -1 || timeout_usec < m))
m = timeout_usec; m = timeout_usec;
struct pollfd p = { p[0].fd = rtnl->fd;
.fd = rtnl->fd, p[0].events = e;
.events = e,
};
r = ppoll(&p, 1, m == (uint64_t) -1 ? NULL : timespec_store(&ts, m), NULL); r = ppoll(p, 1, m == (uint64_t) -1 ? NULL : timespec_store(&ts, m), NULL);
if (r < 0) if (r < 0)
return -errno; return -errno;
if (r == 0)
return 0;
if (p.revents & POLLNVAL) return r > 0 ? 1 : 0;
return -EBADF;
return 1;
} }
int sd_netlink_wait(sd_netlink *nl, uint64_t timeout_usec) { int sd_netlink_wait(sd_netlink *nl, uint64_t timeout_usec) {

View File

@ -216,11 +216,8 @@ static int udev_monitor_receive_sd_device(struct udev_monitor *udev_monitor, sd_
continue; continue;
return -errno; return -errno;
} } else if (r == 0)
if (r == 0)
return -EAGAIN; return -EAGAIN;
if (pfd.revents & POLLNVAL)
return -EBADF;
/* receive next message */ /* receive next message */
break; break;

View File

@ -78,7 +78,7 @@ static int user_mkdir_runtime_path(
r = mount("tmpfs", runtime_path, "tmpfs", MS_NODEV|MS_NOSUID, options); r = mount("tmpfs", runtime_path, "tmpfs", MS_NODEV|MS_NOSUID, options);
if (r < 0) { if (r < 0) {
if (!ERRNO_IS_PRIVILEGE(errno)) { if (!IN_SET(errno, EPERM, EACCES)) {
r = log_error_errno(errno, "Failed to mount per-user tmpfs directory %s: %m", runtime_path); r = log_error_errno(errno, "Failed to mount per-user tmpfs directory %s: %m", runtime_path);
goto fail; goto fail;
} }

View File

@ -898,7 +898,7 @@ static int mount_inaccessible(const char *dest, CustomMount *m) {
return m->graceful ? 0 : r; return m->graceful ? 0 : r;
} }
r = mode_to_inaccessible_node(NULL, st.st_mode, &source); r = mode_to_inaccessible_node("/run/systemd", st.st_mode, &source);
if (r < 0) if (r < 0)
return m->graceful ? 0 : r; return m->graceful ? 0 : r;

View File

@ -3482,7 +3482,7 @@ static int outer_child(
(void) dev_setup(directory, arg_uid_shift, arg_uid_shift); (void) dev_setup(directory, arg_uid_shift, arg_uid_shift);
p = prefix_roota(directory, "/run"); p = prefix_roota(directory, "/run/systemd");
(void) make_inaccessible_nodes(p, arg_uid_shift, arg_uid_shift); (void) make_inaccessible_nodes(p, arg_uid_shift, arg_uid_shift);
r = setup_pts(directory); r = setup_pts(directory);

View File

@ -305,12 +305,6 @@ int ask_password_plymouth(
goto finish; goto finish;
} }
if (pollfd[POLL_SOCKET].revents & POLLNVAL ||
(notify >= 0 && pollfd[POLL_INOTIFY].revents & POLLNVAL)) {
r = -EBADF;
goto finish;
}
if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0) if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0)
(void) flush_fd(notify); (void) flush_fd(notify);
@ -547,12 +541,6 @@ int ask_password_tty(
goto finish; goto finish;
} }
if ((pollfd[POLL_TTY].revents & POLLNVAL) ||
(notify >= 0 && (pollfd[POLL_INOTIFY].revents & POLLNVAL))) {
r = -EBADF;
goto finish;
}
if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0 && keyname) { if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0 && keyname) {
(void) flush_fd(notify); (void) flush_fd(notify);
@ -900,13 +888,6 @@ int ask_password_agent(
goto finish; goto finish;
} }
if (pollfd[FD_SOCKET].revents & POLLNVAL ||
pollfd[FD_SIGNAL].revents & POLLNVAL ||
(notify >= 0 && pollfd[FD_INOTIFY].revents & POLLNVAL)) {
r = -EBADF;
goto finish;
}
if (pollfd[FD_SIGNAL].revents & POLLIN) { if (pollfd[FD_SIGNAL].revents & POLLIN) {
r = -EINTR; r = -EINTR;
goto finish; goto finish;

View File

@ -218,14 +218,10 @@ static bool barrier_read(Barrier *b, int64_t comp) {
uint64_t buf; uint64_t buf;
int r; int r;
r = poll(pfd, ELEMENTSOF(pfd), -1); r = poll(pfd, 2, -1);
if (r < 0) { if (r < 0 && IN_SET(errno, EAGAIN, EINTR))
if (IN_SET(errno, EAGAIN, EINTR))
continue; continue;
goto error; else if (r < 0)
}
if (pfd[0].revents & POLLNVAL ||
pfd[1].revents & POLLNVAL)
goto error; goto error;
if (pfd[1].revents) { if (pfd[1].revents) {

View File

@ -56,38 +56,31 @@ int dev_setup(const char *prefix, uid_t uid, gid_t gid) {
return 0; return 0;
} }
int make_inaccessible_nodes( int make_inaccessible_nodes(const char *root, uid_t uid, gid_t gid) {
const char *runtime_dir,
uid_t uid,
gid_t gid) {
static const struct { static const struct {
const char *name; const char *name;
mode_t mode; mode_t mode;
} table[] = { } table[] = {
{ "/systemd", S_IFDIR | 0755 }, { "", S_IFDIR | 0755 },
{ "/systemd/inaccessible", S_IFDIR | 0000 }, { "/inaccessible", S_IFDIR | 0000 },
{ "/systemd/inaccessible/reg", S_IFREG | 0000 }, { "/inaccessible/reg", S_IFREG | 0000 },
{ "/systemd/inaccessible/dir", S_IFDIR | 0000 }, { "/inaccessible/dir", S_IFDIR | 0000 },
{ "/systemd/inaccessible/fifo", S_IFIFO | 0000 }, { "/inaccessible/fifo", S_IFIFO | 0000 },
{ "/systemd/inaccessible/sock", S_IFSOCK | 0000 }, { "/inaccessible/sock", S_IFSOCK | 0000 },
/* The following two are likely to fail if we lack the privs for it (for example in an userns /* The following two are likely to fail if we lack the privs for it (for example in an userns
* environment, if CAP_SYS_MKNOD is missing, or if a device node policy prohibit major/minor of 0 * environment, if CAP_SYS_MKNOD is missing, or if a device node policy prohibit major/minor of 0
* device nodes to be created). But that's entirely fine. Consumers of these files should carry * device nodes to be created). But that's entirely fine. Consumers of these files should carry
* fallback to use a different node then, for example <root>/inaccessible/sock, which is close * fallback to use a different node then, for example <root>/inaccessible/sock, which is close
* enough in behaviour and semantics for most uses. */ * enough in behaviour and semantics for most uses. */
{ "/systemd/inaccessible/chr", S_IFCHR | 0000 }, { "/inaccessible/chr", S_IFCHR | 0000 },
{ "/systemd/inaccessible/blk", S_IFBLK | 0000 }, { "/inaccessible/blk", S_IFBLK | 0000 },
}; };
_cleanup_umask_ mode_t u; _cleanup_umask_ mode_t u;
size_t i; size_t i;
int r; int r;
if (!runtime_dir)
runtime_dir = "/run";
u = umask(0000); u = umask(0000);
/* Set up inaccessible (and empty) file nodes of all types. This are used to as mount sources for over-mounting /* Set up inaccessible (and empty) file nodes of all types. This are used to as mount sources for over-mounting
@ -98,7 +91,7 @@ int make_inaccessible_nodes(
for (i = 0; i < ELEMENTSOF(table); i++) { for (i = 0; i < ELEMENTSOF(table); i++) {
_cleanup_free_ char *path = NULL; _cleanup_free_ char *path = NULL;
path = path_join(runtime_dir, table[i].name); path = path_join(root, table[i].name);
if (!path) if (!path)
return log_oom(); return log_oom();

View File

@ -397,73 +397,71 @@ int repeat_unmount(const char *path, int flags) {
} }
} }
int mode_to_inaccessible_node( int mode_to_inaccessible_node(const char *runtime_dir, mode_t mode, char **dest) {
const char *runtime_dir, /* This function maps a node type to a corresponding inaccessible file node. These nodes are created during
mode_t mode, * early boot by PID 1. In some cases we lacked the privs to create the character and block devices (maybe
char **ret) { * because we run in an userns environment, or miss CAP_SYS_MKNOD, or run with a devices policy that excludes
* device nodes with major and minor of 0), but that's fine, in that case we use an AF_UNIX file node instead,
/* This function maps a node type to a corresponding inaccessible file node. These nodes are created * which is not the same, but close enough for most uses. And most importantly, the kernel allows bind mounts
* during early boot by PID 1. In some cases we lacked the privs to create the character and block * from socket nodes to any non-directory file nodes, and that's the most important thing that matters. */
* devices (maybe because we run in an userns environment, or miss CAP_SYS_MKNOD, or run with a
* devices policy that excludes device nodes with major and minor of 0), but that's fine, in that
* case we use an AF_UNIX file node instead, which is not the same, but close enough for most
* uses. And most importantly, the kernel allows bind mounts from socket nodes to any non-directory
* file nodes, and that's the most important thing that matters.
*
* Note that the runtime directory argument shall be the top-level runtime directory, i.e. /run/ if
* we operate in system context and $XDG_RUNTIME_DIR if we operate in user context. */
_cleanup_free_ char *d = NULL; _cleanup_free_ char *d = NULL;
const char *node = NULL; const char *node = NULL;
bool fallback = false; char *tmp;
assert(ret); assert(dest);
if (!runtime_dir)
runtime_dir = "/run";
switch(mode & S_IFMT) { switch(mode & S_IFMT) {
case S_IFREG: case S_IFREG:
node = "/systemd/inaccessible/reg"; node = "/inaccessible/reg";
break; break;
case S_IFDIR: case S_IFDIR:
node = "/systemd/inaccessible/dir"; node = "/inaccessible/dir";
break; break;
case S_IFCHR: case S_IFCHR:
node = "/systemd/inaccessible/chr"; d = path_join(runtime_dir, "/inaccessible/chr");
fallback = true; if (!d)
return log_oom();
if (access(d, F_OK) == 0) {
*dest = TAKE_PTR(d);
return 0;
}
node = "/inaccessible/sock";
break; break;
case S_IFBLK: case S_IFBLK:
node = "/systemd/inaccessible/blk"; d = path_join(runtime_dir, "/inaccessible/blk");
fallback = true; if (!d)
return log_oom();
if (access(d, F_OK) == 0) {
*dest = TAKE_PTR(d);
return 0;
}
node = "/inaccessible/sock";
break; break;
case S_IFIFO: case S_IFIFO:
node = "/systemd/inaccessible/fifo"; node = "/inaccessible/fifo";
break; break;
case S_IFSOCK: case S_IFSOCK:
node = "/systemd/inaccessible/sock"; node = "/inaccessible/sock";
break; break;
} }
if (!node) if (!node)
return -EINVAL; return -EINVAL;
d = path_join(runtime_dir, node); tmp = path_join(runtime_dir, node);
if (!d) if (!tmp)
return -ENOMEM; return log_oom();
if (fallback && access(d, F_OK) < 0) { *dest = tmp;
free(d);
d = path_join(runtime_dir, "/systemd/inaccessible/sock");
if (!d)
return -ENOMEM;
}
*ret = TAKE_PTR(d);
return 0; return 0;
} }

View File

@ -131,8 +131,7 @@ int pager_open(PagerFlags flags) {
if (flags & PAGER_JUMP_TO_END) if (flags & PAGER_JUMP_TO_END)
less_opts = strjoina(less_opts, " +G"); less_opts = strjoina(less_opts, " +G");
/* We set SIGINT as PR_DEATHSIG signal here, to match the "K" parameter we set in $LESS, which enables SIGINT behaviour. */ r = safe_fork("(pager)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pager_pid);
r = safe_fork("(pager)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGINT|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pager_pid);
if (r < 0) if (r < 0)
return r; return r;
if (r == 0) { if (r == 0) {

View File

@ -334,10 +334,9 @@ static int write_to_terminal(const char *tty, const char *message) {
k = poll(&pollfd, 1, (end - t) / USEC_PER_MSEC); k = poll(&pollfd, 1, (end - t) / USEC_PER_MSEC);
if (k < 0) if (k < 0)
return -errno; return -errno;
if (k == 0) if (k == 0)
return -ETIME; return -ETIME;
if (pollfd.revents & POLLNVAL)
return -EBADF;
n = write(fd, p, left); n = write(fd, p, left);
if (n < 0) { if (n < 0) {

View File

@ -1048,14 +1048,10 @@ int varlink_wait(Varlink *v, usec_t timeout) {
NULL); NULL);
if (r < 0) if (r < 0)
return -errno; return -errno;
if (r == 0)
return 0;
if (pfd.revents & POLLNVAL)
return -EBADF;
handle_revents(v, pfd.revents); handle_revents(v, pfd.revents);
return 1;
return r > 0 ? 1 : 0;
} }
int varlink_get_fd(Varlink *v) { int varlink_get_fd(Varlink *v) {
@ -1143,14 +1139,9 @@ int varlink_flush(Varlink *v) {
.events = POLLOUT, .events = POLLOUT,
}; };
r = poll(&pfd, 1, -1); if (poll(&pfd, 1, -1) < 0)
if (r < 0)
return -errno; return -errno;
assert(r > 0);
if (pfd.revents & POLLNVAL)
return -EBADF;
handle_revents(v, pfd.revents); handle_revents(v, pfd.revents);
} }

View File

@ -271,9 +271,6 @@ static int execute_s2h(const SleepConfig *sleep_config) {
tfd = safe_close(tfd); tfd = safe_close(tfd);
if (FLAGS_SET(fds.revents, POLLNVAL))
return log_error_errno(SYNTHETIC_ERRNO(EBADF), "Invalid timer fd to sleep on?");
if (!FLAGS_SET(fds.revents, POLLIN)) /* We woke up before the alarm time, we are done. */ if (!FLAGS_SET(fds.revents, POLLIN)) /* We woke up before the alarm time, we are done. */
return 0; return 0;

View File

@ -238,19 +238,17 @@ static int run(int argc, char *argv[]) {
ts = timespec_store(&_ts, t); ts = timespec_store(&_ts, t);
} }
{
struct pollfd p[3] = { struct pollfd p[3] = {
{ .fd = fd, .events = events_a }, {.fd = fd, .events = events_a },
{ .fd = STDIN_FILENO, .events = events_b & POLLIN }, {.fd = STDIN_FILENO, .events = events_b & POLLIN },
{ .fd = STDOUT_FILENO, .events = events_b & POLLOUT }, {.fd = STDOUT_FILENO, .events = events_b & POLLOUT },
}; };
r = ppoll(p, ELEMENTSOF(p), ts, NULL); r = ppoll(p, ELEMENTSOF(p), ts, NULL);
}
if (r < 0) if (r < 0)
return log_error_errno(errno, "ppoll() failed: %m"); return log_error_errno(errno, "ppoll() failed: %m");
if (p[0].revents & POLLNVAL ||
p[1].revents & POLLNVAL ||
p[2].revents & POLLNVAL)
return log_error_errno(SYNTHETIC_ERRNO(EBADF), "Invalid file descriptor to poll on?");
} }
return 0; return 0;

View File

@ -20,6 +20,7 @@ int main(int argc, char *argv[]) {
f = prefix_roota(p, "/run"); f = prefix_roota(p, "/run");
assert_se(mkdir(f, 0755) >= 0); assert_se(mkdir(f, 0755) >= 0);
f = prefix_roota(p, "/run/systemd");
assert_se(make_inaccessible_nodes(f, 1, 1) >= 0); assert_se(make_inaccessible_nodes(f, 1, 1) >= 0);
f = prefix_roota(p, "/run/systemd/inaccessible/reg"); f = prefix_roota(p, "/run/systemd/inaccessible/reg");

View File

@ -395,10 +395,6 @@ static int process_and_watch_password_files(bool watch) {
return -errno; return -errno;
} }
if (pollfd[FD_SIGNAL].revents & POLLNVAL ||
pollfd[FD_INOTIFY].revents & POLLNVAL)
return -EBADF;
if (pollfd[FD_INOTIFY].revents != 0) if (pollfd[FD_INOTIFY].revents != 0)
(void) flush_fd(notify); (void) flush_fd(notify);

View File

@ -202,12 +202,7 @@ int settle_main(int argc, char *argv[], void *userdata) {
return -ETIMEDOUT; return -ETIMEDOUT;
/* wake up when queue becomes empty */ /* wake up when queue becomes empty */
r = poll(&pfd, 1, MSEC_PER_SEC); if (poll(&pfd, 1, MSEC_PER_SEC) > 0 && pfd.revents & POLLIN) {
if (r < 0)
return -errno;
if (pfd.revents & POLLNVAL)
return -EBADF;
if (r > 0 && pfd.revents & POLLIN) {
r = udev_queue_flush(queue); r = udev_queue_flush(queue);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to flush queue: %m"); return log_error_errno(r, "Failed to flush queue: %m");

View File

@ -1841,13 +1841,12 @@ int run_udevd(int argc, char *argv[]) {
return r; return r;
if (arg_children_max == 0) { if (arg_children_max == 0) {
unsigned long cpu_limit, mem_limit, cpu_count = 1; unsigned long cpu_limit, mem_limit;
unsigned long cpu_count = 1;
cpu_set_t cpu_set;
r = cpus_in_affinity_mask(); if (sched_getaffinity(0, sizeof(cpu_set), &cpu_set) == 0)
if (r < 0) cpu_count = CPU_COUNT(&cpu_set);
log_warning_errno(r, "Failed to determine number of local CPUs, ignoring: %m");
else
cpu_count = r;
cpu_limit = cpu_count * 2 + 16; cpu_limit = cpu_count * 2 + 16;
mem_limit = MAX(physical_memory() / (128UL*1024*1024), 10U); mem_limit = MAX(physical_memory() / (128UL*1024*1024), 10U);
@ -1859,6 +1858,10 @@ int run_udevd(int argc, char *argv[]) {
} }
/* set umask before creating any file/directory */ /* set umask before creating any file/directory */
r = chdir("/");
if (r < 0)
return log_error_errno(errno, "Failed to change dir to '/': %m");
umask(022); umask(022);
r = mac_selinux_init(); r = mac_selinux_init();
@ -1869,6 +1872,8 @@ int run_udevd(int argc, char *argv[]) {
if (r < 0 && r != -EEXIST) if (r < 0 && r != -EEXIST)
return log_error_errno(r, "Failed to create /run/udev: %m"); return log_error_errno(r, "Failed to create /run/udev: %m");
dev_setup(NULL, UID_INVALID, GID_INVALID);
if (getppid() == 1 && sd_booted() > 0) { if (getppid() == 1 && sd_booted() > 0) {
/* Get our own cgroup, we regularly kill everything udev has left behind. /* Get our own cgroup, we regularly kill everything udev has left behind.
* We only do this on systemd systems, and only if we are directly spawned * We only do this on systemd systems, and only if we are directly spawned
@ -1911,6 +1916,10 @@ int run_udevd(int argc, char *argv[]) {
/* child */ /* child */
(void) setsid(); (void) setsid();
r = set_oom_score_adjust(-1000);
if (r < 0)
log_debug_errno(r, "Failed to adjust OOM score, ignoring: %m");
} }
return main_loop(manager); return main_loop(manager);

View File

@ -757,8 +757,6 @@ static int run(int argc, char *argv[]) {
if (poll(&pfd, 1, 0) < 0) if (poll(&pfd, 1, 0) < 0)
return log_error_errno(errno, "Failed to test for POLLIN on listening socket: %m"); return log_error_errno(errno, "Failed to test for POLLIN on listening socket: %m");
if (FLAGS_SET(pfd.revents, POLLNVAL))
return log_error_errno(SYNTHETIC_ERRNO(EBADF), "Listening socket dead?");
if (FLAGS_SET(pfd.revents, POLLIN)) { if (FLAGS_SET(pfd.revents, POLLIN)) {
pid_t parent; pid_t parent;

View File

@ -29,34 +29,10 @@ ADDITIONAL_DEPS=(dnf-plugins-core
openssl-devel openssl-devel
p11-kit-devel) p11-kit-devel)
info() { function info() {
echo -e "\033[33;1m$1\033[0m" echo -e "\033[33;1m$1\033[0m"
} }
error() {
echo >&2 -e "\033[31;1m$1\033[0m"
}
success() {
echo >&2 -e "\033[32;1m$1\033[0m"
}
# Simple wrapper which retries given command up to five times
_retry() {
local EC=1
for i in {1..5}; do
if "$@"; then
EC=0
break
fi
sleep $((i * 5))
done
return $EC
}
set -e set -e
source "$(dirname $0)/travis_wait.bash" source "$(dirname $0)/travis_wait.bash"
@ -76,11 +52,11 @@ for phase in "${PHASES[@]}"; do
# running following dnf commands during the initializing/starting # running following dnf commands during the initializing/starting
# (early/late bootup) phase, which caused nasty race conditions # (early/late bootup) phase, which caused nasty race conditions
$DOCKER_EXEC bash -c 'systemctl is-system-running --wait || :' $DOCKER_EXEC bash -c 'systemctl is-system-running --wait || :'
_retry $DOCKER_EXEC dnf makecache $DOCKER_EXEC dnf makecache
# Install necessary build/test requirements # Install necessary build/test requirements
_retry $DOCKER_EXEC dnf -y --exclude selinux-policy\* upgrade $DOCKER_EXEC dnf -y --exclude selinux-policy\* upgrade
_retry $DOCKER_EXEC dnf -y install "${ADDITIONAL_DEPS[@]}" $DOCKER_EXEC dnf -y install "${ADDITIONAL_DEPS[@]}"
_retry $DOCKER_EXEC dnf -y builddep systemd $DOCKER_EXEC dnf -y builddep systemd
;; ;;
RUN) RUN)
info "Run phase" info "Run phase"
@ -110,53 +86,13 @@ for phase in "${PHASES[@]}"; do
-t $CONT_NAME \ -t $CONT_NAME \
meson test --timeout-multiplier=3 -C ./build/ --print-errorlogs meson test --timeout-multiplier=3 -C ./build/ --print-errorlogs
;; ;;
RUN_BUILD_CHECK_GCC|RUN_BUILD_CHECK_CLANG)
ARGS=(
"--optimization=0"
"--optimization=2"
"--optimization=3"
"--optimization=s"
"-Db_lto=true"
"-Db_ndebug=true"
)
if [[ "$phase" = "RUN_BUILD_CHECK_CLANG" ]]; then
ENV_VARS="-e CC=clang -e CXX=clang++"
$DOCKER_EXEC clang --version
else
$DOCKER_EXEC gcc --version
fi
for args in "${ARGS[@]}"; do
SECONDS=0
info "Checking build with $args"
# Redirect meson/ninja logs into separate files, otherwise we
# would trip over Travis' log size limit
if ! docker exec $ENV_VARS -it $CONT_NAME meson --werror $args build &> meson.log; then
cat meson.log
error "meson failed with $args"
exit 1
fi
if ! $DOCKER_EXEC ninja -v -C build &> ninja.log; then
cat ninja.log
error "ninja failed with $args"
exit 1
fi
$DOCKER_EXEC rm -fr build
rm -f meson.log ninja.log
success "Build with $args passed in $SECONDS seconds"
done
;;
CLEANUP) CLEANUP)
info "Cleanup phase" info "Cleanup phase"
docker stop $CONT_NAME docker stop $CONT_NAME
docker rm -f $CONT_NAME docker rm -f $CONT_NAME
;; ;;
*) *)
error "Unknown phase '$phase'" echo >&2 "Unknown phase '$phase'"
exit 1 exit 1
esac esac
done done