diff options
173 files changed, 961 insertions, 969 deletions
diff --git a/coccinelle/run-coccinelle.sh b/coccinelle/run-coccinelle.sh index de23546f19..f463f5eed5 100755 --- a/coccinelle/run-coccinelle.sh +++ b/coccinelle/run-coccinelle.sh @@ -1,10 +1,9 @@ #!/bin/bash -e for SCRIPT in ${@-*.cocci} ; do - echo "--x-- Processing: spatch --sp-file $SCRIPT --dir $(pwd)/.. --x--" + echo "--x-- Processing $SCRIPT --x--" TMPFILE=`mktemp` - spatch --sp-file $SCRIPT --dir $(pwd)/.. 2> "$TMPFILE" || cat "$TMPFILE" + ( set -x ; spatch --sp-file $SCRIPT --dir $PWD/.. 2> "$TMPFILE" || cat "$TMPFILE" ) rm "$TMPFILE" - echo "--x-- Processed: spatch --sp-file $SCRIPT --dir $(pwd)/.. --x--" - echo "" + echo -e "--x-- Processed $SCRIPT --x--\n" done diff --git a/coccinelle/take-fd.cocci b/coccinelle/take-fd.cocci new file mode 100644 index 0000000000..ba242483cd --- /dev/null +++ b/coccinelle/take-fd.cocci @@ -0,0 +1,14 @@ +@@ +local idexpression p; +expression q; +@@ +- p = q; +- q = -1; +- return p; ++ return TAKE_FD(q); +@@ +expression p, q; +@@ +- p = q; +- q = -1; ++ p = TAKE_FD(q); diff --git a/coccinelle/take-ptr.cocci b/coccinelle/take-ptr.cocci new file mode 100644 index 0000000000..0cebe81575 --- /dev/null +++ b/coccinelle/take-ptr.cocci @@ -0,0 +1,14 @@ +@@ +local idexpression p; +expression q; +@@ +- p = q; +- q = NULL; +- return p; ++ return TAKE_PTR(q); +@@ +expression p, q; +@@ +- p = q; +- q = NULL; ++ p = TAKE_PTR(q); diff --git a/doc/HACKING b/doc/HACKING index b9c53dc56b..92001be94e 100644 --- a/doc/HACKING +++ b/doc/HACKING @@ -68,6 +68,7 @@ for systemd (this example is for Fedora): $ meson build # configure the build $ ninja -C build # build it locally, see if everything compiles fine $ ninja -C build test # run some simple regression tests + $ (umask 077; echo 123 > mkosi.rootpw) # set root password used by mkosi $ sudo mkosi # build a test image $ sudo systemd-nspawn -bi image.raw # boot up the test image $ git add -p # interactively put together your patch diff --git a/man/bootup.xml b/man/bootup.xml index 27619c29b8..565dda93cb 100644 --- a/man/bootup.xml +++ b/man/bootup.xml @@ -298,8 +298,18 @@ systemd-reboot.service systemd-poweroff.service systemd-halt.service syste v v v v <emphasis>reboot.target</emphasis> <emphasis>poweroff.target</emphasis> <emphasis>halt.target</emphasis> <emphasis>kexec.target</emphasis></programlisting> - <para>Commonly used system shutdown targets are - <emphasis>emphasized</emphasis>.</para> + <para>Commonly used system shutdown targets are <emphasis>emphasized</emphasis>.</para> + + <para>Note that + <citerefentry>system<refentrytitle>systemd-halt.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>, + <filename>systemd-reboot.service</filename>, <filename>systemd-poweroff.service</filename> and + <filename>systemd-kexec.service</filename> will transition the system and server manager (PID 1) into the second + phase of system shutdown (implemented in the <filename>systemd-shutdown</filename> binary), which will unmount any + remaining file systems, kill any remaining processes and release any other remaining resources, in a simple and + robust fashion, without taking any service or unit concept into account anymore. At that point, regular + applications and resources are generally terminated and released already, the second phase hence operates only as + safety net for everything that couldn't be stopped or released for some reason during the primary, unit-based + shutdown phase described above.</para> </refsect1> <refsect1> @@ -309,6 +319,7 @@ systemd-reboot.service systemd-poweroff.service systemd-halt.service syste <citerefentry project='man-pages'><refentrytitle>boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>, <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>, <citerefentry><refentrytitle>systemd.target</refentrytitle><manvolnum>5</manvolnum></citerefentry>, + <citerefentry><refentrytitle>systemd-halt.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>, <citerefentry project='die-net'><refentrytitle>dracut</refentrytitle><manvolnum>8</manvolnum></citerefentry> </para> </refsect1> diff --git a/man/systemd-halt.service.xml b/man/systemd-halt.service.xml index b58279d828..a381b5c7d9 100644 --- a/man/systemd-halt.service.xml +++ b/man/systemd-halt.service.xml @@ -114,7 +114,8 @@ <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>, <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>, <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>, - <citerefentry><refentrytitle>systemd-suspend.service</refentrytitle><manvolnum>8</manvolnum></citerefentry> + <citerefentry><refentrytitle>systemd-suspend.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>, + <citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry> </para> </refsect1> diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml index fca9690092..74dee3fd6f 100644 --- a/man/systemd-system.conf.xml +++ b/man/systemd-system.conf.xml @@ -157,31 +157,27 @@ <term><varname>RuntimeWatchdogSec=</varname></term> <term><varname>ShutdownWatchdogSec=</varname></term> - <listitem><para>Configure the hardware watchdog at runtime and - at reboot. Takes a timeout value in seconds (or in other time - units if suffixed with <literal>ms</literal>, - <literal>min</literal>, <literal>h</literal>, - <literal>d</literal>, <literal>w</literal>). If - <varname>RuntimeWatchdogSec=</varname> is set to a non-zero - value, the watchdog hardware - (<filename>/dev/watchdog</filename> or the path specified with - <varname>WatchdogDevice=</varname> or the kernel option - <varname>systemd.watchdog-device=</varname>) will be programmed - to automatically reboot the system if it is not contacted within - the specified timeout interval. The system manager will ensure - to contact it at least once in half the specified timeout - interval. This feature requires a hardware watchdog device to - be present, as it is commonly the case in embedded and server - systems. Not all hardware watchdogs allow configuration of the - reboot timeout, in which case the closest available timeout is - picked. <varname>ShutdownWatchdogSec=</varname> may be used to - configure the hardware watchdog when the system is asked to - reboot. It works as a safety net to ensure that the reboot - takes place even if a clean reboot attempt times out. By - default <varname>RuntimeWatchdogSec=</varname> defaults to 0 - (off), and <varname>ShutdownWatchdogSec=</varname> to 10min. - These settings have no effect if a hardware watchdog is not - available.</para></listitem> + <listitem><para>Configure the hardware watchdog at runtime and at reboot. Takes a timeout value in seconds (or + in other time units if suffixed with <literal>ms</literal>, <literal>min</literal>, <literal>h</literal>, + <literal>d</literal>, <literal>w</literal>). If <varname>RuntimeWatchdogSec=</varname> is set to a non-zero + value, the watchdog hardware (<filename>/dev/watchdog</filename> or the path specified with + <varname>WatchdogDevice=</varname> or the kernel option <varname>systemd.watchdog-device=</varname>) will be + programmed to automatically reboot the system if it is not contacted within the specified timeout interval. The + system manager will ensure to contact it at least once in half the specified timeout interval. This feature + requires a hardware watchdog device to be present, as it is commonly the case in embedded and server + systems. Not all hardware watchdogs allow configuration of all possible reboot timeout values, in which case + the closest available timeout is picked. <varname>ShutdownWatchdogSec=</varname> may be used to configure the + hardware watchdog when the system is asked to reboot. It works as a safety net to ensure that the reboot takes + place even if a clean reboot attempt times out. Note that the <varname>ShutdownWatchdogSec=</varname> timeout + applies only to the second phase of the reboot, i.e. after all regular services are already terminated, and + after the system and service manager process (PID 1) got replaced by the <filename>systemd-shutdown</filename> + binary, see system <citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry> + for details. During the first phase of the shutdown operation the system and service manager remains running + and hence <varname>RuntimeWatchdogSec=</varname> is still honoured. In order to define a timeout on this first + phase of system shutdown, configure <varname>JobTimeoutSec=</varname> and <varname>JobTimeoutAction=</varname> + in the <literal>[Unit]</literal> section of the <filename>shutdown.target</filename> unit. By default + <varname>RuntimeWatchdogSec=</varname> defaults to 0 (off), and <varname>ShutdownWatchdogSec=</varname> to + 10min. These settings have no effect if a hardware watchdog is not available.</para></listitem> </varlistentry> <varlistentry> @@ -216,6 +212,21 @@ </varlistentry> <varlistentry> + <term><varname>NoNewPrivileges=</varname></term> + + <listitem><para>Takes a boolean argument. If true, ensures that PID 1 + and all its children can never gain new privileges through + <citerefentry project='man-pages'><refentrytitle>execve</refentrytitle><manvolnum>2</manvolnum></citerefentry> + (e.g. via setuid or setgid bits, or filesystem capabilities). + Defaults to false. General purpose distributions commonly rely + on executables with setuid or setgid bits and will thus not + function properly with this option enabled. Individual units + cannot disable this option. + Also see <ulink url="https://www.kernel.org/doc/html/latest/userspace-api/no_new_privs.html">No New Privileges Flag</ulink>. + </para></listitem> + </varlistentry> + + <varlistentry> <term><varname>SystemCallArchitectures=</varname></term> <listitem><para>Takes a space-separated list of architecture diff --git a/man/udevadm.xml b/man/udevadm.xml index 1495f556f3..bbe56f49fd 100644 --- a/man/udevadm.xml +++ b/man/udevadm.xml @@ -95,7 +95,6 @@ </listitem> </varlistentry> - <xi:include href="standard-options.xml" xpointer="version" /> <xi:include href="standard-options.xml" xpointer="help" /> </variablelist> @@ -202,7 +201,6 @@ </listitem> </varlistentry> - <xi:include href="standard-options.xml" xpointer="version" /> <xi:include href="standard-options.xml" xpointer="help" /> </variablelist> @@ -347,7 +345,6 @@ </listitem> </varlistentry> - <xi:include href="standard-options.xml" xpointer="version" /> <xi:include href="standard-options.xml" xpointer="help" /> </variablelist> @@ -380,7 +377,6 @@ </listitem> </varlistentry> - <xi:include href="standard-options.xml" xpointer="version" /> <xi:include href="standard-options.xml" xpointer="help" /> </variablelist> </refsect2> @@ -456,7 +452,6 @@ </listitem> </varlistentry> - <xi:include href="standard-options.xml" xpointer="version" /> <xi:include href="standard-options.xml" xpointer="help" /> </variablelist> </refsect2> @@ -505,7 +500,6 @@ </listitem> </varlistentry> - <xi:include href="standard-options.xml" xpointer="version" /> <xi:include href="standard-options.xml" xpointer="help" /> </variablelist> </refsect2> @@ -537,7 +531,6 @@ </listitem> </varlistentry> - <xi:include href="standard-options.xml" xpointer="version" /> <xi:include href="standard-options.xml" xpointer="help" /> </variablelist> </refsect2> @@ -551,7 +544,6 @@ for device <replaceable>DEVPATH</replaceable>, and print debug output.</para> <variablelist> - <xi:include href="standard-options.xml" xpointer="version" /> <xi:include href="standard-options.xml" xpointer="help" /> </variablelist> </refsect2> diff --git a/meson.build b/meson.build index 642ccd4491..0d62a11562 100644 --- a/meson.build +++ b/meson.build @@ -552,6 +552,7 @@ m4 = find_program('m4') stat = find_program('stat') git = find_program('git', required : false) env = find_program('env') +perl = find_program('perl', required : false) meson_make_symlink = meson.source_root() + '/tools/meson-make-symlink.sh' mkdir_p = 'mkdir -p $DESTDIR/@0@' diff --git a/src/backlight/backlight.c b/src/backlight/backlight.c index 8fedf8ebbc..2b19bfe0a0 100644 --- a/src/backlight/backlight.c +++ b/src/backlight/backlight.c @@ -234,9 +234,9 @@ static unsigned get_max_brightness(struct udev_device *device) { * an unreadably dim screen, which would otherwise force the user to * disable state restoration. */ static void clamp_brightness(struct udev_device *device, char **value, unsigned max_brightness) { - int r; unsigned brightness, new_brightness, min_brightness; const char *subsystem; + int r; r = safe_atou(*value, &brightness); if (r < 0) { @@ -272,8 +272,8 @@ static void clamp_brightness(struct udev_device *device, char **value, unsigned int main(int argc, char *argv[]) { _cleanup_udev_unref_ struct udev *udev = NULL; _cleanup_udev_device_unref_ struct udev_device *device = NULL; - _cleanup_free_ char *saved = NULL, *ss = NULL, *escaped_ss = NULL, *escaped_sysname = NULL, *escaped_path_id = NULL; - const char *sysname, *path_id; + _cleanup_free_ char *escaped_ss = NULL, *escaped_sysname = NULL, *escaped_path_id = NULL; + const char *sysname, *path_id, *ss, *saved; unsigned max_brightness; int r; @@ -306,15 +306,11 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - ss = strndup(argv[2], sysname - argv[2]); - if (!ss) { - log_oom(); - return EXIT_FAILURE; - } + ss = strndupa(argv[2], sysname - argv[2]); sysname++; - if (!streq(ss, "backlight") && !streq(ss, "leds")) { + if (!STR_IN_SET(ss, "backlight", "leds")) { log_error("Not a backlight or LED device: '%s:%s'", ss, sysname); return EXIT_FAILURE; } @@ -358,14 +354,9 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - saved = strjoin("/var/lib/systemd/backlight/", escaped_path_id, ":", escaped_ss, ":", escaped_sysname); + saved = strjoina("/var/lib/systemd/backlight/", escaped_path_id, ":", escaped_ss, ":", escaped_sysname); } else - saved = strjoin("/var/lib/systemd/backlight/", escaped_ss, ":", escaped_sysname); - - if (!saved) { - log_oom(); - return EXIT_FAILURE; - } + saved = strjoina("/var/lib/systemd/backlight/", escaped_ss, ":", escaped_sysname); /* If there are multiple conflicting backlight devices, then * their probing at boot-time might happen in any order. This diff --git a/src/basic/alloc-util.h b/src/basic/alloc-util.h index ec7808c1f7..b1e0edbb7f 100644 --- a/src/basic/alloc-util.h +++ b/src/basic/alloc-util.h @@ -130,3 +130,12 @@ void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size); _new_ = alloca_align(_size_, (align)); \ (void*)memset(_new_, 0, _size_); \ }) + +/* Takes inspiration from Rusts's Option::take() method: reads and returns a pointer, but at the same time resets it to + * NULL. See: https://doc.rust-lang.org/std/option/enum.Option.html#method.take */ +#define TAKE_PTR(ptr) \ + ({ \ + typeof(ptr) _ptr_ = (ptr); \ + (ptr) = NULL; \ + _ptr_; \ + }) diff --git a/src/basic/cap-list.c b/src/basic/cap-list.c index c4557666ef..9416391a53 100644 --- a/src/basic/cap-list.c +++ b/src/basic/cap-list.c @@ -103,8 +103,7 @@ int capability_set_to_string_alloc(uint64_t set, char **s) { str[n > 0 ? n - 1 : 0] = '\0'; /* truncate the last space, if it's there */ - *s = str; - str = NULL; + *s = TAKE_PTR(str); return 0; } diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index 1a2d7fc087..5934ee6e8a 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -1424,10 +1424,9 @@ int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) { if (r < 0) return r; - if (c == raw) { - *cgroup = raw; - raw = NULL; - } else { + if (c == raw) + *cgroup = TAKE_PTR(raw); + else { char *n; n = strdup(c); @@ -2010,8 +2009,7 @@ int cg_slice_to_path(const char *unit, char **ret) { if (!strextend(&s, e, NULL)) return -ENOMEM; - *ret = s; - s = NULL; + *ret = TAKE_PTR(s); return 0; } @@ -2301,8 +2299,7 @@ int cg_mask_to_string(CGroupMask mask, char **ret) { assert(s); s[n] = 0; - *ret = s; - s = NULL; + *ret = TAKE_PTR(s); return 0; } diff --git a/src/basic/extract-word.c b/src/basic/extract-word.c index 5e42560487..7a6b56f071 100644 --- a/src/basic/extract-word.c +++ b/src/basic/extract-word.c @@ -194,8 +194,7 @@ finish: finish_force_next: s[sz] = 0; - *ret = s; - s = NULL; + *ret = TAKE_PTR(s); return 1; } diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c index 6d7875361c..0726aac38c 100644 --- a/src/basic/fd-util.c +++ b/src/basic/fd-util.c @@ -484,10 +484,7 @@ int acquire_data_fd(const void *data, size_t size, unsigned flags) { if (r < 0) return r; - r = fd; - fd = -1; - - return r; + return TAKE_FD(fd); } try_pipe: @@ -524,10 +521,7 @@ try_pipe: (void) fd_nonblock(pipefds[0], false); - r = pipefds[0]; - pipefds[0] = -1; - - return r; + return TAKE_FD(pipefds[0]); } try_dev_shm: diff --git a/src/basic/fd-util.h b/src/basic/fd-util.h index 635a538b5a..007580b48f 100644 --- a/src/basic/fd-util.h +++ b/src/basic/fd-util.h @@ -105,3 +105,11 @@ int rearrange_stdio(int original_input_fd, int original_output_fd, int original_ static inline int make_null_stdio(void) { return rearrange_stdio(-1, -1, -1); } + +/* Like TAKE_PTR() but for file descriptors, resetting them to -1 */ +#define TAKE_FD(fd) \ + ({ \ + int _fd_ = (fd); \ + (fd) = -1; \ + _fd_; \ + }) diff --git a/src/basic/fileio.c b/src/basic/fileio.c index fb26274afa..f807842c31 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -330,8 +330,7 @@ int read_full_stream(FILE *f, char **contents, size_t *size) { } buf[l] = 0; - *contents = buf; - buf = NULL; /* do not free */ + *contents = TAKE_PTR(buf); if (size) *size = l; @@ -1432,8 +1431,7 @@ int open_tmpfile_linkable(const char *target, int flags, char **ret_path) { if (fd < 0) return -errno; - *ret_path = tmp; - tmp = NULL; + *ret_path = TAKE_PTR(tmp); return fd; } @@ -1519,8 +1517,7 @@ int read_nul_string(FILE *f, char **ret) { return -ENOMEM; } - *ret = x; - x = NULL; + *ret = TAKE_PTR(x); return 0; } diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index c65ba4bfe5..150c47a719 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -458,10 +458,8 @@ int get_files_in_directory(const char *path, char ***list) { n++; } - if (list) { - *list = l; - l = NULL; /* avoid freeing */ - } + if (list) + *list = TAKE_PTR(l); return n; } @@ -732,8 +730,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, } safe_close(fd); - fd = fd_parent; - fd_parent = -1; + fd = TAKE_FD(fd_parent); continue; } @@ -838,10 +835,9 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, } /* If this is not a symlink, then let's just add the name we read to what we already verified. */ - if (!done) { - done = first; - first = NULL; - } else { + if (!done) + done = TAKE_PTR(first); + else { /* If done is "/", as first also contains slash at the head, then remove this redundant slash. */ if (streq(done, "/")) *done = '\0'; @@ -852,8 +848,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, /* And iterate again, but go one directory further down. */ safe_close(fd); - fd = child; - child = -1; + fd = TAKE_FD(child); } if (!done) { @@ -863,22 +858,15 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, return -ENOMEM; } - if (ret) { - *ret = done; - done = NULL; - } + if (ret) + *ret = TAKE_PTR(done); if (flags & CHASE_OPEN) { - int q; - /* Return the O_PATH fd we currently are looking to the caller. It can translate it to a proper fd by * opening /proc/self/fd/xyz. */ assert(fd >= 0); - q = fd; - fd = -1; - - return q; + return TAKE_FD(fd); } return exists; diff --git a/src/basic/locale-util.c b/src/basic/locale-util.c index 266cb29936..de3d7c8c89 100644 --- a/src/basic/locale-util.c +++ b/src/basic/locale-util.c @@ -341,8 +341,7 @@ int get_keymaps(char ***ret) { strv_sort(l); - *ret = l; - l = NULL; + *ret = TAKE_PTR(l); return 0; } diff --git a/src/basic/memfd-util.c b/src/basic/memfd-util.c index e7eb895462..758ba6458a 100644 --- a/src/basic/memfd-util.c +++ b/src/basic/memfd-util.c @@ -168,8 +168,5 @@ int memfd_new_and_map(const char *name, size_t sz, void **p) { if (r < 0) return r; - r = fd; - fd = -1; - - return r; + return TAKE_FD(fd); } diff --git a/src/basic/mkdir-label.c b/src/basic/mkdir-label.c index 6f3a46f467..2a44d276cb 100644 --- a/src/basic/mkdir-label.c +++ b/src/basic/mkdir-label.c @@ -47,8 +47,8 @@ int mkdir_label(const char *path, mode_t mode) { return mac_smack_fix(path, false, false); } -int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink) { - return mkdir_safe_internal(path, mode, uid, gid, follow_symlink, mkdir_label); +int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags) { + return mkdir_safe_internal(path, mode, uid, gid, flags, mkdir_label); } int mkdir_parents_label(const char *path, mode_t mode) { diff --git a/src/basic/mkdir.c b/src/basic/mkdir.c index de4746c867..cb6495525c 100644 --- a/src/basic/mkdir.c +++ b/src/basic/mkdir.c @@ -29,9 +29,10 @@ #include "mkdir.h" #include "path-util.h" #include "stat-util.h" +#include "stdio-util.h" #include "user-util.h" -int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink, mkdir_func_t _mkdir) { +int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdir_func_t _mkdir) { struct stat st; int r; @@ -46,26 +47,47 @@ int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, boo if (lstat(path, &st) < 0) return -errno; - if (follow_symlink && S_ISLNK(st.st_mode)) { + if ((flags & MKDIR_FOLLOW_SYMLINK) && S_ISLNK(st.st_mode)) { _cleanup_free_ char *p = NULL; r = chase_symlinks(path, NULL, CHASE_NONEXISTENT, &p); if (r < 0) return r; if (r == 0) - return mkdir_safe_internal(p, mode, uid, gid, false, _mkdir); + return mkdir_safe_internal(p, mode, uid, gid, + flags & ~MKDIR_FOLLOW_SYMLINK, + _mkdir); if (lstat(p, &st) < 0) return -errno; } + if (!S_ISDIR(st.st_mode)) { + log_full(flags & MKDIR_WARN_MODE ? LOG_WARNING : LOG_DEBUG, + "Path \"%s\" already exists and is not a directory, refusing.", path); + return -ENOTDIR; + } if ((st.st_mode & 0007) > (mode & 0007) || (st.st_mode & 0070) > (mode & 0070) || - (st.st_mode & 0700) > (mode & 0700) || - (uid != UID_INVALID && st.st_uid != uid) || - (gid != GID_INVALID && st.st_gid != gid) || - !S_ISDIR(st.st_mode)) + (st.st_mode & 0700) > (mode & 0700)) { + 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.", + path, st.st_mode & 0777, mode); return -EEXIST; + } + if ((uid != UID_INVALID && st.st_uid != uid) || + (gid != GID_INVALID && st.st_gid != gid)) { + char u[DECIMAL_STR_MAX(uid_t)] = "-", g[DECIMAL_STR_MAX(gid_t)] = "-"; + + if (uid != UID_INVALID) + xsprintf(u, UID_FMT, uid); + if (gid != UID_INVALID) + xsprintf(g, GID_FMT, gid); + 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.", + path, st.st_uid, st.st_gid, u, g); + return -EEXIST; + } return 0; } @@ -76,8 +98,8 @@ int mkdir_errno_wrapper(const char *pathname, mode_t mode) { return 0; } -int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink) { - return mkdir_safe_internal(path, mode, uid, gid, follow_symlink, mkdir_errno_wrapper); +int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags) { + return mkdir_safe_internal(path, mode, uid, gid, flags, mkdir_errno_wrapper); } int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir) { diff --git a/src/basic/mkdir.h b/src/basic/mkdir.h index d6c2d579a3..59d0fb6d81 100644 --- a/src/basic/mkdir.h +++ b/src/basic/mkdir.h @@ -23,18 +23,23 @@ #include <sys/types.h> +typedef enum MkdirFlags { + MKDIR_FOLLOW_SYMLINK = 1 << 0, + MKDIR_WARN_MODE = 1 << 1, +} MkdirFlags; + int mkdir_errno_wrapper(const char *pathname, mode_t mode); -int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink); +int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags); int mkdir_parents(const char *path, mode_t mode); int mkdir_p(const char *path, mode_t mode); /* mandatory access control(MAC) versions */ -int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink); +int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags); int mkdir_parents_label(const char *path, mode_t mode); int mkdir_p_label(const char *path, mode_t mode); /* internally used */ typedef int (*mkdir_func_t)(const char *pathname, mode_t mode); -int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink, mkdir_func_t _mkdir); +int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdir_func_t _mkdir); int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir); int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir); diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c index 8151b3a4e4..b6e7c94017 100644 --- a/src/basic/mount-util.c +++ b/src/basic/mount-util.c @@ -81,10 +81,8 @@ int name_to_handle_at_loop( if (name_to_handle_at(fd, path, h, &mnt_id, flags) >= 0) { - if (ret_handle) { - *ret_handle = h; - h = NULL; - } + if (ret_handle) + *ret_handle = TAKE_PTR(h); if (ret_mnt_id) *ret_mnt_id = mnt_id; @@ -951,8 +949,7 @@ int mount_option_mangle( } *ret_mount_flags = mount_flags; - *ret_remaining_options = ret; - ret = NULL; + *ret_remaining_options = TAKE_PTR(ret); return 0; } diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c index fa5b4a353a..eacd5ba360 100644 --- a/src/basic/parse-util.c +++ b/src/basic/parse-util.c @@ -324,8 +324,7 @@ int parse_syscall_and_errno(const char *in, char **name, int *error) { return -EINVAL; *error = e; - *name = n; - n = NULL; + *name = TAKE_PTR(n); return 0; } @@ -371,12 +370,13 @@ finish: } -int safe_atou(const char *s, unsigned *ret_u) { +int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) { char *x = NULL; unsigned long l; assert(s); assert(ret_u); + assert(base <= 16); /* strtoul() is happy to parse negative values, and silently * converts them to unsigned values without generating an @@ -389,7 +389,7 @@ int safe_atou(const char *s, unsigned *ret_u) { s += strspn(s, WHITESPACE); errno = 0; - l = strtoul(s, &x, 0); + l = strtoul(s, &x, base); if (errno > 0) return -errno; if (!x || x == s || *x != 0) @@ -487,17 +487,18 @@ int safe_atou8(const char *s, uint8_t *ret) { return 0; } -int safe_atou16(const char *s, uint16_t *ret) { +int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) { char *x = NULL; unsigned long l; assert(s); assert(ret); + assert(base <= 16); s += strspn(s, WHITESPACE); errno = 0; - l = strtoul(s, &x, 0); + l = strtoul(s, &x, base); if (errno > 0) return -errno; if (!x || x == s || *x != 0) @@ -531,30 +532,6 @@ int safe_atoi16(const char *s, int16_t *ret) { return 0; } -int safe_atoux16(const char *s, uint16_t *ret) { - char *x = NULL; - unsigned long l; - - assert(s); - assert(ret); - - s += strspn(s, WHITESPACE); - - errno = 0; - l = strtoul(s, &x, 16); - if (errno > 0) - return -errno; - if (!x || x == s || *x != 0) - return -EINVAL; - if (s[0] == '-') - return -ERANGE; - if ((unsigned long) (uint16_t) l != l) - return -ERANGE; - - *ret = (uint16_t) l; - return 0; -} - int safe_atod(const char *s, double *ret_d) { _cleanup_(freelocalep) locale_t loc = (locale_t) 0; char *x = NULL; diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h index 727422056a..1605cc4ff5 100644 --- a/src/basic/parse-util.h +++ b/src/basic/parse-util.h @@ -44,17 +44,29 @@ int parse_syscall_and_errno(const char *in, char **name, int *error); #define FORMAT_BYTES_MAX 8 char *format_bytes(char *buf, size_t l, uint64_t t); -int safe_atou(const char *s, unsigned *ret_u); +int safe_atou_full(const char *s, unsigned base, unsigned *ret_u); + +static inline int safe_atou(const char *s, unsigned *ret_u) { + return safe_atou_full(s, 0, ret_u); +} + int safe_atoi(const char *s, int *ret_i); int safe_atollu(const char *s, unsigned long long *ret_u); int safe_atolli(const char *s, long long int *ret_i); int safe_atou8(const char *s, uint8_t *ret); -int safe_atou16(const char *s, uint16_t *ret); -int safe_atoi16(const char *s, int16_t *ret); +int safe_atou16_full(const char *s, unsigned base, uint16_t *ret); -int safe_atoux16(const char *s, uint16_t *ret); +static inline int safe_atou16(const char *s, uint16_t *ret) { + return safe_atou16_full(s, 0, ret); +} + +static inline int safe_atoux16(const char *s, uint16_t *ret) { + return safe_atou16_full(s, 16, ret); +} + +int safe_atoi16(const char *s, int16_t *ret); static inline int safe_atou32(const char *s, uint32_t *ret_u) { assert_cc(sizeof(uint32_t) == sizeof(unsigned)); diff --git a/src/basic/path-util.c b/src/basic/path-util.c index df94629385..d4c4a02cb3 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -290,8 +290,7 @@ char **path_strv_resolve(char **l, const char *root) { r = chase_symlinks(t, root, 0, &u); if (r == -ENOENT) { if (root) { - u = orig; - orig = NULL; + u = TAKE_PTR(orig); free(t); } else u = t; diff --git a/src/basic/proc-cmdline.c b/src/basic/proc-cmdline.c index c5d1fb1d41..c51e3c0a3b 100644 --- a/src/basic/proc-cmdline.c +++ b/src/basic/proc-cmdline.c @@ -204,10 +204,8 @@ int proc_cmdline_get_key(const char *key, unsigned flags, char **value) { } } - if (value) { - *value = ret; - ret = NULL; - } + if (value) + *value = TAKE_PTR(ret); return found; } diff --git a/src/basic/process-util.c b/src/basic/process-util.c index 853e0e3449..2583b310a4 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -623,8 +623,7 @@ int get_process_environ(pid_t pid, char **env) { } else outcome[sz] = '\0'; - *env = outcome; - outcome = NULL; + *env = TAKE_PTR(outcome); return 0; } diff --git a/src/basic/securebits-util.c b/src/basic/securebits-util.c index 441d386f9e..75675bf4c0 100644 --- a/src/basic/securebits-util.c +++ b/src/basic/securebits-util.c @@ -48,8 +48,7 @@ int secure_bits_to_string_alloc(int i, char **s) { if (len != 0) str[len - 1] = '\0'; - *s = str; - str = NULL; + *s = TAKE_PTR(str); return 0; } diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index b91b093132..fd26ae7137 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -985,8 +985,7 @@ int getpeersec(int fd, char **ret) { if (isempty(s)) return -EOPNOTSUPP; - *ret = s; - s = NULL; + *ret = TAKE_PTR(s); return 0; } diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c index 3689f6e983..67705947aa 100644 --- a/src/basic/stat-util.c +++ b/src/basic/stat-util.c @@ -254,7 +254,8 @@ int fd_is_network_ns(int fd) { if (r <= 0) return r; - if (ioctl(fd, NS_GET_NSTYPE) < 0) + r = ioctl(fd, NS_GET_NSTYPE); + if (r < 0) return -errno; return r == CLONE_NEWNET; diff --git a/src/basic/strv.c b/src/basic/strv.c index e80ff4a62c..8010016451 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -341,8 +341,7 @@ int strv_split_extract(char ***t, const char *s, const char *separators, Extract if (!GREEDY_REALLOC(l, allocated, n + 2)) return -ENOMEM; - l[n++] = word; - word = NULL; + l[n++] = TAKE_PTR(word); l[n] = NULL; } @@ -353,8 +352,7 @@ int strv_split_extract(char ***t, const char *s, const char *separators, Extract return -ENOMEM; } - *t = l; - l = NULL; + *t = TAKE_PTR(l); return (int) n; } diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index eacfd14677..c7e2d2abb7 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -496,10 +496,7 @@ int acquire_terminal( fd = safe_close(fd); } - r = fd; - fd = -1; - - return r; + return TAKE_FD(fd); } int release_terminal(void) { @@ -707,10 +704,9 @@ int vtnr_from_tty(const char *tty) { tty = active; } - if (tty == active) { - *ret = active; - active = NULL; - } else { + if (tty == active) + *ret = TAKE_PTR(active); + else { char *tmp; tmp = strdup(tty); @@ -778,8 +774,7 @@ int get_kernel_consoles(char ***ret) { goto fallback; } - *ret = l; - l = NULL; + *ret = TAKE_PTR(l); return 0; @@ -788,8 +783,7 @@ fallback: if (r < 0) return r; - *ret = l; - l = NULL; + *ret = TAKE_PTR(l); return 0; } diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c index 0fa0472ee1..7d9367334b 100644 --- a/src/basic/unit-name.c +++ b/src/basic/unit-name.c @@ -363,8 +363,7 @@ int unit_name_unescape(const char *f, char **ret) { *t = 0; - *ret = r; - r = NULL; + *ret = TAKE_PTR(r); return 0; } @@ -569,28 +568,32 @@ int unit_name_to_path(const char *name, char **ret) { return unit_name_path_unescape(prefix, ret); } -static char *do_escape_mangle(const char *f, UnitNameMangle allow_globs, char *t) { +static bool do_escape_mangle(const char *f, bool allow_globs, char *t) { const char *valid_chars; + bool mangled = false; assert(f); - assert(IN_SET(allow_globs, UNIT_NAME_GLOB, UNIT_NAME_NOGLOB)); assert(t); - /* We'll only escape the obvious characters here, to play - * safe. */ + /* We'll only escape the obvious characters here, to play safe. + * + * Returns true if any characters were mangled, false otherwise. + */ - valid_chars = allow_globs == UNIT_NAME_GLOB ? VALID_CHARS_GLOB : VALID_CHARS_WITH_AT; + valid_chars = allow_globs ? VALID_CHARS_GLOB : VALID_CHARS_WITH_AT; - for (; *f; f++) { - if (*f == '/') + for (; *f; f++) + if (*f == '/') { *(t++) = '-'; - else if (!strchr(valid_chars, *f)) + mangled = true; + } else if (!strchr(valid_chars, *f)) { t = do_escape_char(*f, t); - else + mangled = true; + } else *(t++) = *f; - } + *t = 0; - return t; + return mangled; } /** @@ -600,9 +603,10 @@ static char *do_escape_mangle(const char *f, UnitNameMangle allow_globs, char *t * * If @allow_globs, globs characters are preserved. Otherwise, they are escaped. */ -int unit_name_mangle_with_suffix(const char *name, UnitNameMangle allow_globs, const char *suffix, char **ret) { - char *s, *t; +int unit_name_mangle_with_suffix(const char *name, UnitNameMangle flags, const char *suffix, char **ret) { + char *s; int r; + bool mangled; assert(name); assert(suffix); @@ -619,7 +623,7 @@ int unit_name_mangle_with_suffix(const char *name, UnitNameMangle allow_globs, c goto good; /* Already a fully valid globbing expression? If so, no mangling is necessary either... */ - if (allow_globs == UNIT_NAME_GLOB && + if ((flags & UNIT_NAME_MANGLE_GLOB) && string_is_glob(name) && in_charset(name, VALID_CHARS_GLOB)) goto good; @@ -644,13 +648,16 @@ int unit_name_mangle_with_suffix(const char *name, UnitNameMangle allow_globs, c if (!s) return -ENOMEM; - t = do_escape_mangle(name, allow_globs, s); - *t = 0; + mangled = do_escape_mangle(name, flags & UNIT_NAME_MANGLE_GLOB, s); + if (mangled) + log_full(flags & UNIT_NAME_MANGLE_WARN ? LOG_NOTICE : LOG_DEBUG, + "Invalid unit name \"%s\" was escaped as \"%s\" (maybe you should use systemd-escape?)", + name, s); /* Append a suffix if it doesn't have any, but only if this is not a glob, so that we can allow "foo.*" as a * valid glob. */ - if ((allow_globs != UNIT_NAME_GLOB || !string_is_glob(s)) && unit_name_to_type(s) < 0) - strcpy(t, suffix); + if ((!(flags & UNIT_NAME_MANGLE_GLOB) || !string_is_glob(s)) && unit_name_to_type(s) < 0) + strcat(s, suffix); *ret = s; return 1; diff --git a/src/basic/unit-name.h b/src/basic/unit-name.h index b47327dcaf..278d1378f7 100644 --- a/src/basic/unit-name.h +++ b/src/basic/unit-name.h @@ -68,14 +68,14 @@ int unit_name_from_path_instance(const char *prefix, const char *path, const cha int unit_name_to_path(const char *name, char **ret); typedef enum UnitNameMangle { - UNIT_NAME_NOGLOB, - UNIT_NAME_GLOB, + UNIT_NAME_MANGLE_GLOB = 1, + UNIT_NAME_MANGLE_WARN = 2, } UnitNameMangle; -int unit_name_mangle_with_suffix(const char *name, UnitNameMangle allow_globs, const char *suffix, char **ret); +int unit_name_mangle_with_suffix(const char *name, UnitNameMangle flags, const char *suffix, char **ret); -static inline int unit_name_mangle(const char *name, UnitNameMangle allow_globs, char **ret) { - return unit_name_mangle_with_suffix(name, allow_globs, ".service", ret); +static inline int unit_name_mangle(const char *name, UnitNameMangle flags, char **ret) { + return unit_name_mangle_with_suffix(name, flags, ".service", ret); } int slice_build_parent_slice(const char *slice, char **ret); diff --git a/src/basic/user-util.c b/src/basic/user-util.c index ceb71b61e8..0f750be65f 100644 --- a/src/basic/user-util.c +++ b/src/basic/user-util.c @@ -734,3 +734,123 @@ bool synthesize_nobody(void) { return cache; #endif } + +int putpwent_sane(const struct passwd *pw, FILE *stream) { + assert(pw); + assert(stream); + + errno = 0; + if (putpwent(pw, stream) != 0) + return errno > 0 ? -errno : -EIO; + + return 0; +} + +int putspent_sane(const struct spwd *sp, FILE *stream) { + assert(sp); + assert(stream); + + errno = 0; + if (putspent(sp, stream) != 0) + return errno > 0 ? -errno : -EIO; + + return 0; +} + +int putgrent_sane(const struct group *gr, FILE *stream) { + assert(gr); + assert(stream); + + errno = 0; + if (putgrent(gr, stream) != 0) + return errno > 0 ? -errno : -EIO; + + return 0; +} + +#if ENABLE_GSHADOW +int putsgent_sane(const struct sgrp *sg, FILE *stream) { + assert(sg); + assert(stream); + + errno = 0; + if (putsgent(sg, stream) != 0) + return errno > 0 ? -errno : -EIO; + + return 0; +} +#endif + +int fgetpwent_sane(FILE *stream, struct passwd **pw) { + struct passwd *p; + + assert(pw); + assert(stream); + + errno = 0; + p = fgetpwent(stream); + if (p == NULL) { + if (errno == ENOENT) + return false; + return errno > 0 ? -errno : -EIO; + } + + *pw = p; + return true; +} + +int fgetspent_sane(FILE *stream, struct spwd **sp) { + struct spwd *s; + + assert(sp); + assert(stream); + + errno = 0; + s = fgetspent(stream); + if (s == NULL) { + if (errno == ENOENT) + return false; + return errno > 0 ? -errno : -EIO; + } + + *sp = s; + return true; +} + +int fgetgrent_sane(FILE *stream, struct group **gr) { + struct group *g; + + assert(gr); + assert(stream); + + errno = 0; + g = fgetgrent(stream); + if (g == NULL) { + if (errno == ENOENT) + return false; + return errno > 0 ? -errno : -EIO; + } + + *gr = g; + return true; +} + +#if ENABLE_GSHADOW +int fgetsgent_sane(FILE *stream, struct sgrp **sg) { + struct sgrp *s; + + assert(sg); + assert(stream); + + errno = 0; + s = fgetsgent(stream); + if (s == NULL) { + if (errno == ENOENT) + return false; + return errno > 0 ? -errno : -EIO; + } + + *sg = s; + return true; +} +#endif diff --git a/src/basic/user-util.h b/src/basic/user-util.h index e1259a1582..66a22ac88f 100644 --- a/src/basic/user-util.h +++ b/src/basic/user-util.h @@ -20,6 +20,10 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <grp.h> +#include <gshadow.h> +#include <pwd.h> +#include <shadow.h> #include <stdbool.h> #include <stdint.h> #include <sys/types.h> @@ -110,3 +114,14 @@ static inline bool valid_shell(const char *p) { int maybe_setgroups(size_t size, const gid_t *list); bool synthesize_nobody(void); + +int fgetpwent_sane(FILE *stream, struct passwd **pw); +int fgetspent_sane(FILE *stream, struct spwd **sp); +int fgetgrent_sane(FILE *stream, struct group **gr); +int putpwent_sane(const struct passwd *pw, FILE *stream); +int putspent_sane(const struct spwd *sp, FILE *stream); +int putgrent_sane(const struct group *gr, FILE *stream); +#ifdef ENABLE_GSHADOW +int fgetsgent_sane(FILE *stream, struct sgrp **sg); +int putsgent_sane(const struct sgrp *sg, FILE *stream); +#endif diff --git a/src/basic/virt.c b/src/basic/virt.c index 39b4a98d89..8a7d71d4b4 100644 --- a/src/basic/virt.c +++ b/src/basic/virt.c @@ -367,7 +367,7 @@ int detect_vm(void) { * because we're not an x86 guest), then we should try the /proc/xen * directory next. If that's not found, then we check for the high-level * hypervisor sysfs file. - */ + */ r = detect_vm_xen(); if (r < 0) diff --git a/src/busctl/busctl-introspect.c b/src/busctl/busctl-introspect.c index 54d6e07d2c..cce68a480b 100644 --- a/src/busctl/busctl-introspect.c +++ b/src/busctl/busctl-introspect.c @@ -275,10 +275,9 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth free(node_path); - if (name[0] == '/') { - node_path = name; - name = NULL; - } else { + if (name[0] == '/') + node_path = TAKE_PTR(name); + else { if (endswith(prefix, "/")) node_path = strappend(prefix, name); diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 65ed86580f..62a3d86ef1 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -1381,8 +1381,7 @@ int unit_set_cgroup_path(Unit *u, const char *path) { unit_release_cgroup(u); - u->cgroup_path = p; - p = NULL; + u->cgroup_path = TAKE_PTR(p); return 1; } diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 635213a866..7344623ebf 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -424,10 +424,8 @@ static int property_get_syscall_filter( if (r < 0) return -ENOMEM; } - } else { - s = name; - name = NULL; - } + } else + s = TAKE_PTR(name); r = strv_consume(&l, s); if (r < 0) @@ -1125,8 +1123,7 @@ int bus_set_transient_exec_command( return -ENOMEM; } - c->argv = argv; - argv = NULL; + c->argv = TAKE_PTR(argv); c->flags = b ? EXEC_COMMAND_IGNORE_FAILURE : 0; diff --git a/src/core/dbus-job.c b/src/core/dbus-job.c index 0802fc9773..15d0e5dd8b 100644 --- a/src/core/dbus-job.c +++ b/src/core/dbus-job.c @@ -274,8 +274,7 @@ int bus_job_coldplug_bus_track(Job *j) { assert(j); - deserialized_clients = j->deserialized_clients; - j->deserialized_clients = NULL; + deserialized_clients = TAKE_PTR(j->deserialized_clients); if (strv_isempty(deserialized_clients)) return 0; diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index 6de905b69c..587d9b5f9e 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -354,7 +354,8 @@ static int bus_service_set_transient_property( if (streq(name, "SuccessExitStatus")) return bus_set_transient_exit_status(u, name, &s->success_status, message, flags, error); - if ((ci = service_exec_command_from_string(name)) >= 0) + ci = service_exec_command_from_string(name); + if (ci >= 0) return bus_set_transient_exec_command(u, name, &s->exec_command[ci], message, flags, error); if (streq(name, "StandardInputFileDescriptor")) diff --git a/src/core/dbus.c b/src/core/dbus.c index 56b43adcda..eb9ec44f5b 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -501,8 +501,7 @@ static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char assert(hashmap_size(m->jobs) == k); - *nodes = l; - l = NULL; + *nodes = TAKE_PTR(l); return k; } @@ -526,8 +525,7 @@ static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, cha k++; } - *nodes = l; - l = NULL; + *nodes = TAKE_PTR(l); return k; } diff --git a/src/core/device.c b/src/core/device.c index b0dd469fd1..66bfc30b5f 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -296,7 +296,7 @@ static int device_add_udev_wants(Unit *u, struct udev_device *dev) { } else { /* If this is not a template, then let's mangle it so, that it becomes a valid unit name. */ - r = unit_name_mangle(word, UNIT_NAME_NOGLOB, &k); + r = unit_name_mangle(word, UNIT_NAME_MANGLE_WARN, &k); if (r < 0) return log_unit_error_errno(u, r, "Failed to mangle unit name \"%s\": %m", word); } diff --git a/src/core/dynamic-user.c b/src/core/dynamic-user.c index de6aadd597..7236dcfabd 100644 --- a/src/core/dynamic-user.c +++ b/src/core/dynamic-user.c @@ -319,10 +319,7 @@ static int pick_uid(char **suggested_paths, const char *name, uid_t *ret_uid) { (void) make_uid_symlinks(candidate, name, true); /* also add direct lookup symlinks */ *ret_uid = candidate; - r = lock_fd; - lock_fd = -1; - - return r; + return TAKE_FD(lock_fd); next: ; @@ -770,8 +767,7 @@ int dynamic_user_lookup_uid(Manager *m, uid_t uid, char **ret) { if (check_uid != uid) /* lock file doesn't match our own idea */ return -ESRCH; - *ret = user; - user = NULL; + *ret = TAKE_PTR(user); return 0; } diff --git a/src/core/execute.c b/src/core/execute.c index 7292b815db..56e0eec205 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1733,8 +1733,7 @@ static int build_environment( our_env[n_env++] = NULL; assert(n_env <= 12); - *ret = our_env; - our_env = NULL; + *ret = TAKE_PTR(our_env); return 0; } @@ -1763,8 +1762,7 @@ static int build_pass_environment(const ExecContext *c, char ***ret) { x = NULL; } - *ret = pass_env; - pass_env = NULL; + *ret = TAKE_PTR(pass_env); return 0; } @@ -2051,7 +2049,7 @@ static int setup_exec_directory( } /* First set up private root if it doesn't exist yet, with access mode 0700 and owned by root:root */ - r = mkdir_safe_label(private_root, 0700, 0, 0, false); + r = mkdir_safe_label(private_root, 0700, 0, 0, MKDIR_WARN_MODE); if (r < 0) goto fail; @@ -2290,9 +2288,7 @@ static int compile_bind_mounts( *ret_bind_mounts = bind_mounts; *ret_n_bind_mounts = n; - *ret_empty_directories = empty_directories; - - empty_directories = NULL; + *ret_empty_directories = TAKE_PTR(empty_directories); return (int) n; @@ -2696,8 +2692,7 @@ static int compile_suggested_paths(const ExecContext *c, const ExecParameters *p } } - *ret = list; - list = NULL; + *ret = TAKE_PTR(list); return 0; } diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 94605ab0d0..887eb1cf49 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -1248,8 +1248,7 @@ int config_parse_exec_cpu_affinity(const char *unit, } if (!c->cpuset) { - c->cpuset = cpuset; - cpuset = NULL; + c->cpuset = TAKE_PTR(cpuset); c->cpuset_ncpus = (unsigned) ncpus; return 0; } @@ -1257,8 +1256,7 @@ int config_parse_exec_cpu_affinity(const char *unit, if (c->cpuset_ncpus < (unsigned) ncpus) { CPU_OR_S(CPU_ALLOC_SIZE(c->cpuset_ncpus), cpuset, c->cpuset, cpuset); CPU_FREE(c->cpuset); - c->cpuset = cpuset; - cpuset = NULL; + c->cpuset = TAKE_PTR(cpuset); c->cpuset_ncpus = (unsigned) ncpus; return 0; } @@ -2089,8 +2087,7 @@ int config_parse_user_group( return -ENOEXEC; } - n = k; - k = NULL; + n = TAKE_PTR(k); } free(*user); @@ -2320,10 +2317,8 @@ int config_parse_environ( "Failed to resolve specifiers, ignoring: %s", word); continue; } - } else { - k = word; - word = NULL; - } + } else + k = TAKE_PTR(word); if (!env_assignment_is_valid(k)) { log_syntax(unit, LOG_ERR, filename, line, 0, @@ -2390,10 +2385,8 @@ int config_parse_pass_environ( "Failed to resolve specifiers, ignoring: %s", word); continue; } - } else { - k = word; - word = NULL; - } + } else + k = TAKE_PTR(word); if (!env_name_is_valid(k)) { log_syntax(unit, LOG_ERR, filename, line, 0, @@ -2469,10 +2462,8 @@ int config_parse_unset_environ( "Failed to resolve specifiers, ignoring: %s", word); continue; } - } else { - k = word; - word = NULL; - } + } else + k = TAKE_PTR(word); if (!env_assignment_is_valid(k) && !env_name_is_valid(k)) { log_syntax(unit, LOG_ERR, filename, line, 0, @@ -3515,8 +3506,7 @@ int config_parse_device_allow( if (!a) return log_oom(); - a->path = path; - path = NULL; + a->path = TAKE_PTR(path); a->r = !!strchr(m, 'r'); a->w = !!strchr(m, 'w'); a->m = !!strchr(m, 'm'); @@ -3615,8 +3605,7 @@ int config_parse_io_device_weight( if (!w) return log_oom(); - w->path = path; - path = NULL; + w->path = TAKE_PTR(path); w->weight = u; @@ -3701,8 +3690,7 @@ int config_parse_io_limit( if (!l) return log_oom(); - l->path = path; - path = NULL; + l->path = TAKE_PTR(path); for (ttype = 0; ttype < _CGROUP_IO_LIMIT_TYPE_MAX; ttype++) l->limits[ttype] = cgroup_io_limit_defaults[ttype]; @@ -3804,8 +3792,7 @@ int config_parse_blockio_device_weight( if (!w) return log_oom(); - w->path = path; - path = NULL; + w->path = TAKE_PTR(path); w->weight = u; @@ -3885,8 +3872,7 @@ int config_parse_blockio_bandwidth( if (!b) return log_oom(); - b->path = path; - path = NULL; + b->path = TAKE_PTR(path); b->rbps = CGROUP_LIMIT_MAX; b->wbps = CGROUP_LIMIT_MAX; diff --git a/src/core/main.c b/src/core/main.c index a4d2cdf759..7ee3faabf4 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -127,6 +127,7 @@ static char *arg_watchdog_device = NULL; static char **arg_default_environment = NULL; static struct rlimit *arg_default_rlimit[_RLIMIT_MAX] = {}; static uint64_t arg_capability_bounding_set = CAP_ALL; +static bool arg_no_new_privs = false; static nsec_t arg_timer_slack_nsec = NSEC_INFINITY; static usec_t arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE; static Set* arg_syscall_archs = NULL; @@ -671,6 +672,7 @@ static int parse_config_file(void) { { "Manager", "ShutdownWatchdogSec", config_parse_sec, 0, &arg_shutdown_watchdog }, { "Manager", "WatchdogDevice", config_parse_path, 0, &arg_watchdog_device }, { "Manager", "CapabilityBoundingSet", config_parse_capability_set, 0, &arg_capability_bounding_set }, + { "Manager", "NoNewPrivileges", config_parse_bool, 0, &arg_no_new_privs }, #if HAVE_SECCOMP { "Manager", "SystemCallArchitectures", config_parse_syscall_archs, 0, &arg_syscall_archs }, #endif @@ -1865,6 +1867,13 @@ static int initialize_runtime( } } + if (arg_system && arg_no_new_privs) { + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) { + *ret_error_message = "Failed to disable new privileges"; + return log_emergency_errno(errno, "Failed to disable new privileges: %m"); + } + } + if (arg_syscall_archs) { r = enforce_syscall_archs(arg_syscall_archs); if (r < 0) { diff --git a/src/core/manager.c b/src/core/manager.c index 7026a58d73..e67f7446c7 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -844,8 +844,7 @@ static int manager_setup_notify(Manager *m) { if (r < 0) return log_error_errno(errno, "SO_PASSCRED failed: %m"); - m->notify_fd = fd; - fd = -1; + m->notify_fd = TAKE_FD(fd); log_debug("Using notification socket %s", m->notify_socket); } @@ -1671,6 +1670,42 @@ Unit *manager_get_unit(Manager *m, const char *name) { return hashmap_get(m->units, name); } +static int manager_dispatch_target_deps_queue(Manager *m) { + Unit *u; + unsigned k; + int r = 0; + + static const UnitDependency deps[] = { + UNIT_REQUIRED_BY, + UNIT_REQUISITE_OF, + UNIT_WANTED_BY, + UNIT_BOUND_BY + }; + + assert(m); + + while ((u = m->target_deps_queue)) { + assert(u->in_target_deps_queue); + + LIST_REMOVE(target_deps_queue, u->manager->target_deps_queue, u); + u->in_target_deps_queue = false; + + for (k = 0; k < ELEMENTSOF(deps); k++) { + Unit *target; + Iterator i; + void *v; + + HASHMAP_FOREACH_KEY(v, target, u->dependencies[deps[k]], i) { + r = unit_add_default_target_dependency(u, target); + if (r < 0) + return r; + } + } + } + + return r; +} + unsigned manager_dispatch_load_queue(Manager *m) { Unit *u; unsigned n = 0; @@ -1694,6 +1729,11 @@ unsigned manager_dispatch_load_queue(Manager *m) { } m->dispatching_load_queue = false; + + /* Dispatch the units waiting for their target dependencies to be added now, as all targets that we know about + * should be loaded and have aliases resolved */ + (void) manager_dispatch_target_deps_queue(m); + return n; } diff --git a/src/core/manager.h b/src/core/manager.h index 80304a4010..28c5da225b 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -144,6 +144,9 @@ struct Manager { /* Units whose cgroup ran empty */ LIST_HEAD(Unit, cgroup_empty_queue); + /* Target units whose default target dependencies haven't been set yet */ + LIST_HEAD(Unit, target_deps_queue); + sd_event *event; /* This maps PIDs we care about to units that are interested in. We allow multiple units to he interested in diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c index 9c27972aff..b7d654619c 100644 --- a/src/core/mount-setup.c +++ b/src/core/mount-setup.c @@ -315,10 +315,8 @@ int mount_cgroup_controllers(char ***join_controllers) { options = strv_join(*k, ","); if (!options) return log_oom(); - } else { - options = controller; - controller = NULL; - } + } else + options = TAKE_PTR(controller); where = strappend("/sys/fs/cgroup/", options); if (!where) diff --git a/src/core/service.c b/src/core/service.c index 5c66876c8f..a39c95da55 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -2554,8 +2554,7 @@ static int service_deserialize_exec_command(Unit *u, const char *key, const char state = STATE_EXEC_COMMAND_PATH; break; case STATE_EXEC_COMMAND_PATH: - path = arg; - arg = NULL; + path = TAKE_PTR(arg); state = STATE_EXEC_COMMAND_ARGS; if (!path_is_absolute(path)) diff --git a/src/core/socket.c b/src/core/socket.c index b3c09f67c0..eecf6fbe18 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -1238,10 +1238,7 @@ static int fifo_address_create( goto fail; } - r = fd; - fd = -1; - - return r; + return TAKE_FD(fd); fail: mac_selinux_create_file_clear(); @@ -1251,7 +1248,6 @@ fail: static int special_address_create(const char *path, bool writable) { _cleanup_close_ int fd = -1; struct stat st; - int r; assert(path); @@ -1266,16 +1262,12 @@ static int special_address_create(const char *path, bool writable) { if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) return -EEXIST; - r = fd; - fd = -1; - - return r; + return TAKE_FD(fd); } static int usbffs_address_create(const char *path) { _cleanup_close_ int fd = -1; struct stat st; - int r; assert(path); @@ -1290,10 +1282,7 @@ static int usbffs_address_create(const char *path) { if (!S_ISREG(st.st_mode)) return -EEXIST; - r = fd; - fd = -1; - - return r; + return TAKE_FD(fd); } static int mq_address_create( @@ -1306,7 +1295,6 @@ static int mq_address_create( struct stat st; mode_t old_mask; struct mq_attr _attr, *attr = NULL; - int r; assert(path); @@ -1338,10 +1326,7 @@ static int mq_address_create( st.st_gid != getgid()) return -EEXIST; - r = fd; - fd = -1; - - return r; + return TAKE_FD(fd); } static int socket_symlink(Socket *s) { diff --git a/src/core/system.conf.in b/src/core/system.conf.in index 08cbe529ba..f0a59a79a5 100644 --- a/src/core/system.conf.in +++ b/src/core/system.conf.in @@ -27,6 +27,7 @@ #RuntimeWatchdogSec=0 #ShutdownWatchdogSec=10min #CapabilityBoundingSet= +#NoNewPrivileges=no #SystemCallArchitectures= #TimerSlackNSec= #DefaultTimerAccuracySec=1min diff --git a/src/core/unit.c b/src/core/unit.c index 52851b6ffc..72f475ab14 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -649,6 +649,9 @@ void unit_free(Unit *u) { if (u->in_cleanup_queue) LIST_REMOVE(cleanup_queue, u->manager->cleanup_queue, u); + if (u->in_target_deps_queue) + LIST_REMOVE(target_deps_queue, u->manager->target_deps_queue, u); + safe_close(u->ip_accounting_ingress_map_fd); safe_close(u->ip_accounting_egress_map_fd); @@ -709,10 +712,8 @@ static int set_complete_move(Set **s, Set **other) { if (*s) return set_move(*s, *other); - else { - *s = *other; - *other = NULL; - } + else + *s = TAKE_PTR(*other); return 0; } @@ -726,10 +727,8 @@ static int hashmap_complete_move(Hashmap **s, Hashmap **other) { if (*s) return hashmap_move(*s, *other); - else { - *s = *other; - *other = NULL; - } + else + *s = TAKE_PTR(*other); return 0; } @@ -1342,6 +1341,18 @@ int unit_load_fragment_and_dropin_optional(Unit *u) { return unit_load_dropin(unit_follow_merge(u)); } +void unit_add_to_target_deps_queue(Unit *u) { + Manager *m = u->manager; + + assert(u); + + if (u->in_target_deps_queue) + return; + + LIST_PREPEND(target_deps_queue, m->target_deps_queue, u); + u->in_target_deps_queue = true; +} + int unit_add_default_target_dependency(Unit *u, Unit *target) { assert(u); assert(target); @@ -1368,35 +1379,6 @@ int unit_add_default_target_dependency(Unit *u, Unit *target) { return unit_add_dependency(target, UNIT_AFTER, u, true, UNIT_DEPENDENCY_DEFAULT); } -static int unit_add_target_dependencies(Unit *u) { - - static const UnitDependency deps[] = { - UNIT_REQUIRED_BY, - UNIT_REQUISITE_OF, - UNIT_WANTED_BY, - UNIT_BOUND_BY - }; - - unsigned k; - int r = 0; - - assert(u); - - for (k = 0; k < ELEMENTSOF(deps); k++) { - Unit *target; - Iterator i; - void *v; - - HASHMAP_FOREACH_KEY(v, target, u->dependencies[deps[k]], i) { - r = unit_add_default_target_dependency(u, target); - if (r < 0) - return r; - } - } - - return r; -} - static int unit_add_slice_dependencies(Unit *u) { UnitDependencyMask mask; assert(u); @@ -1525,10 +1507,7 @@ int unit_load(Unit *u) { } if (u->load_state == UNIT_LOADED) { - - r = unit_add_target_dependencies(u); - if (r < 0) - goto fail; + unit_add_to_target_deps_queue(u); r = unit_add_slice_dependencies(u); if (r < 0) @@ -4017,8 +3996,7 @@ static int user_from_unit_name(Unit *u, char **ret) { return r; if (valid_user_group_name(n)) { - *ret = n; - n = NULL; + *ret = TAKE_PTR(n); return 0; } @@ -4220,7 +4198,7 @@ char* unit_escape_setting(const char *s, UnitWriteFlags flags, char **buf) { char* unit_concat_strv(char **l, UnitWriteFlags flags) { _cleanup_free_ char *result = NULL; size_t n = 0, allocated = 0; - char **i, *ret; + char **i; /* Takes a list of strings, escapes them, and concatenates them. This may be used to format command lines in a * way suitable for ExecStart= stanzas */ @@ -4255,10 +4233,7 @@ char* unit_concat_strv(char **l, UnitWriteFlags flags) { result[n] = 0; - ret = result; - result = NULL; - - return ret; + return TAKE_PTR(result); } int unit_write_setting(Unit *u, UnitWriteFlags flags, const char *name, const char *data) { diff --git a/src/core/unit.h b/src/core/unit.h index e9370a4b93..9f50d81cc8 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -231,6 +231,9 @@ struct Unit { /* cgroup empty queue */ LIST_FIELDS(Unit, cgroup_empty_queue); + /* Target dependencies queue */ + LIST_FIELDS(Unit, target_deps_queue); + /* PIDs we keep an eye on. Note that a unit might have many * more, but these are the ones we care enough about to * process SIGCHLD for */ @@ -336,6 +339,7 @@ struct Unit { bool in_gc_queue:1; bool in_cgroup_realize_queue:1; bool in_cgroup_empty_queue:1; + bool in_target_deps_queue:1; bool sent_dbus_new_signal:1; @@ -632,6 +636,7 @@ void unit_add_to_load_queue(Unit *u); void unit_add_to_dbus_queue(Unit *u); void unit_add_to_cleanup_queue(Unit *u); void unit_add_to_gc_queue(Unit *u); +void unit_add_to_target_deps_queue(Unit *u); int unit_merge(Unit *u, Unit *other); int unit_merge_by_name(Unit *u, const char *other); diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c index e924750d1b..6fbfe58bd6 100644 --- a/src/coredump/coredump.c +++ b/src/coredump/coredump.c @@ -584,8 +584,7 @@ static int compose_open_fds(pid_t pid, char **open_fds) { if (errno > 0) return -errno; - *open_fds = buffer; - buffer = NULL; + *open_fds = TAKE_PTR(buffer); return 0; } diff --git a/src/coredump/coredumpctl.c b/src/coredump/coredumpctl.c index 62bcbb6be3..b0a00cda37 100644 --- a/src/coredump/coredumpctl.c +++ b/src/coredump/coredumpctl.c @@ -764,8 +764,7 @@ static int save_core(sd_journal *j, FILE *file, char **path, bool *unlink_temp) return log_error_errno(errno, "File \"%s\" is not readable: %m", filename); if (path && !endswith(filename, ".xz") && !endswith(filename, ".lz4")) { - *path = filename; - filename = NULL; + *path = TAKE_PTR(filename); return 0; } @@ -1073,8 +1072,7 @@ int main(int argc, char *argv[]) { end: pager_close(); - if (arg_output) - fclose(arg_output); + safe_fclose(arg_output); return r >= 0 ? r : EXIT_FAILURE; } diff --git a/src/coredump/stacktrace.c b/src/coredump/stacktrace.c index 95fd27b79a..ec39fb8499 100644 --- a/src/coredump/stacktrace.c +++ b/src/coredump/stacktrace.c @@ -184,8 +184,7 @@ int coredump_make_stack_trace(int fd, const char *executable, char **ret) { c.f = safe_fclose(c.f); - *ret = buf; - buf = NULL; + *ret = TAKE_PTR(buf); r = 0; diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index 7255ff418c..69bbf525fe 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -402,8 +402,7 @@ static int get_password(const char *vol, const char *src, usec_t until, bool acc *p = c; } - *ret = passwords; - passwords = NULL; + *ret = TAKE_PTR(passwords); return 0; } diff --git a/src/debug-generator/debug-generator.c b/src/debug-generator/debug-generator.c index 61c890d05a..cd0507ced6 100644 --- a/src/debug-generator/debug-generator.c +++ b/src/debug-generator/debug-generator.c @@ -45,7 +45,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat if (proc_cmdline_value_missing(key, value)) return 0; - r = unit_name_mangle(value, UNIT_NAME_NOGLOB, &n); + r = unit_name_mangle(value, UNIT_NAME_MANGLE_WARN, &n); if (r < 0) return log_error_errno(r, "Failed to glob unit name: %m"); @@ -59,7 +59,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat if (proc_cmdline_value_missing(key, value)) return 0; - r = unit_name_mangle(value, UNIT_NAME_NOGLOB, &n); + r = unit_name_mangle(value, UNIT_NAME_MANGLE_WARN, &n); if (r < 0) return log_error_errno(r, "Failed to glob unit name: %m"); diff --git a/src/environment-d-generator/environment-d-generator.c b/src/environment-d-generator/environment-d-generator.c index bb4d76da90..9c16a60e2e 100644 --- a/src/environment-d-generator/environment-d-generator.c +++ b/src/environment-d-generator/environment-d-generator.c @@ -45,8 +45,7 @@ static int environment_dirs(char ***ret) { if (r < 0) return r; - *ret = dirs; - dirs = NULL; + *ret = TAKE_PTR(dirs); return 0; } diff --git a/src/escape/escape.c b/src/escape/escape.c index 9c35b4663e..2eb0a58673 100644 --- a/src/escape/escape.c +++ b/src/escape/escape.c @@ -217,7 +217,7 @@ int main(int argc, char *argv[]) { break; case ACTION_MANGLE: - r = unit_name_mangle(*i, UNIT_NAME_NOGLOB, &e); + r = unit_name_mangle(*i, 0, &e); if (r < 0) { log_error_errno(r, "Failed to mangle name: %m"); goto finish; diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c index 3d8a59029d..a1f7e226f8 100644 --- a/src/firstboot/firstboot.c +++ b/src/firstboot/firstboot.c @@ -20,7 +20,6 @@ #include <fcntl.h> #include <getopt.h> -#include <shadow.h> #include <unistd.h> #ifdef HAVE_CRYPT_H @@ -576,8 +575,7 @@ static int prompt_root_password(void) { continue; } - arg_root_password = a; - a = NULL; + arg_root_password = TAKE_PTR(a); break; } @@ -586,6 +584,8 @@ static int prompt_root_password(void) { static int write_root_shadow(const char *path, const struct spwd *p) { _cleanup_fclose_ FILE *f = NULL; + int r; + assert(path); assert(p); @@ -594,9 +594,9 @@ static int write_root_shadow(const char *path, const struct spwd *p) { if (!f) return -errno; - errno = 0; - if (putspent(p, f) != 0) - return errno > 0 ? -errno : -EIO; + r = putspent_sane(p, f); + if (r < 0) + return r; return fflush_sync_and_check(f); } diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index fc58cba64f..20c457e60c 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -237,7 +237,7 @@ static int write_dependency(FILE *f, const char *opts, STRV_FOREACH(s, names) { char *x; - r = unit_name_mangle_with_suffix(*s, UNIT_NAME_NOGLOB, ".mount", &x); + r = unit_name_mangle_with_suffix(*s, 0, ".mount", &x); if (r < 0) return log_error_errno(r, "Failed to generate unit name: %m"); r = strv_consume(&units, x); diff --git a/src/fuzz/fuzz-unit-file.c b/src/fuzz/fuzz-unit-file.c index 44c68db64d..4865653f5b 100644 --- a/src/fuzz/fuzz-unit-file.c +++ b/src/fuzz/fuzz-unit-file.c @@ -41,11 +41,14 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { for (;;) { _cleanup_free_ char *l = NULL; + const char *ll; if (read_line(f, LINE_MAX, &l) <= 0) break; - if (startswith(l, "ListenNetlink=")) + ll = l + strspn(l, WHITESPACE); + + if (startswith(ll, "ListenNetlink=")) /* ListenNetlink causes a false positive in msan, * let's skip this for now. */ return 0; diff --git a/src/import/export-raw.c b/src/import/export-raw.c index eaa6d10915..9cab838b96 100644 --- a/src/import/export-raw.c +++ b/src/import/export-raw.c @@ -326,13 +326,10 @@ int raw_export_start(RawExport *e, const char *path, int fd, ImportCompressType /* Try to take a reflink snapshot of the file, if we can t make the export atomic */ tfd = reflink_snapshot(sfd, path); - if (tfd >= 0) { - e->input_fd = tfd; - tfd = -1; - } else { - e->input_fd = sfd; - sfd = -1; - } + if (tfd >= 0) + e->input_fd = TAKE_FD(tfd); + else + e->input_fd = TAKE_FD(sfd); r = import_compress_init(&e->compress, compress); if (r < 0) diff --git a/src/import/import-common.c b/src/import/import-common.c index a3dc1dde8c..b9d8c23905 100644 --- a/src/import/import-common.c +++ b/src/import/import-common.c @@ -117,13 +117,9 @@ int import_fork_tar_x(const char *path, pid_t *ret) { _exit(EXIT_FAILURE); } - pipefd[0] = safe_close(pipefd[0]); - r = pipefd[1]; - pipefd[1] = -1; - *ret = pid; - return r; + return TAKE_FD(pipefd[1]); } int import_fork_tar_c(const char *path, pid_t *ret) { @@ -165,11 +161,7 @@ int import_fork_tar_c(const char *path, pid_t *ret) { _exit(EXIT_FAILURE); } - pipefd[1] = safe_close(pipefd[1]); - r = pipefd[0]; - pipefd[0] = -1; - *ret = pid; - return r; + return TAKE_FD(pipefd[0]); } diff --git a/src/import/import-raw.c b/src/import/import-raw.c index f117c94da2..032b3dcda2 100644 --- a/src/import/import-raw.c +++ b/src/import/import-raw.c @@ -210,8 +210,7 @@ static int raw_import_maybe_convert_qcow2(RawImport *i) { free_and_replace(i->temp_path, t); safe_close(i->output_fd); - i->output_fd = converted_fd; - converted_fd = -1; + i->output_fd = TAKE_FD(converted_fd); return 1; } diff --git a/src/import/importd.c b/src/import/importd.c index 10f52c7fc1..55e61b485f 100644 --- a/src/import/importd.c +++ b/src/import/importd.c @@ -453,8 +453,7 @@ static int transfer_start(Transfer *t) { } pipefd[1] = safe_close(pipefd[1]); - t->log_fd = pipefd[0]; - pipefd[0] = -1; + t->log_fd = TAKE_FD(pipefd[0]); t->stdin_fd = safe_close(t->stdin_fd); @@ -1083,8 +1082,7 @@ static int transfer_node_enumerator(sd_bus *bus, const char *path, void *userdat k++; } - *nodes = l; - l = NULL; + *nodes = TAKE_PTR(l); return 1; } diff --git a/src/import/pull-common.c b/src/import/pull-common.c index 7651870bf0..92f2692c81 100644 --- a/src/import/pull-common.c +++ b/src/import/pull-common.c @@ -124,8 +124,7 @@ int pull_find_old_etags( return r; } - *etags = l; - l = NULL; + *etags = TAKE_PTR(l); return 0; } diff --git a/src/import/pull-raw.c b/src/import/pull-raw.c index 880cb84ba8..9784141871 100644 --- a/src/import/pull-raw.c +++ b/src/import/pull-raw.c @@ -272,8 +272,7 @@ static int raw_pull_maybe_convert_qcow2(RawPull *i) { free_and_replace(i->temp_path, t); safe_close(i->raw_job->disk_fd); - i->raw_job->disk_fd = converted_fd; - converted_fd = -1; + i->raw_job->disk_fd = TAKE_FD(converted_fd); return 1; } diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c index 73329ba024..b6adf64c27 100644 --- a/src/journal/journal-send.c +++ b/src/journal/journal-send.c @@ -441,9 +441,7 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve if (r < 0) return r; - r = fd; - fd = -1; - return r; + return TAKE_FD(fd); } _public_ int sd_journal_print_with_location(int priority, const char *file, const char *line, const char *func, const char *format, ...) { diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 3c9c6df07d..e8eb9ac161 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1539,7 +1539,7 @@ static int add_units(sd_journal *j) { STRV_FOREACH(i, arg_system_units) { _cleanup_free_ char *u = NULL; - r = unit_name_mangle(*i, UNIT_NAME_GLOB, &u); + r = unit_name_mangle(*i, UNIT_NAME_MANGLE_GLOB | (arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN), &u); if (r < 0) return r; @@ -1584,7 +1584,7 @@ static int add_units(sd_journal *j) { STRV_FOREACH(i, arg_user_units) { _cleanup_free_ char *u = NULL; - r = unit_name_mangle(*i, UNIT_NAME_GLOB, &u); + r = unit_name_mangle(*i, UNIT_NAME_MANGLE_GLOB | (arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN), &u); if (r < 0) return r; diff --git a/src/journal/mmap-cache.c b/src/journal/mmap-cache.c index 630ae6fbac..91ed3cd519 100644 --- a/src/journal/mmap-cache.c +++ b/src/journal/mmap-cache.c @@ -220,8 +220,7 @@ static void context_detach_window(Context *c) { if (!c->window) return; - w = c->window; - c->window = NULL; + w = TAKE_PTR(c->window); LIST_REMOVE(by_window, w->contexts, c); if (!w->contexts && !w->keep_always) { diff --git a/src/journal/test-journal.c b/src/journal/test-journal.c index 3b9917b4a8..f90b7e4375 100644 --- a/src/journal/test-journal.c +++ b/src/journal/test-journal.c @@ -200,7 +200,7 @@ static bool check_compressed(uint64_t compress_threshold, uint64_t data_size) { /* We have to partially reimplement some of the dump logic, because the normal next_entry does the * decompression for us. */ p = le64toh(f->header->header_size); - while (true) { + for (;;) { r = journal_file_move_to_object(f, OBJECT_UNUSED, p, &o); assert_se(r == 0); if (o->object.type == OBJECT_DATA) diff --git a/src/libsystemd-network/arp-util.c b/src/libsystemd-network/arp-util.c index b8e9b2e496..3217ac0d1f 100644 --- a/src/libsystemd-network/arp-util.c +++ b/src/libsystemd-network/arp-util.c @@ -103,10 +103,7 @@ int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_ if (r < 0) return -errno; - r = s; - s = -1; - - return r; + return TAKE_FD(s); } static int arp_send_packet(int fd, int ifindex, diff --git a/src/libsystemd-network/dhcp-network.c b/src/libsystemd-network/dhcp-network.c index 602bf08a60..ac9a7a31b6 100644 --- a/src/libsystemd-network/dhcp-network.c +++ b/src/libsystemd-network/dhcp-network.c @@ -123,10 +123,7 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link, if (r < 0) return -errno; - r = s; - s = -1; - - return r; + return TAKE_FD(s); } int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link, @@ -211,10 +208,7 @@ int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port) { if (r < 0) return -errno; - r = s; - s = -1; - - return r; + return TAKE_FD(s); } int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link, diff --git a/src/libsystemd-network/dhcp-option.c b/src/libsystemd-network/dhcp-option.c index 0489579e7f..142e39bc66 100644 --- a/src/libsystemd-network/dhcp-option.c +++ b/src/libsystemd-network/dhcp-option.c @@ -253,10 +253,8 @@ int dhcp_option_parse(DHCPMessage *message, size_t len, dhcp_option_callback_t c if (message_type == 0) return -ENOMSG; - if (_error_message && IN_SET(message_type, DHCP_NAK, DHCP_DECLINE)) { - *_error_message = error_message; - error_message = NULL; - } + if (_error_message && IN_SET(message_type, DHCP_NAK, DHCP_DECLINE)) + *_error_message = TAKE_PTR(error_message); return message_type; } diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h index 8b5620e138..f2ffb39e44 100644 --- a/src/libsystemd-network/dhcp-server-internal.h +++ b/src/libsystemd-network/dhcp-server-internal.h @@ -86,6 +86,7 @@ typedef struct DHCPRequest { } DHCPRequest; #define log_dhcp_server(client, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCP SERVER: " fmt, ##__VA_ARGS__) +#define log_dhcp_server_errno(client, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "DHCP SERVER: " fmt, ##__VA_ARGS__) int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, size_t length); diff --git a/src/libsystemd-network/dhcp6-network.c b/src/libsystemd-network/dhcp6-network.c index b3b8fddbcb..70f5909304 100644 --- a/src/libsystemd-network/dhcp6-network.c +++ b/src/libsystemd-network/dhcp6-network.c @@ -67,9 +67,7 @@ int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) { if (r < 0) return -errno; - r = s; - s = -1; - return r; + return TAKE_FD(s); } int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address, diff --git a/src/libsystemd-network/dhcp6-option.c b/src/libsystemd-network/dhcp6-option.c index df96ad739d..2b3c8ceb59 100644 --- a/src/libsystemd-network/dhcp6-option.c +++ b/src/libsystemd-network/dhcp6-option.c @@ -617,8 +617,7 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char * idx++; } - *str_arr = names; - names = NULL; + *str_arr = TAKE_PTR(names); return idx; diff --git a/src/libsystemd-network/icmp6-util.c b/src/libsystemd-network/icmp6-util.c index dd4e28bfd9..2347251572 100644 --- a/src/libsystemd-network/icmp6-util.c +++ b/src/libsystemd-network/icmp6-util.c @@ -98,9 +98,7 @@ static int icmp6_bind_router_message(const struct icmp6_filter *filter, if (r < 0) return -errno; - r = s; - s = -1; - return r; + return TAKE_FD(s); } int icmp6_bind_router_solicitation(int index) { diff --git a/src/libsystemd-network/lldp-network.c b/src/libsystemd-network/lldp-network.c index cb3841ef22..c653813cfb 100644 --- a/src/libsystemd-network/lldp-network.c +++ b/src/libsystemd-network/lldp-network.c @@ -92,8 +92,5 @@ int lldp_network_bind_raw_socket(int ifindex) { if (r < 0) return -errno; - r = fd; - fd = -1; - - return r; + return TAKE_FD(fd); } diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c index 584a1f36ac..00a56c8206 100644 --- a/src/libsystemd-network/network-internal.c +++ b/src/libsystemd-network/network-internal.c @@ -276,10 +276,9 @@ int config_parse_ifalias(const char *unit, } free(*s); - if (*n) { - *s = n; - n = NULL; - } else + if (*n) + *s = TAKE_PTR(n); + else *s = NULL; return 0; @@ -437,8 +436,7 @@ int deserialize_in_addrs(struct in_addr **ret, const char *string) { size++; } - *ret = addresses; - addresses = NULL; + *ret = TAKE_PTR(addresses); return size; } @@ -491,8 +489,7 @@ int deserialize_in6_addrs(struct in6_addr **ret, const char *string) { size++; } - *ret = addresses; - addresses = NULL; + *ret = TAKE_PTR(addresses); return size; } @@ -585,8 +582,7 @@ int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_size = size; *ret_allocated = allocated; - *ret = routes; - routes = NULL; + *ret = TAKE_PTR(routes); return 0; } diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 2e88e39878..9db0a93898 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -807,8 +807,7 @@ int dhcp_lease_parse_search_domains(const uint8_t *option, size_t len, char ***d pos = next_chunk; } - *domains = names; - names = NULL; + *domains = TAKE_PTR(names); return cnt; } diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index d64a47d2fc..25f5b378bc 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -313,7 +313,6 @@ static int dhcp_server_send_udp(sd_dhcp_server *server, be32_t destination, }; struct cmsghdr *cmsg; struct in_pktinfo *pktinfo; - int r; assert(server); assert(server->fd >= 0); @@ -337,8 +336,7 @@ static int dhcp_server_send_udp(sd_dhcp_server *server, be32_t destination, pktinfo->ipi_ifindex = server->ifindex; pktinfo->ipi_spec_dst.s_addr = server->address; - r = sendmsg(server->fd, &msg, 0); - if (r < 0) + if (sendmsg(server->fd, &msg, 0) < 0) return -errno; return 0; @@ -778,8 +776,9 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, if (!server->bound_leases[next_offer]) { address = server->subnet | htobe32(server->pool_offset + next_offer); break; - } else - next_offer = (next_offer + 1) % server->pool_size; + } + + next_offer = (next_offer + 1) % server->pool_size; } } @@ -788,18 +787,12 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, return 0; r = server_send_offer(server, req, address); - if (r < 0) { + if (r < 0) /* this only fails on critical errors */ - log_dhcp_server(server, "could not send offer: %s", - strerror(-r)); - return r; - } else { - log_dhcp_server(server, "OFFER (0x%x)", - be32toh(req->message->xid)); - return DHCP_OFFER; - } + return log_dhcp_server_errno(server, r, "Could not send offer: %m"); - break; + log_dhcp_server(server, "OFFER (0x%x)", be32toh(req->message->xid)); + return DHCP_OFFER; } case DHCP_DECLINE: log_dhcp_server(server, "DECLINE (0x%x): %s", be32toh(req->message->xid), strna(error_message)); @@ -899,8 +892,7 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, r = server_send_ack(server, req, address); if (r < 0) { /* this only fails on critical errors */ - log_dhcp_server(server, "could not send ack: %s", - strerror(-r)); + log_dhcp_server_errno(server, r, "Could not send ack: %m"); if (!existing_lease) dhcp_lease_free(lease); @@ -916,18 +908,15 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, return DHCP_ACK; } + } else if (init_reboot) { r = server_send_nak(server, req); - if (r < 0) { + if (r < 0) /* this only fails on critical errors */ - log_dhcp_server(server, "could not send nak: %s", - strerror(-r)); - return r; - } else { - log_dhcp_server(server, "NAK (0x%x)", - be32toh(req->message->xid)); - return DHCP_NAK; - } + return log_dhcp_server_errno(server, r, "Could not send nak: %m"); + + log_dhcp_server(server, "NAK (0x%x)", be32toh(req->message->xid)); + return DHCP_NAK; } break; @@ -953,12 +942,10 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, server->bound_leases[pool_offset] = NULL; hashmap_remove(server->leases_by_client_id, existing_lease); dhcp_lease_free(existing_lease); + } - return 1; - } else - return 0; - } - } + return 0; + }} return 0; } @@ -977,6 +964,7 @@ static int server_receive_message(sd_event_source *s, int fd, }; struct cmsghdr *cmsg; ssize_t buflen, len; + int r; assert(server); @@ -997,7 +985,8 @@ static int server_receive_message(sd_event_source *s, int fd, return 0; return -errno; - } else if ((size_t)len < sizeof(DHCPMessage)) + } + if ((size_t)len < sizeof(DHCPMessage)) return 0; CMSG_FOREACH(cmsg, &msg) { @@ -1015,7 +1004,11 @@ static int server_receive_message(sd_event_source *s, int fd, } } - return dhcp_server_handle_message(server, message, (size_t)len); + r = dhcp_server_handle_message(server, message, (size_t) len); + if (r < 0) + log_dhcp_server_errno(server, r, "Couldn't process incoming message: %m"); + + return 0; } int sd_dhcp_server_start(sd_dhcp_server *server) { @@ -1024,8 +1017,8 @@ int sd_dhcp_server_start(sd_dhcp_server *server) { assert_return(server, -EINVAL); assert_return(server->event, -EINVAL); assert_return(!server->receive_message, -EBUSY); - assert_return(server->fd_raw == -1, -EBUSY); - assert_return(server->fd == -1, -EBUSY); + assert_return(server->fd_raw < 0, -EBUSY); + assert_return(server->fd < 0, -EBUSY); assert_return(server->address != htobe32(INADDR_ANY), -EUNATCH); r = socket(AF_PACKET, SOCK_DGRAM | SOCK_NONBLOCK, 0); @@ -1081,8 +1074,8 @@ int sd_dhcp_server_forcerenew(sd_dhcp_server *server) { lease->chaddr); if (r < 0) return r; - else - log_dhcp_server(server, "FORCERENEW"); + + log_dhcp_server(server, "FORCERENEW"); } return r; diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c index 6e00255b20..08015a99ef 100644 --- a/src/libsystemd/sd-bus/bus-objects.c +++ b/src/libsystemd/sd-bus/bus-objects.c @@ -1470,8 +1470,7 @@ static struct node *bus_node_allocate(sd_bus *bus, const char *path) { return NULL; n->parent = parent; - n->path = s; - s = NULL; /* do not free */ + n->path = TAKE_PTR(s); r = hashmap_put(bus->nodes, n->path, n); if (r < 0) { diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 2f5e483ae2..8c022fce1b 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -1342,8 +1342,7 @@ int bus_set_address_user(sd_bus *b) { if (asprintf(&s, DEFAULT_USER_BUS_ADDRESS_FMT, ee) < 0) return -ENOMEM; - b->address = s; - s = NULL; + b->address = TAKE_PTR(s); return 0; } diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c index 1334498ca4..0da0ca5890 100644 --- a/src/libsystemd/sd-daemon/sd-daemon.c +++ b/src/libsystemd/sd-daemon/sd-daemon.c @@ -141,8 +141,7 @@ _public_ int sd_listen_fds_with_names(int unset_environment, char ***names) { return r; } - *names = l; - l = NULL; + *names = TAKE_PTR(l); return n_fds; } diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index 1297dfa911..fd2821b1a7 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -1297,8 +1297,7 @@ int device_get_id_filename(sd_device *device, const char **ret) { } } - device->id_filename = id; - id = NULL; + device->id_filename = TAKE_PTR(id); } *ret = device->id_filename; diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c index 6601bcd6be..2a4eede9f8 100644 --- a/src/libsystemd/sd-login/sd-login.c +++ b/src/libsystemd/sd-login/sd-login.c @@ -325,8 +325,7 @@ _public_ int sd_uid_get_display(uid_t uid, char **session) { if (isempty(s)) return -ENODATA; - *session = s; - s = NULL; + *session = TAKE_PTR(s); return 0; } @@ -355,8 +354,7 @@ static int file_of_seat(const char *seat, char **_p) { if (!p) return -ENOMEM; - *_p = p; - p = NULL; + *_p = TAKE_PTR(p); return 0; } @@ -529,8 +527,7 @@ _public_ int sd_session_get_state(const char *session, char **state) { if (isempty(s)) return -EIO; - *state = s; - s = NULL; + *state = TAKE_PTR(s); return 0; } @@ -575,8 +572,7 @@ static int session_get_string(const char *session, const char *field, char **val if (isempty(s)) return -ENODATA; - *value = s; - s = NULL; + *value = TAKE_PTR(s); return 0; } @@ -681,10 +677,8 @@ _public_ int sd_seat_get_active(const char *seat, char **session, uid_t *uid) { return r; } - if (session && s) { - *session = s; - s = NULL; - } + if (session && s) + *session = TAKE_PTR(s); return 0; } @@ -909,10 +903,9 @@ _public_ int sd_get_machine_names(char ***machines) { *b = NULL; } - if (machines) { - *machines = l; - l = NULL; - } + if (machines) + *machines = TAKE_PTR(l); + return r; } @@ -933,8 +926,7 @@ _public_ int sd_machine_get_class(const char *machine, char **class) { if (!c) return -EIO; - *class = c; - c = NULL; + *class = TAKE_PTR(c); return 0; } diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index af3d13edcd..3a5f9346aa 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -803,8 +803,7 @@ static int netlink_container_parse(sd_netlink_message *m, attributes[type].net_byteorder = RTA_FLAGS(rta) & NLA_F_NET_BYTEORDER; } - container->attributes = attributes; - attributes = NULL; + container->attributes = TAKE_PTR(attributes); container->n_attributes = count; return 0; diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c index 8f4814019e..1d3e9b30f5 100644 --- a/src/libsystemd/sd-network/sd-network.c +++ b/src/libsystemd/sd-network/sd-network.c @@ -51,8 +51,7 @@ _public_ int sd_network_get_operational_state(char **state) { if (isempty(s)) return -ENODATA; - *state = s; - s = NULL; + *state = TAKE_PTR(s); return 0; } @@ -81,8 +80,7 @@ static int network_get_strv(const char *key, char ***ret) { strv_uniq(a); r = strv_length(a); - *ret = a; - a = NULL; + *ret = TAKE_PTR(a); return r; } @@ -121,8 +119,7 @@ static int network_link_get_string(int ifindex, const char *field, char **ret) { if (isempty(s)) return -ENODATA; - *ret = s; - s = NULL; + *ret = TAKE_PTR(s); return 0; } @@ -154,8 +151,7 @@ static int network_link_get_strv(int ifindex, const char *key, char ***ret) { strv_uniq(a); r = strv_length(a); - *ret = a; - a = NULL; + *ret = TAKE_PTR(a); return r; } @@ -263,8 +259,7 @@ static int network_link_get_ifindexes(int ifindex, const char *key, int **ret) { if (ifis) ifis[c] = 0; /* Let's add a 0 ifindex to the end, to be nice */ - *ret = ifis; - ifis = NULL; + *ret = TAKE_PTR(ifis); return c; } diff --git a/src/libudev/libudev-enumerate.c b/src/libudev/libudev-enumerate.c index 271880075e..a366ab16be 100644 --- a/src/libudev/libudev-enumerate.c +++ b/src/libudev/libudev-enumerate.c @@ -69,7 +69,6 @@ struct udev_enumerate { **/ _public_ struct udev_enumerate *udev_enumerate_new(struct udev *udev) { _cleanup_free_ struct udev_enumerate *udev_enumerate = NULL; - struct udev_enumerate *ret; int r; assert_return_errno(udev, NULL, EINVAL); @@ -97,10 +96,7 @@ _public_ struct udev_enumerate *udev_enumerate_new(struct udev *udev) { udev_list_init(udev, &udev_enumerate->devices_list, false); - ret = udev_enumerate; - udev_enumerate = NULL; - - return ret; + return TAKE_PTR(udev_enumerate); } /** diff --git a/src/locale/keymap-util.c b/src/locale/keymap-util.c index 2d788106bb..393e9b5648 100644 --- a/src/locale/keymap-util.c +++ b/src/locale/keymap-util.c @@ -278,8 +278,7 @@ int locale_write_data(Context *c, char ***settings) { if (r < 0) return r; - *settings = l; - l = NULL; + *settings = TAKE_PTR(l); return 0; } @@ -539,8 +538,7 @@ int find_converted_keymap(const char *x11_layout, const char *x11_variant, char log_debug("Found converted keymap %s at %s", n, uncompressed ? p : pz); - *new_keymap = n; - n = NULL; + *new_keymap = TAKE_PTR(n); return 1; } } diff --git a/src/login/logind-core.c b/src/login/logind-core.c index 41b4d4d8d7..8c022cf0f1 100644 --- a/src/login/logind-core.c +++ b/src/login/logind-core.c @@ -282,7 +282,7 @@ int manager_process_button_device(Manager *m, struct udev_device *d) { return 0; } -int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) { +int manager_get_session_by_pid(Manager *m, pid_t pid, Session **ret) { _cleanup_free_ char *unit = NULL; Session *s; int r; @@ -294,38 +294,51 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) { r = cg_pid_get_unit(pid, &unit); if (r < 0) - return 0; + goto not_found; s = hashmap_get(m->session_units, unit); if (!s) - return 0; + goto not_found; + + if (ret) + *ret = s; - if (session) - *session = s; return 1; + +not_found: + if (ret) + *ret = NULL; + return 0; } -int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) { +int manager_get_user_by_pid(Manager *m, pid_t pid, User **ret) { _cleanup_free_ char *unit = NULL; User *u; int r; assert(m); - assert(user); if (!pid_is_valid(pid)) return -EINVAL; r = cg_pid_get_slice(pid, &unit); if (r < 0) - return 0; + goto not_found; u = hashmap_get(m->user_units, unit); if (!u) - return 0; + goto not_found; + + if (ret) + *ret = u; - *user = u; return 1; + +not_found: + if (ret) + *ret = NULL; + + return 0; } int manager_get_idle_hint(Manager *m, dual_timestamp *t) { diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index ef5c478fef..7dc8c5a340 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -658,10 +658,9 @@ static int method_list_inhibitors(sd_bus_message *message, void *userdata, sd_bu static int method_create_session(sd_bus_message *message, void *userdata, sd_bus_error *error) { const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop; - uint32_t audit_id = 0; - _cleanup_free_ char *unit = NULL; - _cleanup_free_ char *id = NULL; + _cleanup_free_ char *unit = NULL, *id = NULL; Session *session = NULL; + uint32_t audit_id = 0; Manager *m = userdata; User *user = NULL; Seat *seat = NULL; @@ -685,7 +684,7 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus if (!uid_is_valid(uid)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid UID"); - if (leader < 0 || leader == 1) + if (leader < 0 || leader == 1 || leader == getpid_cached()) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID"); if (isempty(type)) @@ -731,7 +730,7 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus if (v <= 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty); - if (!vtnr) + if (vtnr == 0) vtnr = (uint32_t) v; else if (vtnr != (uint32_t) v) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match"); @@ -749,7 +748,7 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus if (seat) { if (seat_has_vts(seat)) { - if (!vtnr || vtnr > 63) + if (vtnr <= 0 || vtnr > 63) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range"); } else { if (vtnr != 0) @@ -789,16 +788,13 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus return r; } - /* - * Check if we are already in a logind session. Or if we are in user@.service - * which is a special PAM session that avoids creating a logind session. - */ - r = cg_pid_get_unit(leader, &unit); + /* Check if we are already in a logind session. Or if we are in user@.service which is a special PAM session + * that avoids creating a logind session. */ + r = manager_get_user_by_pid(m, leader, NULL); if (r < 0) return r; - if (hashmap_get(m->session_units, unit) || - hashmap_get(m->user_units, unit)) - return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already running in a session"); + if (r > 0) + return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already running in a session or user slice"); /* * Old gdm and lightdm start the user-session on the same VT as @@ -832,9 +828,8 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus * the audit data and let's better register a new * ID */ if (hashmap_get(m->sessions, id)) { - log_warning("Existing logind session ID %s used by new audit session, ignoring", id); + log_warning("Existing logind session ID %s used by new audit session, ignoring.", id); audit_id = AUDIT_SESSION_INVALID; - id = mfree(id); } } @@ -926,8 +921,7 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus session->create_message = sd_bus_message_ref(message); - /* Now, let's wait until the slice unit and stuff got - * created. We send the reply back from + /* Now, let's wait until the slice unit and stuff got created. We send the reply back from * session_send_create_reply(). */ return 1; @@ -1225,7 +1219,7 @@ static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bu mkdir_p_label("/var/lib/systemd", 0755); - r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0, false); + r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0, MKDIR_WARN_MODE); if (r < 0) return r; @@ -1969,7 +1963,7 @@ static int update_schedule_file(Manager *m) { assert(m); - r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0, false); + r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0, MKDIR_WARN_MODE); if (r < 0) return log_error_errno(r, "Failed to create shutdown subdirectory: %m"); @@ -3094,13 +3088,8 @@ int manager_start_scope( return r; } - /* cgroup empty notification is not available in containers - * currently. To make this less problematic, let's shorten the - * stop timeout for sessions, so that we don't wait - * forever. */ - - /* Make sure that the session shells are terminated with - * SIGHUP since bash and friends tend to ignore SIGTERM */ + /* Make sure that the session shells are terminated with SIGHUP since bash and friends tend to ignore + * SIGTERM */ r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true); if (r < 0) return r; diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c index e14835292e..f814376e80 100644 --- a/src/login/logind-inhibit.c +++ b/src/login/logind-inhibit.c @@ -87,7 +87,7 @@ int inhibitor_save(Inhibitor *i) { assert(i); - r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0, false); + r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0, MKDIR_WARN_MODE); if (r < 0) goto fail; @@ -291,7 +291,7 @@ int inhibitor_create_fifo(Inhibitor *i) { /* Create FIFO */ if (!i->fifo_path) { - r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0, false); + r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0, MKDIR_WARN_MODE); if (r < 0) return r; diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c index 46e7c06ddc..ecca551db3 100644 --- a/src/login/logind-seat.c +++ b/src/login/logind-seat.c @@ -95,7 +95,7 @@ int seat_save(Seat *s) { if (!s->started) return 0; - r = mkdir_safe_label("/run/systemd/seats", 0755, 0, 0, false); + r = mkdir_safe_label("/run/systemd/seats", 0755, 0, 0, MKDIR_WARN_MODE); if (r < 0) goto fail; @@ -560,8 +560,7 @@ void seat_complete_switch(Seat *s) { if (!s->pending_switch) return; - session = s->pending_switch; - s->pending_switch = NULL; + session = TAKE_PTR(s->pending_switch); seat_set_active(s, session); } diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 1859150b5e..b5d90a70da 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -180,7 +180,7 @@ int session_save(Session *s) { if (!s->started) return 0; - r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0, false); + r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0, MKDIR_WARN_MODE); if (r < 0) goto fail; @@ -949,7 +949,7 @@ int session_create_fifo(Session *s) { /* Create FIFO */ if (!s->fifo_path) { - r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0, false); + r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0, MKDIR_WARN_MODE); if (r < 0) return r; @@ -1145,8 +1145,7 @@ void session_restore_vt(Session *s) { * little dance to avoid having the terminal be available * for reuse before we've cleaned it up. */ - old_fd = s->vtfd; - s->vtfd = -1; + old_fd = TAKE_FD(s->vtfd); vt = session_open_vt(s); safe_close(old_fd); @@ -1271,8 +1270,7 @@ int session_set_controller(Session *s, const char *sender, bool force, bool prep } session_release_controller(s, true); - s->controller = name; - name = NULL; + s->controller = TAKE_PTR(name); session_save(s); return 0; diff --git a/src/login/logind-user.c b/src/login/logind-user.c index f85564f221..dc8feacbf9 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -143,7 +143,7 @@ static int user_save_internal(User *u) { assert(u); assert(u->state_file); - r = mkdir_safe_label("/run/systemd/users", 0755, 0, 0, false); + r = mkdir_safe_label("/run/systemd/users", 0755, 0, 0, MKDIR_WARN_MODE); if (r < 0) goto fail; @@ -337,7 +337,7 @@ static int user_mkdir_runtime_path(User *u) { assert(u); - r = mkdir_safe_label("/run/user", 0755, 0, 0, false); + r = mkdir_safe_label("/run/user", 0755, 0, 0, MKDIR_WARN_MODE); if (r < 0) return log_error_errno(r, "Failed to create /run/user: %m"); diff --git a/src/login/logind.c b/src/login/logind.c index 95b29ae85e..6d3b7cee23 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -438,8 +438,7 @@ static int parse_fdname(const char *fdname, char **session_id, dev_t *dev) { return r; *dev = makedev(major, minor); - *session_id = id; - id = NULL; + *session_id = TAKE_PTR(id); return 0; } diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index 9c435d6715..fb053343c1 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -1475,8 +1475,7 @@ int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char return r; } - *nodes = l; - l = NULL; + *nodes = TAKE_PTR(l); return 1; } diff --git a/src/machine/machine.c b/src/machine/machine.c index 4bacf91d26..95eb590f73 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -131,7 +131,7 @@ int machine_save(Machine *m) { if (!m->started) return 0; - r = mkdir_safe_label("/run/systemd/machines", 0755, 0, 0, false); + r = mkdir_safe_label("/run/systemd/machines", 0755, 0, 0, MKDIR_WARN_MODE); if (r < 0) goto fail; diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c index dd139740c2..046def33ae 100644 --- a/src/mount/mount-tool.c +++ b/src/mount/mount-tool.c @@ -766,16 +766,14 @@ static int find_mount_points(const char *what, char ***list) { if (!GREEDY_REALLOC(l, bufsize, n + 2)) return log_oom(); - l[n++] = where; - where = NULL; + l[n++] = TAKE_PTR(where); } if (!GREEDY_REALLOC(l, bufsize, n + 1)) return log_oom(); l[n] = NULL; - *list = l; - l = NULL; /* avoid freeing */ + *list = TAKE_PTR(l); return n; } @@ -827,8 +825,7 @@ static int find_loop_device(const char *backing_file, char **loop_dev) { if (!l) return -ENXIO; - *loop_dev = l; - l = NULL; /* avoid freeing */ + *loop_dev = TAKE_PTR(l); return 0; } diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index 93648e1be0..421a32d567 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -488,8 +488,7 @@ int netdev_get_mac(const char *ifname, struct ether_addr **ret) { mac->ether_addr_octet[0] &= 0xfe; /* clear multicast bit */ mac->ether_addr_octet[0] |= 0x02; /* set local assignment bit (IEEE802) */ - *ret = mac; - mac = NULL; + *ret = TAKE_PTR(mac); return 0; } diff --git a/src/network/netdev/wireguard.c b/src/network/netdev/wireguard.c index f1f4bab475..9025693f70 100644 --- a/src/network/netdev/wireguard.c +++ b/src/network/netdev/wireguard.c @@ -228,8 +228,7 @@ static int on_resolve_retry(sd_event_source *s, usec_t usec, void *userdata) { w->resolve_retry_event_source = sd_event_source_unref(w->resolve_retry_event_source); - w->unresolved_endpoints = w->failed_endpoints; - w->failed_endpoints = NULL; + w->unresolved_endpoints = TAKE_PTR(w->failed_endpoints); resolve_endpoints(netdev); diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c index 2f4850b1a1..cc966fa363 100644 --- a/src/network/networkd-link-bus.c +++ b/src/network/networkd-link-bus.c @@ -82,8 +82,7 @@ int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char *** } l[c] = NULL; - *nodes = l; - l = NULL; + *nodes = TAKE_PTR(l); return 1; } diff --git a/src/network/networkd-network-bus.c b/src/network/networkd-network-bus.c index 8d3d7236fc..459868a57f 100644 --- a/src/network/networkd-network-bus.c +++ b/src/network/networkd-network-bus.c @@ -122,8 +122,7 @@ int network_node_enumerator(sd_bus *bus, const char *path, void *userdata, char return r; } - *nodes = l; - l = NULL; + *nodes = TAKE_PTR(l); return 1; } diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index fc9fbed6f1..e3ed24e600 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -72,8 +72,7 @@ int network_config_section_new(const char *filename, unsigned line, NetworkConfi strcpy(cs->filename, filename); cs->line = line; - *s = cs; - cs = NULL; + *s = TAKE_PTR(cs); return 0; } diff --git a/src/network/networkd-radv.c b/src/network/networkd-radv.c index a921d120b3..1cc89f3b0a 100644 --- a/src/network/networkd-radv.c +++ b/src/network/networkd-radv.c @@ -126,8 +126,7 @@ int prefix_new(Prefix **ret) { if (sd_radv_prefix_new(&prefix->radv_prefix) < 0) return -ENOMEM; - *ret = prefix; - prefix = NULL; + *ret = TAKE_PTR(prefix); return 0; } @@ -344,8 +343,7 @@ static int radv_get_ip6dns(Network *network, struct in6_addr **dns, } if (addresses) { - *dns = addresses; - addresses = NULL; + *dns = TAKE_PTR(addresses); *n_dns = n_addresses; } diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index fdbaec58eb..d8f712c069 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -857,8 +857,7 @@ static int routing_policy_rule_read_full_file(const char *state_file, char **ret if (size <= 0) return -ENODATA; - *ret = s; - s = NULL; + *ret = TAKE_PTR(s); return size; } diff --git a/src/network/networkd.c b/src/network/networkd.c index 79c15d4111..5fd82552ee 100644 --- a/src/network/networkd.c +++ b/src/network/networkd.c @@ -56,7 +56,7 @@ int main(int argc, char *argv[]) { /* Create runtime directory. This is not necessary when networkd is * started with "RuntimeDirectory=systemd/netif", or after * systemd-tmpfiles-setup.service. */ - r = mkdir_safe_label("/run/systemd/netif", 0755, uid, gid, false); + r = mkdir_safe_label("/run/systemd/netif", 0755, uid, gid, MKDIR_WARN_MODE); if (r < 0) log_warning_errno(r, "Could not create runtime directory: %m"); @@ -75,15 +75,15 @@ int main(int argc, char *argv[]) { /* Always create the directories people can create inotify watches in. * It is necessary to create the following subdirectories after drop_privileges() * to support old kernels not supporting AmbientCapabilities=. */ - r = mkdir_safe_label("/run/systemd/netif/links", 0755, uid, gid, false); + r = mkdir_safe_label("/run/systemd/netif/links", 0755, uid, gid, MKDIR_WARN_MODE); if (r < 0) log_warning_errno(r, "Could not create runtime directory 'links': %m"); - r = mkdir_safe_label("/run/systemd/netif/leases", 0755, uid, gid, false); + r = mkdir_safe_label("/run/systemd/netif/leases", 0755, uid, gid, MKDIR_WARN_MODE); if (r < 0) log_warning_errno(r, "Could not create runtime directory 'leases': %m"); - r = mkdir_safe_label("/run/systemd/netif/lldp", 0755, uid, gid, false); + r = mkdir_safe_label("/run/systemd/netif/lldp", 0755, uid, gid, MKDIR_WARN_MODE); if (r < 0) log_warning_errno(r, "Could not create runtime directory 'lldp': %m"); diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c index 0ee69114b2..e32c6223d7 100644 --- a/src/nspawn/nspawn-mount.c +++ b/src/nspawn/nspawn-mount.c @@ -308,8 +308,7 @@ int overlay_mount_parse(CustomMount **l, unsigned *n, const char *s, bool read_o !source_path_is_valid(lower[1])) return -EINVAL; - upper = lower[1]; - lower[1] = NULL; + upper = TAKE_PTR(lower[1]); destination = strdup(upper[0] == '+' ? upper+1 : upper); /* take the destination without "+" prefix */ if (!destination) @@ -321,8 +320,7 @@ int overlay_mount_parse(CustomMount **l, unsigned *n, const char *s, bool read_o * the "upper", and all before that the "lower" directories. */ destination = lower[k - 1]; - upper = lower[k - 2]; - lower[k - 2] = NULL; + upper = TAKE_PTR(lower[k - 2]); STRV_FOREACH(i, lower) if (!source_path_is_valid(*i)) diff --git a/src/nspawn/nspawn-register.c b/src/nspawn/nspawn-register.c index 07d68242c6..838634b624 100644 --- a/src/nspawn/nspawn-register.c +++ b/src/nspawn/nspawn-register.c @@ -293,7 +293,7 @@ int allocate_scope( if (r < 0) return log_error_errno(r, "Could not watch job: %m"); - r = unit_name_mangle_with_suffix(machine_name, UNIT_NAME_NOGLOB, ".scope", &scope); + r = unit_name_mangle_with_suffix(machine_name, 0, ".scope", &scope); if (r < 0) return log_error_errno(r, "Failed to mangle scope name: %m"); diff --git a/src/nspawn/nspawn-setuid.c b/src/nspawn/nspawn-setuid.c index 2dee5f8ec8..80189ac6db 100644 --- a/src/nspawn/nspawn-setuid.c +++ b/src/nspawn/nspawn-setuid.c @@ -226,8 +226,8 @@ int change_uid_gid(const char *user, char **_home) { if (r < 0) return log_error_errno(r, "Failed to make home root directory: %m"); - r = mkdir_safe(home, 0755, uid, gid, false); - if (r < 0 && r != -EEXIST) + r = mkdir_safe(home, 0755, uid, gid, 0); + if (r < 0 && !IN_SET(r, -EEXIST, -ENOTDIR)) return log_error_errno(r, "Failed to make home directory: %m"); (void) fchown(STDIN_FILENO, uid, gid); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 49325f0d22..384b1ea5df 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1175,8 +1175,7 @@ static int parse_argv(int argc, char *argv[]) { * accept this here, and silently make "--ephemeral --template=" equivalent to "--ephemeral * --directory=". */ - arg_directory = arg_template; - arg_template = NULL; + arg_directory = TAKE_PTR(arg_template); } if (arg_template && !(arg_directory || arg_machine)) { diff --git a/src/resolve/resolve-tool.c b/src/resolve/resolve-tool.c index 462ea7a2d5..9208bf1167 100644 --- a/src/resolve/resolve-tool.c +++ b/src/resolve/resolve-tool.c @@ -1454,11 +1454,6 @@ static int status_global(sd_bus *bus, bool *empty_line) { goto finish; } - if (strv_isempty(global_info.dns) && strv_isempty(global_info.domains) && strv_isempty(global_info.ntas)) { - r = 0; - goto finish; - } - (void) pager_open(arg_no_pager, false); printf("%sGlobal%s\n", ansi_highlight(), ansi_normal()); @@ -2421,11 +2416,11 @@ int main(int argc, char **argv) { STRV_FOREACH(ifname, argv + optind) { int ifindex, q; - q = parse_ifindex(argv[optind], &ifindex); + q = parse_ifindex(*ifname, &ifindex); if (q < 0) { - ifindex = if_nametoindex(argv[optind]); + ifindex = if_nametoindex(*ifname); if (ifindex <= 0) { - log_error_errno(errno, "Failed to resolve interface name: %s", argv[optind]); + log_error_errno(errno, "Failed to resolve interface name '%s': %m", *ifname); continue; } } diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index bf6aac8300..305bb6afe8 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -325,7 +325,7 @@ static int dns_scope_socket( union sockaddr_union sa = {}; socklen_t salen; static const int one = 1; - int ret, r, ifindex; + int r, ifindex; assert(s); @@ -409,10 +409,7 @@ static int dns_scope_socket( if (r < 0 && errno != EINPROGRESS) return -errno; - ret = fd; - fd = -1; - - return ret; + return TAKE_FD(fd); } int dns_scope_socket_udp(DnsScope *s, DnsServer *server, uint16_t port) { diff --git a/src/resolve/resolved-dns-search-domain.c b/src/resolve/resolved-dns-search-domain.c index 585c518e19..03f7536fd2 100644 --- a/src/resolve/resolved-dns-search-domain.c +++ b/src/resolve/resolved-dns-search-domain.c @@ -56,8 +56,7 @@ int dns_search_domain_new( d->n_ref = 1; d->manager = m; d->type = type; - d->name = normalized; - normalized = NULL; + d->name = TAKE_PTR(normalized); switch (type) { diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c index 5ce8d240dd..20ff8a1d3b 100644 --- a/src/resolve/resolved-dns-stub.c +++ b/src/resolve/resolved-dns-stub.c @@ -447,10 +447,8 @@ static int manager_dns_stub_udp_fd(Manager *m) { return r; (void) sd_event_source_set_description(m->dns_stub_udp_event_source, "dns-stub-udp"); - m->dns_stub_udp_fd = fd; - fd = -1; - return m->dns_stub_udp_fd; + return m->dns_stub_udp_fd = TAKE_FD(fd); } static int on_dns_stub_stream_packet(DnsStream *s) { @@ -542,10 +540,8 @@ static int manager_dns_stub_tcp_fd(Manager *m) { return r; (void) sd_event_source_set_description(m->dns_stub_tcp_event_source, "dns-stub-tcp"); - m->dns_stub_tcp_fd = fd; - fd = -1; - return m->dns_stub_tcp_fd; + return m->dns_stub_tcp_fd = TAKE_FD(fd); } int manager_dns_stub_start(Manager *m) { diff --git a/src/resolve/resolved-dns-zone.c b/src/resolve/resolved-dns-zone.c index dcb9702e57..4888eccbd3 100644 --- a/src/resolve/resolved-dns-zone.c +++ b/src/resolve/resolved-dns-zone.c @@ -36,8 +36,7 @@ void dns_zone_item_probe_stop(DnsZoneItem *i) { if (!i->probe_transaction) return; - t = i->probe_transaction; - i->probe_transaction = NULL; + t = TAKE_PTR(i->probe_transaction); set_remove(t->notify_zone_items, i); set_remove(t->notify_zone_items_done, i); diff --git a/src/resolve/resolved-dnssd-bus.c b/src/resolve/resolved-dnssd-bus.c index c914e8f8d2..1a70968dd1 100644 --- a/src/resolve/resolved-dnssd-bus.c +++ b/src/resolve/resolved-dnssd-bus.c @@ -139,8 +139,7 @@ int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ** } l[c] = NULL; - *nodes = l; - l = NULL; + *nodes = TAKE_PTR(l); return 1; } diff --git a/src/resolve/resolved-dnssd.c b/src/resolve/resolved-dnssd.c index db589f4436..18e61aaee3 100644 --- a/src/resolve/resolved-dnssd.c +++ b/src/resolve/resolved-dnssd.c @@ -198,8 +198,7 @@ int dnssd_render_instance_name(DnssdService *s, char **ret_name) { return -EINVAL; } - *ret_name = name; - name = NULL; + *ret_name = TAKE_PTR(name); return 0; } @@ -319,8 +318,7 @@ int dnssd_txt_item_new_from_string(const char *key, const char *value, DnsTxtIte } i->length = length; - *ret_item = i; - i = NULL; + *ret_item = TAKE_PTR(i); return 0; } @@ -345,8 +343,7 @@ int dnssd_txt_item_new_from_data(const char *key, const void *data, const size_t } i->length = length; - *ret_item = i; - i = NULL; + *ret_item = TAKE_PTR(i); return 0; } diff --git a/src/resolve/resolved-link-bus.c b/src/resolve/resolved-link-bus.c index 82a29289d2..7e7308a819 100644 --- a/src/resolve/resolved-link-bus.c +++ b/src/resolve/resolved-link-bus.c @@ -496,8 +496,7 @@ int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, v } set_free_free(l->dnssec_negative_trust_anchors); - l->dnssec_negative_trust_anchors = ns; - ns = NULL; + l->dnssec_negative_trust_anchors = TAKE_PTR(ns); (void) link_save_user(l); @@ -621,8 +620,7 @@ int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char *** } l[c] = NULL; - *nodes = l; - l = NULL; + *nodes = TAKE_PTR(l); return 1; } diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c index e3e50eca53..4d87e88cdf 100644 --- a/src/resolve/resolved-link.c +++ b/src/resolve/resolved-link.c @@ -440,8 +440,7 @@ static int link_update_dnssec_negative_trust_anchors(Link *l) { return r; set_free_free(l->dnssec_negative_trust_anchors); - l->dnssec_negative_trust_anchors = ns; - ns = NULL; + l->dnssec_negative_trust_anchors = TAKE_PTR(ns); return 0; @@ -1293,8 +1292,7 @@ int link_load_user(Link *l) { if (r < 0) goto fail; - l->dnssec_negative_trust_anchors = ns; - ns = NULL; + l->dnssec_negative_trust_anchors = TAKE_PTR(ns); } return 0; diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 2ee027791a..de1f0ce21d 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -396,11 +396,8 @@ static int determine_hostname(char **full_hostname, char **llmnr_hostname, char if (r < 0) return log_error_errno(r, "Failed to determine mDNS hostname: %m"); - *llmnr_hostname = n; - n = NULL; - - *full_hostname = h; - h = NULL; + *llmnr_hostname = TAKE_PTR(n); + *full_hostname = TAKE_PTR(h); return 0; } @@ -445,11 +442,8 @@ static int make_fallback_hostnames(char **full_hostname, char **llmnr_hostname, if (!h) return log_oom(); - *llmnr_hostname = n; - n = NULL; - - *mdns_hostname = m; - m = NULL; + *llmnr_hostname = TAKE_PTR(n); + *mdns_hostname = TAKE_PTR(m); *full_hostname = h; diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c index a4cda0b5ef..193f88bd58 100644 --- a/src/resolve/resolved.c +++ b/src/resolve/resolved.c @@ -62,7 +62,7 @@ int main(int argc, char *argv[]) { } /* Always create the directory where resolv.conf will live */ - r = mkdir_safe_label("/run/systemd/resolve", 0755, uid, gid, false); + r = mkdir_safe_label("/run/systemd/resolve", 0755, uid, gid, MKDIR_WARN_MODE); if (r < 0) { log_error_errno(r, "Could not create runtime directory: %m"); goto finish; diff --git a/src/run/run.c b/src/run/run.c index cfab3d6f97..1da185dde9 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -520,7 +520,7 @@ static int transient_cgroup_set_properties(sd_bus_message *m) { if (!isempty(arg_slice)) { _cleanup_free_ char *slice = NULL; - r = unit_name_mangle_with_suffix(arg_slice, UNIT_NAME_NOGLOB, ".slice", &slice); + r = unit_name_mangle_with_suffix(arg_slice, arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, ".slice", &slice); if (r < 0) return log_error_errno(r, "Failed to mangle name '%s': %m", arg_slice); @@ -984,7 +984,7 @@ static int start_transient_service( } if (arg_unit) { - r = unit_name_mangle_with_suffix(arg_unit, UNIT_NAME_NOGLOB, ".service", &service); + r = unit_name_mangle_with_suffix(arg_unit, arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, ".service", &service); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); } else { @@ -1187,7 +1187,7 @@ static int start_transient_scope( return log_oom(); if (arg_unit) { - r = unit_name_mangle_with_suffix(arg_unit, UNIT_NAME_NOGLOB, ".scope", &scope); + r = unit_name_mangle_with_suffix(arg_unit, arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, ".scope", &scope); if (r < 0) return log_error_errno(r, "Failed to mangle scope name: %m"); } else { @@ -1358,11 +1358,11 @@ static int start_transient_trigger( break; default: - r = unit_name_mangle_with_suffix(arg_unit, UNIT_NAME_NOGLOB, ".service", &service); + r = unit_name_mangle_with_suffix(arg_unit, arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, ".service", &service); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); - r = unit_name_mangle_with_suffix(arg_unit, UNIT_NAME_NOGLOB, suffix, &trigger); + r = unit_name_mangle_with_suffix(arg_unit, arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, suffix, &trigger); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c index 4fa9188957..88cafd4940 100644 --- a/src/shared/ask-password-api.c +++ b/src/shared/ask-password-api.c @@ -730,8 +730,7 @@ int ask_password_agent( if (keyname) (void) add_to_keyring_and_log(keyname, flags, l); - *ret = l; - l = NULL; + *ret = TAKE_PTR(l); r = 0; finish: diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 8061af1865..803f75335c 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -1094,8 +1094,7 @@ static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_ return r; strv_free(*p); - *p = l; - l = NULL; + *p = TAKE_PTR(l); return 0; } diff --git a/src/shared/cgroup-show.c b/src/shared/cgroup-show.c index 0ddae95434..326a398075 100644 --- a/src/shared/cgroup-show.c +++ b/src/shared/cgroup-show.c @@ -189,8 +189,7 @@ int show_cgroup_by_path( free(last); } - last = k; - k = NULL; + last = TAKE_PTR(k); } if (r < 0) diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c index e7c901f761..483dc1a69f 100644 --- a/src/shared/conf-parser.c +++ b/src/shared/conf-parser.c @@ -165,7 +165,7 @@ static int next_assignment( return 0; } -/* Parse a variable assignment line */ +/* Parse a single logical line */ static int parse_line( const char* unit, const char *filename, @@ -180,7 +180,7 @@ static int parse_line( char *l, void *userdata) { - char *e; + char *e, *include; assert(filename); assert(line > 0); @@ -194,7 +194,8 @@ static int parse_line( if (strchr(COMMENTS "\n", *l)) return 0; - if (startswith(l, ".include ")) { + include = first_word(l, ".include"); + if (include) { _cleanup_free_ char *fn = NULL; /* .includes are a bad idea, we only support them here @@ -211,7 +212,11 @@ static int parse_line( return 0; } - fn = file_in_same_dir(filename, strstrip(l+9)); + log_syntax(unit, LOG_WARNING, filename, line, 0, + ".include directives are deprecated, and support for them will be removed in a future version of systemd. " + "Please use drop-in files instead."); + + fn = file_in_same_dir(filename, strstrip(include)); if (!fn) return -ENOMEM; diff --git a/src/shared/dns-domain.c b/src/shared/dns-domain.c index 8c807e0e23..89d18431e4 100644 --- a/src/shared/dns-domain.c +++ b/src/shared/dns-domain.c @@ -295,8 +295,7 @@ int dns_label_escape_new(const char *p, size_t l, char **ret) { if (r < 0) return r; - *ret = s; - s = NULL; + *ret = TAKE_PTR(s); return r; } @@ -601,8 +600,7 @@ int dns_name_endswith(const char *name, const char *suffix) { /* Not the same, let's jump back, and try with the next label again */ s = suffix; - n = saved_n; - saved_n = NULL; + n = TAKE_PTR(saved_n); } } } diff --git a/src/shared/efivars.c b/src/shared/efivars.c index 9ca51cf750..d31cf2d860 100644 --- a/src/shared/efivars.c +++ b/src/shared/efivars.c @@ -249,8 +249,7 @@ int efi_get_variable( ((char*) buf)[st.st_size - 4] = 0; ((char*) buf)[st.st_size - 4 + 1] = 0; - *value = buf; - buf = NULL; + *value = TAKE_PTR(buf); *size = (size_t) st.st_size - 4; if (attribute) @@ -563,8 +562,7 @@ int efi_get_boot_order(uint16_t **order) { l / sizeof(uint16_t) > INT_MAX) return -EINVAL; - *order = buf; - buf = NULL; + *order = TAKE_PTR(buf); return (int) (l / sizeof(uint16_t)); } diff --git a/src/shared/fdset.c b/src/shared/fdset.c index 9ce1295223..845c19b1cf 100644 --- a/src/shared/fdset.c +++ b/src/shared/fdset.c @@ -25,6 +25,7 @@ #include "sd-daemon.h" +#include "alloc-util.h" #include "dirent-util.h" #include "fd-util.h" #include "fdset.h" @@ -168,8 +169,7 @@ int fdset_new_fill(FDSet **_s) { } r = 0; - *_s = s; - s = NULL; + *_s = TAKE_PTR(s); finish: /* We won't close the fds here! */ diff --git a/src/shared/fstab-util.c b/src/shared/fstab-util.c index bcd7b43084..1a3bc46d2a 100644 --- a/src/shared/fstab-util.c +++ b/src/shared/fstab-util.c @@ -169,10 +169,8 @@ answer: *filtered = f; } - if (value) { - *value = v; - v = NULL; - } + if (value) + *value = TAKE_PTR(v); return !!n; } @@ -201,8 +199,7 @@ int fstab_extract_values(const char *opts, const char *name, char ***values) { return r; } - *values = res; - res = NULL; + *values = TAKE_PTR(res); return !!*values; } diff --git a/src/shared/import-util.c b/src/shared/import-util.c index 07ba216e93..5f71add506 100644 --- a/src/shared/import-util.c +++ b/src/shared/import-util.c @@ -153,8 +153,7 @@ int raw_strip_suffixes(const char *p, char **ret) { break; } - *ret = q; - q = NULL; + *ret = TAKE_PTR(q); return 0; } diff --git a/src/shared/install-printf.c b/src/shared/install-printf.c index aaab2e6665..5135d0671e 100644 --- a/src/shared/install-printf.c +++ b/src/shared/install-printf.c @@ -50,10 +50,8 @@ static int specifier_prefix_and_instance(char specifier, void *data, void *userd if (!ans) return -ENOMEM; *ret = ans; - } else { - *ret = prefix; - prefix = NULL; - } + } else + *ret = TAKE_PTR(prefix); return 0; } diff --git a/src/shared/install.c b/src/shared/install.c index ed5f51cc46..7506018d41 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -1422,8 +1422,7 @@ static int unit_file_search( r = unit_file_load_or_readlink(c, info, path, paths->root_dir, flags); if (r >= 0) { - info->path = path; - path = NULL; + info->path = TAKE_PTR(path); result = r; found_unit = true; break; @@ -1446,8 +1445,7 @@ static int unit_file_search( r = unit_file_load_or_readlink(c, info, path, paths->root_dir, flags); if (r >= 0) { - info->path = path; - path = NULL; + info->path = TAKE_PTR(path); result = r; found_unit = true; break; @@ -1754,8 +1752,7 @@ static int install_info_symlink_wants( if (r < 0) return r; - path = instance.path; - instance.path = NULL; + path = TAKE_PTR(instance.path); if (instance.type == UNIT_FILE_TYPE_MASKED) { unit_file_changes_add(changes, n_changes, -ERFKILL, path, NULL); diff --git a/src/shared/libshared.sym b/src/shared/libshared.sym index e4ae17eede..6a7495adc3 100644 --- a/src/shared/libshared.sym +++ b/src/shared/libshared.sym @@ -1,3 +1,3 @@ SD_SHARED { - global: *; + global: *; }; diff --git a/src/shared/machine-image.c b/src/shared/machine-image.c index 66eefb3036..f48b6c693c 100644 --- a/src/shared/machine-image.c +++ b/src/shared/machine-image.c @@ -80,7 +80,6 @@ Image *image_unref(Image *i) { static char **image_settings_path(Image *image) { _cleanup_strv_free_ char **l = NULL; - char **ret; const char *fn, *s; unsigned i = 0; @@ -104,10 +103,7 @@ static char **image_settings_path(Image *image) { if (!l[i]) return NULL; - ret = l; - l = NULL; - - return ret; + return TAKE_PTR(l); } static char *image_roothash_path(Image *image) { diff --git a/src/shared/machine-pool.c b/src/shared/machine-pool.c index 031d443e9e..68e5bd19a0 100644 --- a/src/shared/machine-pool.c +++ b/src/shared/machine-pool.c @@ -89,11 +89,8 @@ static int setup_machine_raw(uint64_t size, sd_bus_error *error) { * /var/lib/machines. */ fd = open("/var/lib/machines.raw", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); - if (fd >= 0) { - r = fd; - fd = -1; - return r; - } + if (fd >= 0) + return TAKE_FD(fd); if (errno != ENOENT) return sd_bus_error_set_errnof(error, errno, "Failed to open /var/lib/machines.raw: %m"); @@ -162,10 +159,7 @@ static int setup_machine_raw(uint64_t size, sd_bus_error *error) { goto fail; } - r = fd; - fd = -1; - - return r; + return TAKE_FD(fd); fail: unlink_noerrno(tmp); diff --git a/src/shared/nsflags.c b/src/shared/nsflags.c index 05ec9feb8d..a8ddc9a57f 100644 --- a/src/shared/nsflags.c +++ b/src/shared/nsflags.c @@ -114,8 +114,7 @@ int namespace_flag_to_string_many(unsigned long flags, char **ret) { return -ENOMEM; } - *ret = s; - s = NULL; + *ret = TAKE_PTR(s); return 0; } diff --git a/src/shared/path-lookup.c b/src/shared/path-lookup.c index 5f31831c99..a472e80aec 100644 --- a/src/shared/path-lookup.c +++ b/src/shared/path-lookup.c @@ -181,7 +181,6 @@ static char** user_dirs( _cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL; _cleanup_free_ char *data_home = NULL; _cleanup_strv_free_ char **res = NULL; - char **tmp; int r; r = xdg_user_dirs(&config_dirs, &data_dirs); @@ -242,10 +241,7 @@ static char** user_dirs( if (path_strv_make_absolute_cwd(res) < 0) return NULL; - tmp = res; - res = NULL; - - return tmp; + return TAKE_PTR(res); } bool path_is_user_data_dir(const char *path) { @@ -374,8 +370,7 @@ static int acquire_config_dirs(UnitFileScope scope, char **persistent, char **ru *runtime = NULL; } - *persistent = a; - a = NULL; + *persistent = TAKE_PTR(a); return 0; @@ -413,8 +408,7 @@ static int acquire_control_dirs(UnitFileScope scope, char **persistent, char **r if (!b) return -ENOMEM; - *runtime = b; - b = NULL; + *runtime = TAKE_PTR(b); break; } @@ -443,8 +437,7 @@ static int acquire_control_dirs(UnitFileScope scope, char **persistent, char **r assert_not_reached("Hmm, unexpected scope value."); } - *persistent = a; - a = NULL; + *persistent = TAKE_PTR(a); return 0; } diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index 3691e73b84..13c83097a5 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -1185,6 +1185,10 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) { case SCMP_ARCH_PPC: case SCMP_ARCH_PPC64: case SCMP_ARCH_PPC64LE: + case SCMP_ARCH_MIPSEL64N32: + case SCMP_ARCH_MIPS64N32: + case SCMP_ARCH_MIPSEL64: + case SCMP_ARCH_MIPS64: /* These we know we support (i.e. are the ones that do not use socketcall()) */ supported = true; break; @@ -1192,6 +1196,8 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) { case SCMP_ARCH_S390: case SCMP_ARCH_S390X: case SCMP_ARCH_X86: + case SCMP_ARCH_MIPSEL: + case SCMP_ARCH_MIPS: default: /* These we either know we don't support (i.e. are the ones that do use socketcall()), or we * don't know */ diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c index 1e1a7e57ad..f65eed87f2 100644 --- a/src/shared/sleep-config.c +++ b/src/shared/sleep-config.c @@ -40,8 +40,6 @@ #include "string-util.h" #include "strv.h" -#define USE(x, y) do { (x) = (y); (y) = NULL; } while (0) - int parse_sleep_config(const char *verb, char ***_modes, char ***_states, usec_t *_delay) { _cleanup_strv_free_ char @@ -69,32 +67,32 @@ int parse_sleep_config(const char *verb, char ***_modes, char ***_states, usec_t if (streq(verb, "suspend")) { /* empty by default */ - USE(modes, suspend_mode); + modes = TAKE_PTR(suspend_mode); if (suspend_state) - USE(states, suspend_state); + states = TAKE_PTR(suspend_state); else states = strv_new("mem", "standby", "freeze", NULL); } else if (streq(verb, "hibernate")) { if (hibernate_mode) - USE(modes, hibernate_mode); + modes = TAKE_PTR(hibernate_mode); else modes = strv_new("platform", "shutdown", NULL); if (hibernate_state) - USE(states, hibernate_state); + states = TAKE_PTR(hibernate_state); else states = strv_new("disk", NULL); } else if (streq(verb, "hybrid-sleep")) { if (hybrid_mode) - USE(modes, hybrid_mode); + modes = TAKE_PTR(hybrid_mode); else modes = strv_new("suspend", "platform", "shutdown", NULL); if (hybrid_state) - USE(states, hybrid_state); + states = TAKE_PTR(hybrid_state); else states = strv_new("disk", NULL); diff --git a/src/shared/specifier.c b/src/shared/specifier.c index 23aaa88c4b..98d95eef8e 100644 --- a/src/shared/specifier.c +++ b/src/shared/specifier.c @@ -117,8 +117,7 @@ int specifier_printf(const char *text, const Specifier table[], void *userdata, *(t++) = '%'; *t = 0; - *_ret = ret; - ret = NULL; + *_ret = TAKE_PTR(ret); return 0; } diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index cae4ff023a..d23bddc99a 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -1810,7 +1810,7 @@ static int list_dependencies(int argc, char *argv[], void *userdata) { int r; if (argv[1]) { - r = unit_name_mangle(argv[1], UNIT_NAME_NOGLOB, &unit); + r = unit_name_mangle(argv[1], arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, &unit); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); @@ -1924,8 +1924,7 @@ static int get_machine_list( return log_oom(); machine_infos[c].is_host = true; - machine_infos[c].name = hn; - hn = NULL; + machine_infos[c].name = TAKE_PTR(hn); (void) get_machine_properties(bus, &machine_infos[c]); c++; @@ -2116,7 +2115,7 @@ static int set_default(int argc, char *argv[], void *userdata) { assert(argc >= 2); assert(argv); - r = unit_name_mangle_with_suffix(argv[1], UNIT_NAME_NOGLOB, ".target", &unit); + r = unit_name_mangle_with_suffix(argv[1], arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, ".target", &unit); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); @@ -2462,10 +2461,9 @@ static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **un if (r < 0) return log_error_errno(r, "Failed to access path '%s': %m", path); - if (unit_path) { - *unit_path = lpath; - lpath = NULL; - } + if (unit_path) + *unit_path = TAKE_PTR(lpath); + return 1; } @@ -2497,10 +2495,9 @@ static int unit_find_template_path( if (r < 0) return r; - if (template) { - *template = _template; - _template = NULL; - } + if (template) + *template = TAKE_PTR(_template); + return r; } @@ -2663,7 +2660,7 @@ static int check_triggering_units( char **i; int r; - r = unit_name_mangle(name, UNIT_NAME_NOGLOB, &n); + r = unit_name_mangle(name, 0, &n); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); @@ -2949,11 +2946,12 @@ static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***r STRV_FOREACH(name, names) { char *t; + UnitNameMangle options = UNIT_NAME_MANGLE_GLOB | (arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN); if (suffix) - r = unit_name_mangle_with_suffix(*name, UNIT_NAME_GLOB, suffix, &t); + r = unit_name_mangle_with_suffix(*name, options, suffix, &t); else - r = unit_name_mangle(*name, UNIT_NAME_GLOB, &t); + r = unit_name_mangle(*name, options, &t); if (r < 0) return log_error_errno(r, "Failed to mangle name: %m"); @@ -5422,7 +5420,7 @@ static int set_property(int argc, char *argv[], void *userdata) { if (r < 0) return bus_log_create_error(r); - r = unit_name_mangle(argv[1], UNIT_NAME_NOGLOB, &n); + r = unit_name_mangle(argv[1], arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, &n); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); @@ -6000,7 +5998,7 @@ static int mangle_names(char **original_names, char ***mangled_names) { return log_oom(); } } else { - r = unit_name_mangle(*name, UNIT_NAME_NOGLOB, i); + r = unit_name_mangle(*name, arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, i); if (r < 0) { *i = NULL; strv_free(l); @@ -6336,7 +6334,7 @@ static int add_dependency(int argc, char *argv[], void *userdata) { if (!argv[1]) return 0; - r = unit_name_mangle_with_suffix(argv[1], UNIT_NAME_NOGLOB, ".target", &target); + r = unit_name_mangle_with_suffix(argv[1], arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, ".target", &target); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); @@ -6670,8 +6668,7 @@ static int create_edit_temp_file(const char *new_path, const char *original_path } else if (r < 0) return log_error_errno(r, "Failed to create temporary file for \"%s\": %m", new_path); - *ret_tmp_fn = t; - t = NULL; + *ret_tmp_fn = TAKE_PTR(t); return 0; } @@ -6702,12 +6699,9 @@ static int get_file_to_edit( return -EEXIST; } - *ret_path = run; - run = NULL; - } else { - *ret_path = path; - path = NULL; - } + *ret_path = TAKE_PTR(run); + } else + *ret_path = TAKE_PTR(path); return 0; } diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 43952e5f19..f6878a9c01 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -19,10 +19,6 @@ ***/ #include <getopt.h> -#include <grp.h> -#include <gshadow.h> -#include <pwd.h> -#include <shadow.h> #include <utmp.h> #include "alloc-util.h" @@ -113,8 +109,7 @@ static int load_user_database(void) { if (r < 0) return r; - errno = 0; - while ((pw = fgetpwent(f))) { + while ((r = fgetpwent_sane(f, &pw)) > 0) { char *n; int k, q; @@ -137,13 +132,8 @@ static int load_user_database(void) { if (q < 0 && k < 0) free(n); - - errno = 0; } - if (!IN_SET(errno, 0, ENOENT)) - return -errno; - - return 0; + return r; } static int load_group_database(void) { @@ -287,6 +277,7 @@ static int putgrent_with_members(const struct group *gr, FILE *group) { if (added) { struct group t; + int r; strv_uniq(l); strv_sort(l); @@ -294,19 +285,12 @@ static int putgrent_with_members(const struct group *gr, FILE *group) { t = *gr; t.gr_mem = l; - errno = 0; - if (putgrent(&t, group) != 0) - return errno > 0 ? -errno : -EIO; - - return 1; + r = putgrent_sane(&t, group); + return r < 0 ? r : 1; } } - errno = 0; - if (putgrent(gr, group) != 0) - return errno > 0 ? -errno : -EIO; - - return 0; + return putgrent_sane(gr, group); } #if ENABLE_GSHADOW @@ -338,6 +322,7 @@ static int putsgent_with_members(const struct sgrp *sg, FILE *gshadow) { if (added) { struct sgrp t; + int r; strv_uniq(l); strv_sort(l); @@ -345,19 +330,12 @@ static int putsgent_with_members(const struct sgrp *sg, FILE *gshadow) { t = *sg; t.sg_mem = l; - errno = 0; - if (putsgent(&t, gshadow) != 0) - return errno > 0 ? -errno : -EIO; - - return 1; + r = putsgent_sane(&t, gshadow); + return r < 0 ? r : 1; } } - errno = 0; - if (putsgent(sg, gshadow) != 0) - return errno > 0 ? -errno : -EIO; - - return 0; + return putsgent_sane(sg, gshadow); } #endif @@ -415,8 +393,7 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char if (r < 0) return r; - errno = 0; - while ((pw = fgetpwent(original))) { + while ((r = fgetpwent_sane(original, &pw)) > 0) { i = ordered_hashmap_get(users, pw->pw_name); if (i && i->todo_user) { @@ -429,19 +406,16 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char return -EEXIST; } - errno = 0; - /* Make sure we keep the NIS entries (if any) at the end. */ if (IN_SET(pw->pw_name[0], '+', '-')) break; - if (putpwent(pw, passwd) < 0) - return errno ? -errno : -EIO; - - errno = 0; + r = putpwent_sane(pw, passwd); + if (r < 0) + return r; } - if (!IN_SET(errno, 0, ENOENT)) - return -errno; + if (r < 0) + return r; } else { if (errno != ENOENT) @@ -468,23 +442,23 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char .pw_shell = i->shell ?: (char*) default_shell(i->uid), }; - errno = 0; - if (putpwent(&n, passwd) != 0) - return errno ? -errno : -EIO; + r = putpwent_sane(&n, passwd); + if (r < 0) + return r; } - errno = 0; /* Append the remaining NIS entries if any */ while (pw) { - errno = 0; - if (putpwent(pw, passwd) < 0) - return errno ? -errno : -EIO; + r = putpwent_sane(pw, passwd); + if (r < 0) + return r; - errno = 0; - pw = fgetpwent(original); + r = fgetpwent_sane(original, &pw); + if (r < 0) + return r; + if (r == 0) + break; } - if (!IN_SET(errno, 0, ENOENT)) - return -errno; r = fflush_and_check(passwd); if (r < 0) @@ -522,8 +496,7 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char if (r < 0) return r; - errno = 0; - while ((sp = fgetspent(original))) { + while ((r = fgetspent_sane(original, &sp)) > 0) { i = ordered_hashmap_get(users, sp->sp_namp); if (i && i->todo_user) { @@ -536,19 +509,16 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char ordered_hashmap_remove(todo_uids, UID_TO_PTR(i->uid)); } - errno = 0; - /* Make sure we keep the NIS entries (if any) at the end. */ if (IN_SET(sp->sp_namp[0], '+', '-')) break; - if (putspent(sp, shadow) < 0) - return errno ? -errno : -EIO; - - errno = 0; + r = putspent_sane(sp, shadow); + if (r < 0) + return r; } - if (!IN_SET(errno, 0, ENOENT)) - return -errno; + if (r < 0) + return r; } else { if (errno != ENOENT) @@ -570,20 +540,22 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char .sp_flag = (unsigned long) -1, /* this appears to be what everybody does ... */ }; - errno = 0; - if (putspent(&n, shadow) != 0) - return errno ? -errno : -EIO; + r = putspent_sane(&n, shadow); + if (r < 0) + return r; } - errno = 0; /* Append the remaining NIS entries if any */ while (sp) { - errno = 0; - if (putspent(sp, shadow) < 0) - return errno ? -errno : -EIO; + r = putspent_sane(sp, shadow); + if (r < 0) + return r; - errno = 0; - sp = fgetspent(original); + r = fgetspent_sane(original, &sp); + if (r < 0) + return r; + if (r == 0) + break; } if (!IN_SET(errno, 0, ENOENT)) return -errno; @@ -622,8 +594,7 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char ** if (r < 0) return r; - errno = 0; - while ((gr = fgetgrent(original))) { + while ((r = fgetgrent_sane(original, &gr)) > 0) { /* Safety checks against name and GID collisions. Normally, * this should be unnecessary, but given that we look at the * entries anyway here, let's make an extra verification @@ -640,8 +611,6 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char ** return -EEXIST; } - errno = 0; - /* Make sure we keep the NIS entries (if any) at the end. */ if (IN_SET(gr->gr_name[0], '+', '-')) break; @@ -651,11 +620,9 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char ** return r; if (r > 0) group_changed = true; - - errno = 0; } - if (!IN_SET(errno, 0, ENOENT)) - return -errno; + if (r < 0) + return r; } else { if (errno != ENOENT) @@ -677,19 +644,19 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char ** group_changed = true; } - errno = 0; /* Append the remaining NIS entries if any */ while (gr) { - errno = 0; - if (putgrent(gr, group) != 0) - return errno > 0 ? -errno : -EIO; + r = putgrent_sane(gr, group); + if (r < 0) + return r; - errno = 0; - gr = fgetgrent(original); + r = fgetgrent_sane(original, &gr); + if (r < 0) + return r; + if (r == 0) + break; } - if (!IN_SET(errno, 0, ENOENT)) - return -errno; r = fflush_sync_and_check(group); if (r < 0) @@ -728,8 +695,7 @@ static int write_temporary_gshadow(const char * gshadow_path, FILE **tmpfile, ch if (r < 0) return r; - errno = 0; - while ((sg = fgetsgent(original))) { + while ((r = fgetsgent_sane(original, &sg)) > 0) { i = ordered_hashmap_get(groups, sg->sg_namp); if (i && i->todo_group) { @@ -742,11 +708,9 @@ static int write_temporary_gshadow(const char * gshadow_path, FILE **tmpfile, ch return r; if (r > 0) group_changed = true; - - errno = 0; } - if (!IN_SET(errno, 0, ENOENT)) - return -errno; + if (r < 0) + return r; } else { if (errno != ENOENT) diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c index 087ba08559..394a04bb88 100644 --- a/src/sysv-generator/sysv-generator.c +++ b/src/sysv-generator/sysv-generator.c @@ -240,7 +240,7 @@ static char *sysv_translate_name(const char *name) { if (res) *res = 0; - if (unit_name_mangle(c, UNIT_NAME_NOGLOB, &res) < 0) + if (unit_name_mangle(c, 0, &res) < 0) return NULL; return res; @@ -741,8 +741,7 @@ static int acquire_search_path(const char *def, const char *envvar, char ***ret) if (!path_strv_resolve_uniq(l, NULL)) return log_oom(); - *ret = l; - l = NULL; + *ret = TAKE_PTR(l); return 0; } diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c index ebcec4fcc5..9fe79502c8 100644 --- a/src/test/test-fs-util.c +++ b/src/test/test-fs-util.c @@ -317,7 +317,7 @@ static void test_readlink_and_make_absolute(void) { char *r = NULL; _cleanup_free_ char *pwd = NULL; - assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid(), false) >= 0); + assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid(), MKDIR_WARN_MODE) >= 0); assert_se(touch(name) >= 0); assert_se(symlink(name, name_alias) >= 0); diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c index f7598d2284..3c7a17b42f 100644 --- a/src/test/test-unit-name.c +++ b/src/test/test-unit-name.c @@ -162,10 +162,10 @@ static void test_unit_name_to_path(void) { test_unit_name_to_path_one("home/foo", NULL, -EINVAL); } -static void test_unit_name_mangle_one(UnitNameMangle allow_globs, const char *pattern, const char *expect, int ret) { +static void test_unit_name_mangle_one(bool allow_globs, const char *pattern, const char *expect, int ret) { _cleanup_free_ char *t = NULL; - assert_se(unit_name_mangle(pattern, allow_globs, &t) == ret); + assert_se(unit_name_mangle(pattern, (allow_globs * UNIT_NAME_MANGLE_GLOB) | UNIT_NAME_MANGLE_WARN, &t) == ret); puts(strna(t)); assert_se(streq_ptr(t, expect)); @@ -173,29 +173,29 @@ static void test_unit_name_mangle_one(UnitNameMangle allow_globs, const char *pa _cleanup_free_ char *k = NULL; assert_se(unit_name_is_valid(t, UNIT_NAME_ANY) || - (allow_globs == UNIT_NAME_GLOB && string_is_glob(t))); + (allow_globs && string_is_glob(t))); - assert_se(unit_name_mangle(t, allow_globs, &k) == 0); + assert_se(unit_name_mangle(t, (allow_globs * UNIT_NAME_MANGLE_GLOB) | UNIT_NAME_MANGLE_WARN, &k) == 0); assert_se(streq_ptr(t, k)); } } static void test_unit_name_mangle(void) { puts("-------------------------------------------------"); - test_unit_name_mangle_one(UNIT_NAME_NOGLOB, "foo.service", "foo.service", 0); - test_unit_name_mangle_one(UNIT_NAME_NOGLOB, "/home", "home.mount", 1); - test_unit_name_mangle_one(UNIT_NAME_NOGLOB, "/dev/sda", "dev-sda.device", 1); - test_unit_name_mangle_one(UNIT_NAME_NOGLOB, "üxknürz.service", "\\xc3\\xbcxkn\\xc3\\xbcrz.service", 1); - test_unit_name_mangle_one(UNIT_NAME_NOGLOB, "foobar-meh...waldi.service", "foobar-meh...waldi.service", 0); - test_unit_name_mangle_one(UNIT_NAME_NOGLOB, "_____####----.....service", "_____\\x23\\x23\\x23\\x23----.....service", 1); - test_unit_name_mangle_one(UNIT_NAME_NOGLOB, "_____##@;;;,,,##----.....service", "_____\\x23\\x23@\\x3b\\x3b\\x3b\\x2c\\x2c\\x2c\\x23\\x23----.....service", 1); - test_unit_name_mangle_one(UNIT_NAME_NOGLOB, "xxx@@@@/////\\\\\\\\\\yyy.service", "xxx@@@@-----\\\\\\\\\\yyy.service", 1); - test_unit_name_mangle_one(UNIT_NAME_NOGLOB, "", NULL, -EINVAL); - - test_unit_name_mangle_one(UNIT_NAME_GLOB, "foo.service", "foo.service", 0); - test_unit_name_mangle_one(UNIT_NAME_GLOB, "foo", "foo.service", 1); - test_unit_name_mangle_one(UNIT_NAME_GLOB, "foo*", "foo*", 0); - test_unit_name_mangle_one(UNIT_NAME_GLOB, "ü*", "\\xc3\\xbc*", 1); + test_unit_name_mangle_one(false, "foo.service", "foo.service", 0); + test_unit_name_mangle_one(false, "/home", "home.mount", 1); + test_unit_name_mangle_one(false, "/dev/sda", "dev-sda.device", 1); + test_unit_name_mangle_one(false, "üxknürz.service", "\\xc3\\xbcxkn\\xc3\\xbcrz.service", 1); + test_unit_name_mangle_one(false, "foobar-meh...waldi.service", "foobar-meh...waldi.service", 0); + test_unit_name_mangle_one(false, "_____####----.....service", "_____\\x23\\x23\\x23\\x23----.....service", 1); + test_unit_name_mangle_one(false, "_____##@;;;,,,##----.....service", "_____\\x23\\x23@\\x3b\\x3b\\x3b\\x2c\\x2c\\x2c\\x23\\x23----.....service", 1); + test_unit_name_mangle_one(false, "xxx@@@@/////\\\\\\\\\\yyy.service", "xxx@@@@-----\\\\\\\\\\yyy.service", 1); + test_unit_name_mangle_one(false, "", NULL, -EINVAL); + + test_unit_name_mangle_one(true, "foo.service", "foo.service", 0); + test_unit_name_mangle_one(true, "foo", "foo.service", 1); + test_unit_name_mangle_one(true, "foo*", "foo*", 0); + test_unit_name_mangle_one(true, "ü*", "\\xc3\\xbc*", 1); } static int test_unit_printf(void) { diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c index 3d7cfd5be5..7ec23904db 100644 --- a/src/timesync/timesyncd.c +++ b/src/timesync/timesyncd.c @@ -71,7 +71,8 @@ static int load_clock_timestamp(uid_t uid, gid_t gid) { } } else { - r = mkdir_safe_label("/var/lib/systemd/timesync", 0755, uid, gid, true); + r = mkdir_safe_label("/var/lib/systemd/timesync", 0755, uid, gid, + MKDIR_FOLLOW_SYMLINK | MKDIR_WARN_MODE); if (r < 0) return log_error_errno(r, "Failed to create state directory: %m"); diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index f1890f3261..b56b7ac963 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -310,8 +310,7 @@ static int user_config_paths(char*** ret) { if (r < 0) return r; - *ret = res; - res = NULL; + *ret = TAKE_PTR(res); return 0; } @@ -822,7 +821,7 @@ static int fd_set_perms(Item *i, int fd, const struct stat *st) { if (m == (st->st_mode & 07777)) log_debug("\"%s\" has correct mode %o already.", path, st->st_mode); else { - char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; + char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; log_debug("Changing \"%s\" to mode %o.", path, m); @@ -921,7 +920,7 @@ static int parse_xattrs_from_arg(Item *i) { } static int fd_set_xattrs(Item *i, int fd, const struct stat *st) { - char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; + char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; _cleanup_free_ char *path = NULL; char **name, **value; int r; @@ -1025,7 +1024,7 @@ static int path_set_acl(const char *path, const char *pretty, acl_type_t type, a static int fd_set_acls(Item *item, int fd, const struct stat *st) { int r = 0; #if HAVE_ACL - char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; + char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; _cleanup_free_ char *path = NULL; assert(item); @@ -1187,7 +1186,7 @@ static int parse_attribute_from_arg(Item *item) { } static int fd_set_attribute(Item *item, int fd, const struct stat *st) { - char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; + char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; _cleanup_close_ int procfs_fd = -1; _cleanup_free_ char *path = NULL; unsigned f; diff --git a/src/udev/meson.build b/src/udev/meson.build index de2fd2d9c4..7b5e326d76 100644 --- a/src/udev/meson.build +++ b/src/udev/meson.build @@ -63,7 +63,7 @@ endif if conf.get('HAVE_ACL') == 1 libudev_core_sources += ['udev-builtin-uaccess.c', - logind_acl_c, + logind_acl_c, sd_login_c] endif diff --git a/src/udev/net/ethtool-util.c b/src/udev/net/ethtool-util.c index 1fdfc85408..69ac3e8c58 100644 --- a/src/udev/net/ethtool-util.c +++ b/src/udev/net/ethtool-util.c @@ -304,8 +304,7 @@ static int get_stringset(int fd, struct ifreq *ifr, int stringset_id, struct eth if (r < 0) return -errno; - *gstrings = strings; - strings = NULL; + *gstrings = TAKE_PTR(strings); return 0; } diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c index dbfe024298..b95465b3e3 100644 --- a/src/udev/udev-builtin-hwdb.c +++ b/src/udev/udev-builtin-hwdb.c @@ -73,9 +73,9 @@ static const char *modalias_usb(struct udev_device *dev, char *s, size_t size) { if (!p) return NULL; if (safe_atoux16(v, &vn) < 0) - return NULL; + return NULL; if (safe_atoux16(p, &pn) < 0) - return NULL; + return NULL; snprintf(s, size, "usb:v%04Xp%04X*", vn, pn); return s; } diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c index 02b86cce23..4d5b1233f1 100644 --- a/src/udev/udev-builtin-input_id.c +++ b/src/udev/udev-builtin-input_id.c @@ -195,15 +195,23 @@ static bool test_pointers(struct udev_device *dev, has_mt_coordinates = false; is_direct = test_bit(INPUT_PROP_DIRECT, bitmask_props); has_touch = test_bit(BTN_TOUCH, bitmask_key); + /* joysticks don't necessarily have buttons; e. g. * rudders/pedals are joystick-like, but buttonless; they have - * other fancy axes. Others have buttons only but no axes. */ - for (button = BTN_JOYSTICK; button < BTN_DIGI && !has_joystick_axes_or_buttons; button++) - has_joystick_axes_or_buttons = test_bit(button, bitmask_key); - for (button = BTN_TRIGGER_HAPPY1; button <= BTN_TRIGGER_HAPPY40 && !has_joystick_axes_or_buttons; button++) - has_joystick_axes_or_buttons = test_bit(button, bitmask_key); - for (button = BTN_DPAD_UP; button <= BTN_DPAD_RIGHT && !has_joystick_axes_or_buttons; button++) - has_joystick_axes_or_buttons = test_bit(button, bitmask_key); + * other fancy axes. Others have buttons only but no axes. + * + * The BTN_JOYSTICK range starts after the mouse range, so a mouse + * with more than 16 buttons runs into the joystick range (e.g. Mad + * Catz Mad Catz M.M.O.TE). Skip those. + */ + if (!test_bit(BTN_JOYSTICK - 1, bitmask_key)) { + for (button = BTN_JOYSTICK; button < BTN_DIGI && !has_joystick_axes_or_buttons; button++) + has_joystick_axes_or_buttons = test_bit(button, bitmask_key); + for (button = BTN_TRIGGER_HAPPY1; button <= BTN_TRIGGER_HAPPY40 && !has_joystick_axes_or_buttons; button++) + has_joystick_axes_or_buttons = test_bit(button, bitmask_key); + for (button = BTN_DPAD_UP; button <= BTN_DPAD_RIGHT && !has_joystick_axes_or_buttons; button++) + has_joystick_axes_or_buttons = test_bit(button, bitmask_key); + } for (axis = ABS_RX; axis < ABS_PRESSURE && !has_joystick_axes_or_buttons; axis++) has_joystick_axes_or_buttons = test_bit(axis, bitmask_abs); diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c index 0a32363deb..7d967e04de 100644 --- a/src/udev/udev-builtin-path_id.c +++ b/src/udev/udev-builtin-path_id.c @@ -62,10 +62,8 @@ static void path_prepend(char **path, const char *fmt, ...) { } free_and_replace(*path, new); - } else { - *path = pre; - pre = NULL; - } + } else + *path = TAKE_PTR(pre); } /* diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 615c4ed3e2..34976b30e0 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -233,8 +233,7 @@ static int worker_new(struct worker **ret, Manager *manager, struct udev_monitor if (r < 0) return r; - *ret = worker; - worker = NULL; + *ret = TAKE_PTR(worker); return 0; } diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index a9cc2bf63c..e7fced247d 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -49,35 +49,42 @@ #include "virt.h" static int verify_vc_device(int fd) { - unsigned char data[1]; + unsigned char data[] = { + TIOCL_GETFGCONSOLE, + }; + int r; - data[0] = TIOCL_GETFGCONSOLE; r = ioctl(fd, TIOCLINUX, data); - return r < 0 ? -errno : r; + if (r < 0) + return -errno; + + return r; } static int verify_vc_allocation(unsigned idx) { char vcname[sizeof("/dev/vcs") + DECIMAL_STR_MAX(unsigned) - 2]; - int r; xsprintf(vcname, "/dev/vcs%u", idx); - r = access(vcname, F_OK); - return r < 0 ? -errno : r; + + if (access(vcname, F_OK) < 0) + return -errno; + + return 0; } static int verify_vc_allocation_byfd(int fd) { struct vt_stat vcs = {}; - int r; - r = ioctl(fd, VT_GETSTATE, &vcs); - return r < 0 ? -errno : verify_vc_allocation(vcs.v_active); + if (ioctl(fd, VT_GETSTATE, &vcs) < 0) + return -errno; + + return verify_vc_allocation(vcs.v_active); } static int verify_vc_kbmode(int fd) { - int r, curr_mode; + int curr_mode; - r = ioctl(fd, KDGKBMODE, &curr_mode); /* * Make sure we only adjust consoles in K_XLATE or K_UNICODE mode. * Otherwise we would (likely) interfere with X11's processing of the @@ -85,7 +92,8 @@ static int verify_vc_kbmode(int fd) { * * http://lists.freedesktop.org/archives/systemd-devel/2013-February/008573.html */ - if (r < 0) + + if (ioctl(fd, KDGKBMODE, &curr_mode) < 0) return -errno; return IN_SET(curr_mode, K_XLATE, K_UNICODE) ? 0 : -EBUSY; @@ -129,7 +137,6 @@ static int toggle_utf8_sysfs(bool utf8) { } static int keyboard_load_and_wait(const char *vc, const char *map, const char *map_toggle, bool utf8) { - _cleanup_free_ char *cmd = NULL; const char *args[8]; unsigned i = 0; pid_t pid; @@ -150,8 +157,12 @@ static int keyboard_load_and_wait(const char *vc, const char *map, const char *m args[i++] = map_toggle; args[i++] = NULL; - log_debug("Executing \"%s\"...", - strnull((cmd = strv_join((char**) args, " ")))); + if (DEBUG_LOGGING) { + _cleanup_free_ char *cmd; + + cmd = strv_join((char**) args, " "); + log_debug("Executing \"%s\"...", strnull(cmd)); + } r = safe_fork("(loadkeys)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG, &pid); if (r < 0) @@ -165,7 +176,6 @@ static int keyboard_load_and_wait(const char *vc, const char *map, const char *m } static int font_load_and_wait(const char *vc, const char *font, const char *map, const char *unimap) { - _cleanup_free_ char *cmd = NULL; const char *args[9]; unsigned i = 0; pid_t pid; @@ -190,8 +200,12 @@ static int font_load_and_wait(const char *vc, const char *font, const char *map, args[i++] = font; args[i++] = NULL; - log_debug("Executing \"%s\"...", - strnull((cmd = strv_join((char**) args, " ")))); + if (DEBUG_LOGGING) { + _cleanup_free_ char *cmd; + + cmd = strv_join((char**) args, " "); + log_debug("Executing \"%s\"...", strnull(cmd)); + } r = safe_fork("(setfont)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG, &pid); if (r < 0) @@ -325,8 +339,8 @@ static void setup_remaining_vcs(int src_fd, unsigned src_idx, bool utf8) { static int find_source_vc(char **ret_path, unsigned *ret_idx) { _cleanup_free_ char *path = NULL; + int r, err = 0; unsigned i; - int ret_fd, r, err = 0; path = new(char, sizeof("/dev/tty63")); if (!path) @@ -358,20 +372,17 @@ static int find_source_vc(char **ret_path, unsigned *ret_idx) { /* all checks passed, return this one as a source console */ *ret_idx = i; - *ret_path = path; - path = NULL; - ret_fd = fd; - fd = -1; - return ret_fd; + *ret_path = TAKE_PTR(path); + return TAKE_FD(fd); } return log_error_errno(err, "No usable source console found: %m"); } static int verify_source_vc(char **ret_path, const char *src_vc) { - char *path; _cleanup_close_ int fd = -1; - int ret_fd, r; + char *path; + int r; fd = open_terminal(src_vc, O_RDWR|O_CLOEXEC|O_NOCTTY); if (fd < 0) @@ -394,9 +405,7 @@ static int verify_source_vc(char **ret_path, const char *src_vc) { return log_oom(); *ret_path = path; - ret_fd = fd; - fd = -1; - return ret_fd; + return TAKE_FD(fd); } int main(int argc, char **argv) { @@ -419,7 +428,6 @@ int main(int argc, char **argv) { fd = verify_source_vc(&vc, argv[1]); else fd = find_source_vc(&vc, &idx); - if (fd < 0) return EXIT_FAILURE; diff --git a/test/TEST-06-SELINUX/test.sh b/test/TEST-06-SELINUX/test.sh index e0c4c10e1c..18856c2459 100755 --- a/test/TEST-06-SELINUX/test.sh +++ b/test/TEST-06-SELINUX/test.sh @@ -10,6 +10,9 @@ TEST_NO_NSPAWN=1 # selinux-policy-targeted # selinux-policy-devel +# Check if selinux-policy-devel is installed, and if it isn't bail out early instead of failing +test -d /usr/share/selinux/devel || exit 0 + . $TEST_BASE_DIR/test-functions SETUP_SELINUX=yes KERNEL_APPEND="$KERNEL_APPEND selinux=1 security=selinux" diff --git a/test/fuzz-corpus/unit-file/directives.service b/test/fuzz-corpus/unit-file/directives.service index 0077ae739b..c2334d3b19 100644 --- a/test/fuzz-corpus/unit-file/directives.service +++ b/test/fuzz-corpus/unit-file/directives.service @@ -809,6 +809,7 @@ MountFlags= NAME= NAutoVTs= Nice= +NoNewPrivileges= NotifyReady= OOMScoreAdjust= Overlay= diff --git a/test/meson.build b/test/meson.build index 99103e9570..809bd44a93 100644 --- a/test/meson.build +++ b/test/meson.build @@ -233,9 +233,13 @@ custom_target( output : 'sys', build_by_default : true) -udev_test_pl = find_program('udev-test.pl') -test('udev-test', - udev_test_pl) +if perl.found() + udev_test_pl = find_program('udev-test.pl') + test('udev-test', + udev_test_pl) +else + message('Skipping udev-test because perl is not available') +endif if conf.get('ENABLE_HWDB') == 1 hwdb_test_sh = find_program('hwdb-test.sh') diff --git a/test/run-integration-tests.sh b/test/run-integration-tests.sh index 7d70be3fea..94df346c28 100755 --- a/test/run-integration-tests.sh +++ b/test/run-integration-tests.sh @@ -11,14 +11,16 @@ ninja -C "$BUILD_DIR" declare -A results -RESULT=0 +COUNT=0 FAILURES=0 cd "$(dirname "$0")" for TEST in TEST-??-* ; do - echo -e "\n--x-- Starting $TEST --x--" + COUNT=$(($COUNT+1)) + + echo -e "\n--x-- Running $TEST --x--" set +e - make -C "$TEST" "BUILD_DIR=$BUILD_DIR" $args + ( set -x ; make -C "$TEST" "BUILD_DIR=$BUILD_DIR" $args ) RESULT=$? set -e echo "--x-- Result of $TEST: $RESULT --x--" @@ -40,9 +42,9 @@ for TEST in ${!results[@]}; do done | sort if [ "$FAILURES" -eq 0 ] ; then - echo -e "\nALL PASSED" + echo -e "\nALL $COUNT TESTS PASSED" else - echo -e "\nTOTAL FAILURES: $FAILURES" + echo -e "\nTOTAL FAILURES: $FAILURES OF $COUNT" fi exit "$FAILURES" diff --git a/test/test-execute/exec-capabilityboundingset-invert.service b/test/test-execute/exec-capabilityboundingset-invert.service index fd5d248702..1abe390601 100644 --- a/test/test-execute/exec-capabilityboundingset-invert.service +++ b/test/test-execute/exec-capabilityboundingset-invert.service @@ -2,6 +2,6 @@ Description=Test for CapabilityBoundingSet [Service] -ExecStart=/bin/sh -x -c 'c=$$(capsh --print | grep "^Bounding set .*cap_chown"); test -z "$$c"' +ExecStart=/bin/sh -x -c '! capsh --print | grep "^Bounding set .*cap_chown"' Type=oneshot CapabilityBoundingSet=~CAP_CHOWN diff --git a/test/test-execute/exec-privatenetwork-yes.service b/test/test-execute/exec-privatenetwork-yes.service index 3df543ec93..a38d24912f 100644 --- a/test/test-execute/exec-privatenetwork-yes.service +++ b/test/test-execute/exec-privatenetwork-yes.service @@ -2,6 +2,6 @@ Description=Test for PrivateNetwork [Service] -ExecStart=/bin/sh -x -c 'i=$$(ip link | grep ": " | grep -v ": lo:"); test -z "$$i"' +ExecStart=/bin/sh -x -c '! ip link | grep ": " | grep -Ev ": (lo|sit0@.*):"' Type=oneshot PrivateNetwork=yes diff --git a/test/test-execute/exec-specifier-interpolation.service b/test/test-execute/exec-specifier-interpolation.service index 3e62662aa9..f128e3c4b3 100644 --- a/test/test-execute/exec-specifier-interpolation.service +++ b/test/test-execute/exec-specifier-interpolation.service @@ -3,4 +3,4 @@ Description=https://github.com/systemd/systemd/issues/2637 [Service] Type=oneshot -ExecStart=/bin/sh -x -c "perl -e 'exit(!(qq{%%U} eq qq{\\x25U}))'" +ExecStart=/bin/sh -x -c "! test -x perl || perl -e 'exit(!(qq{%%U} eq qq{\\x25U}))'" diff --git a/units/systemd-time-wait-sync.service.in b/units/systemd-time-wait-sync.service.in index 352705d1a1..475182d6bc 100644 --- a/units/systemd-time-wait-sync.service.in +++ b/units/systemd-time-wait-sync.service.in @@ -10,6 +10,17 @@ [Unit] Description=Wait Until Kernel Time Synchronized Documentation=man:systemd-time-wait-sync.service(8) + +# Note that this tool doesn't need CAP_SYS_TIME itself, but it's primary +# usecase is to run in conjunction with a local NTP service such as +# systemd-timesyncd.service, which is conditioned this way. There might be +# niche usecases where running this service independently is desired, but let's +# make this all "just work" for the general case, and leave it to local +# modifications to make it work in the remaining cases. + +ConditionCapability=CAP_SYS_TIME +ConditionVirtualization=!container + DefaultDependencies=no Before=time-sync.target shutdown.target Wants=time-sync.target |