]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fileio: port write_string_file() to LabelOps, and thus add WRITE_STRING_FILE_LABEL...
authorLennart Poettering <lennart@poettering.net>
Tue, 22 Oct 2024 08:09:20 +0000 (10:09 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 22 Oct 2024 15:51:26 +0000 (17:51 +0200)
Given that we have the LabelOps abstraction these days, we can teach
write_string_file() to use it, which means we can get rid of
fileio-label.[ch] as a separate concept.

(The only reason that fileio-label.[ch] exists independently of
fileio.[ch] was that the former linekd to libselinux potentially, and
thus had to be in src/shared/ while the other always was in src/basic/.
But the LabelOps vtable provides us with a nice work-around)

13 files changed:
src/basic/fileio.c
src/basic/fileio.h
src/core/unit-serialize.c
src/core/unit.c
src/debug-generator/debug-generator.c
src/hostname/hostnamed.c
src/locale/localed-util.c
src/login/logind-dbus.c
src/shared/dropin.c
src/shared/fileio-label.c
src/shared/fileio-label.h
src/timedate/timedated.c
src/update-done/update-done.c

index bf1603de0ea5608a1fead7032c2c4a6fbbd9422b..891fe065d14d8238d9d55c672e84272a94f104c1 100644 (file)
@@ -18,6 +18,7 @@
 #include "fileio.h"
 #include "fs-util.h"
 #include "hexdecoct.h"
+#include "label.h"
 #include "log.h"
 #include "macro.h"
 #include "mkdir.h"
@@ -230,22 +231,40 @@ static int write_string_file_atomic_at(
         /* Note that we'd really like to use O_TMPFILE here, but can't really, since we want replacement
          * semantics here, and O_TMPFILE can't offer that. i.e. rename() replaces but linkat() doesn't. */
 
+        mode_t mode = write_string_file_flags_to_mode(flags);
+
+        bool call_label_ops_post = false;
+        if (FLAGS_SET(flags, WRITE_STRING_FILE_LABEL)) {
+                r = label_ops_pre(dir_fd, fn, mode);
+                if (r < 0)
+                        return r;
+
+                call_label_ops_post = true;
+        }
+
         r = fopen_temporary_at(dir_fd, fn, &f, &p);
         if (r < 0)
-                return r;
+                goto fail;
+
+        if (call_label_ops_post) {
+                call_label_ops_post = false;
+
+                r = label_ops_post(fileno(f), /* path= */ NULL, /* created= */ true);
+                if (r < 0)
+                        goto fail;
+        }
 
         r = write_string_stream_full(f, line, flags, ts);
         if (r < 0)
                 goto fail;
 
-        r = fchmod_umask(fileno(f), write_string_file_flags_to_mode(flags));
+        r = fchmod_umask(fileno(f), mode);
         if (r < 0)
                 goto fail;
 
-        if (renameat(dir_fd, p, dir_fd, fn) < 0) {
-                r = -errno;
+        r = RET_NERRNO(renameat(dir_fd, p, dir_fd, fn));
+        if (r < 0)
                 goto fail;
-        }
 
         if (FLAGS_SET(flags, WRITE_STRING_FILE_SYNC)) {
                 /* Sync the rename, too */
@@ -257,7 +276,11 @@ static int write_string_file_atomic_at(
         return 0;
 
 fail:
-        (void) unlinkat(dir_fd, p, 0);
+        if (call_label_ops_post)
+                (void) label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fn, /* created= */ !!f);
+
+        if (f)
+                (void) unlinkat(dir_fd, p, 0);
         return r;
 }
 
@@ -268,9 +291,10 @@ int write_string_file_full(
                 WriteStringFileFlags flags,
                 const struct timespec *ts) {
 
+        bool call_label_ops_post = false;
         _cleanup_fclose_ FILE *f = NULL;
         _cleanup_close_ int fd = -EBADF;
-        int q, r;
+        int r;
 
         assert(fn);
         assert(line);
@@ -292,8 +316,17 @@ int write_string_file_full(
                         goto fail;
 
                 return r;
-        } else
-                assert(!ts);
+        }
+
+        mode_t mode = write_string_file_flags_to_mode(flags);
+
+        if (FLAGS_SET(flags, WRITE_STRING_FILE_LABEL|WRITE_STRING_FILE_CREATE)) {
+                r = label_ops_pre(dir_fd, fn, mode);
+                if (r < 0)
+                        goto fail;
+
+                call_label_ops_post = true;
+        }
 
         /* We manually build our own version of fopen(..., "we") that works without O_CREAT and with O_NOFOLLOW if needed. */
         fd = openat(dir_fd, fn, O_CLOEXEC|O_NOCTTY |
@@ -301,12 +334,20 @@ int write_string_file_full(
                     (FLAGS_SET(flags, WRITE_STRING_FILE_CREATE) ? O_CREAT : 0) |
                     (FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0) |
                     (FLAGS_SET(flags, WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) ? O_RDWR : O_WRONLY),
-                    write_string_file_flags_to_mode(flags));
+                    mode);
         if (fd < 0) {
                 r = -errno;
                 goto fail;
         }
 
+        if (call_label_ops_post) {
+                call_label_ops_post = false;
+
+                r = label_ops_post(fd, /* path= */ NULL, /* created= */ true);
+                if (r < 0)
+                        goto fail;
+        }
+
         r = take_fdopen_unlocked(&fd, "w", &f);
         if (r < 0)
                 goto fail;
@@ -321,19 +362,21 @@ int write_string_file_full(
         return 0;
 
 fail:
+        if (call_label_ops_post)
+                (void) label_ops_post(fd >= 0 ? fd : dir_fd, fd >= 0 ? NULL : fn, /* created= */ true);
+
         if (!(flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE))
                 return r;
 
         f = safe_fclose(f);
+        fd = safe_close(fd);
 
-        /* OK, the operation failed, but let's see if the right
-         * contents in place already. If so, eat up the error. */
-
-        q = verify_file(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) || (flags & WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE));
-        if (q <= 0)
-                return r;
+        /* OK, the operation failed, but let's see if the right contents in place already. If so, eat up the
+         * error. */
+        if (verify_file(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) || (flags & WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE)) > 0)
+                return 0;
 
-        return 0;
+        return r;
 }
 
 int write_string_filef(
index dc514e3cccc0091d33c7f26e2dc5778efcd8787d..8f54491c12c512bdf5a35ca459f2b618fa5a2c9f 100644 (file)
@@ -28,11 +28,7 @@ typedef enum {
         WRITE_STRING_FILE_MODE_0600                  = 1 << 10,
         WRITE_STRING_FILE_MODE_0444                  = 1 << 11,
         WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL = 1 << 12,
-
-        /* And before you wonder, why write_string_file_atomic_label_ts() is a separate function instead of just one
-           more flag here: it's about linking: we don't want to pull -lselinux into all users of write_string_file()
-           and friends. */
-
+        WRITE_STRING_FILE_LABEL                      = 1 << 13,
 } WriteStringFileFlags;
 
 typedef enum {
index f96bae19f9e4b21f2ec3b200dff4996af2c5ecb3..ec1d3df32f4ce480b425669975437b6c13cb0bf9 100644 (file)
@@ -4,7 +4,6 @@
 #include "bpf-socket-bind.h"
 #include "bus-util.h"
 #include "dbus.h"
-#include "fileio-label.h"
 #include "fileio.h"
 #include "format-util.h"
 #include "parse-util.h"
index 4384e3bfcbf2830a3c4c2fc7e83c80d36baf32af..64ce5967f407897f1cfca59be8f7565de914d2a3 100644 (file)
@@ -29,7 +29,6 @@
 #include "exec-credential.h"
 #include "execute.h"
 #include "fd-util.h"
-#include "fileio-label.h"
 #include "fileio.h"
 #include "format-util.h"
 #include "id128-util.h"
@@ -4620,7 +4619,7 @@ int unit_write_setting(Unit *u, UnitWriteFlags flags, const char *name, const ch
                         return r;
         }
 
-        r = write_string_file_atomic_label(q, wrapped);
+        r = write_string_file(q, wrapped, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
         if (r < 0)
                 return r;
 
index 98670a6c906a507747ecf7a7f43a1341d7b4470d..664d57d452fc45120a02289f0fd855e149d1e205 100644 (file)
@@ -7,7 +7,7 @@
 #include "dropin.h"
 #include "errno-util.h"
 #include "fd-util.h"
-#include "fileio-label.h"
+#include "fileio.h"
 #include "generator.h"
 #include "initrd-util.h"
 #include "parse-util.h"
@@ -206,7 +206,7 @@ static int process_unit_credentials(const char *credentials_dir) {
                         if (!p)
                                 return log_oom();
 
-                        r = write_string_file_at_label(AT_FDCWD, p, d, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755);
+                        r = write_string_file(p, d, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755|WRITE_STRING_FILE_LABEL);
                         if (r < 0) {
                                 log_warning_errno(r, "Failed to write unit file '%s' from credential '%s', ignoring: %m",
                                                   unit, de->d_name);
index df0ebe8daab210409b9234836f3d100990c956d9..d2444dbf2df2e96faf3933157e37229fe72a6110 100644 (file)
@@ -19,7 +19,6 @@
 #include "env-file-label.h"
 #include "env-file.h"
 #include "env-util.h"
-#include "fileio-label.h"
 #include "fileio.h"
 #include "hostname-setup.h"
 #include "hostname-util.h"
@@ -619,7 +618,7 @@ static int context_write_data_static_hostname(Context *c) {
                 return 0;
         }
 
-        r = write_string_file_atomic_label("/etc/hostname", c->data[PROP_STATIC_HOSTNAME]);
+        r = write_string_file("/etc/hostname", c->data[PROP_STATIC_HOSTNAME], WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
         if (r < 0)
                 return r;
 
index 56996596fe13ce07134f498aef25a73ac6503cab..6413288ea3d5f85345b75cde6e035d274d771f23 100644 (file)
@@ -11,7 +11,6 @@
 #include "env-file.h"
 #include "env-util.h"
 #include "fd-util.h"
-#include "fileio-label.h"
 #include "fileio.h"
 #include "fs-util.h"
 #include "kbd-util.h"
index 35549e663a085c5de89956181a64de1bc9d24d50..9582fb47dfa59fa2e49a23d16dd4cb0d06646299 100644 (file)
@@ -29,8 +29,8 @@
 #include "escape.h"
 #include "event-util.h"
 #include "fd-util.h"
-#include "fileio-label.h"
 #include "fileio.h"
+#include "fileio-label.h"
 #include "format-util.h"
 #include "fs-util.h"
 #include "logind-action.h"
@@ -1593,7 +1593,7 @@ static int trigger_device(Manager *m, sd_device *parent) {
 
 static int attach_device(Manager *m, const char *seat, const char *sysfs, sd_bus_error *error) {
         _cleanup_(sd_device_unrefp) sd_device *d = NULL;
-        _cleanup_free_ char *rule = NULL, *file = NULL;
+        _cleanup_free_ char *file = NULL;
         const char *id_for_seat;
         int r;
 
@@ -1614,11 +1614,10 @@ static int attach_device(Manager *m, const char *seat, const char *sysfs, sd_bus
         if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
                 return -ENOMEM;
 
-        if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
-                return -ENOMEM;
-
-        (void) mkdir_p_label("/etc/udev/rules.d", 0755);
-        r = write_string_file_atomic_label(file, rule);
+        r = write_string_filef(
+                        file,
+                        WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755|WRITE_STRING_FILE_LABEL,
+                        "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat);
         if (r < 0)
                 return r;
 
@@ -3286,11 +3285,9 @@ static int method_set_reboot_to_boot_loader_menu(
                         if (unlink("/run/systemd/reboot-to-boot-loader-menu") < 0 && errno != ENOENT)
                                 return -errno;
                 } else {
-                        char buf[DECIMAL_STR_MAX(uint64_t) + 1];
-
-                        xsprintf(buf, "%" PRIu64, x); /* μs granularity */
-
-                        r = write_string_file_atomic_label("/run/systemd/reboot-to-boot-loader-menu", buf);
+                        r = write_string_filef("/run/systemd/reboot-to-boot-loader-menu",
+                                               WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL,
+                                               "%" PRIu64, x); /* μs granularity */
                         if (r < 0)
                                 return r;
                 }
@@ -3479,7 +3476,7 @@ static int method_set_reboot_to_boot_loader_entry(
                         if (unlink("/run/systemd/reboot-to-boot-loader-entry") < 0 && errno != ENOENT)
                                 return -errno;
                 } else {
-                        r = write_string_file_atomic_label("/run/systemd/reboot-boot-to-loader-entry", v);
+                        r = write_string_file("/run/systemd/reboot-boot-to-loader-entry", v, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
                         if (r < 0)
                                 return r;
                 }
index 3e1eaa6623606fffc7cab0fca77f048d1c31fff3..2e285f8eb62e698b54967f21ba5915aff14f68e2 100644 (file)
@@ -12,7 +12,7 @@
 #include "dropin.h"
 #include "escape.h"
 #include "fd-util.h"
-#include "fileio-label.h"
+#include "fileio.h"
 #include "hashmap.h"
 #include "log.h"
 #include "macro.h"
@@ -87,7 +87,7 @@ int write_drop_in(
         if (r < 0)
                 return r;
 
-        return write_string_file_at_label(AT_FDCWD, p, data, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755);
+        return write_string_file(p, data, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755|WRITE_STRING_FILE_LABEL);
 }
 
 int write_drop_in_format(
index 39de54fa25676c875d1a97675381f7b1f5abfa33..69ea82cf032fdb681ae9dd3fa9b99024aeee9364 100644 (file)
@@ -6,20 +6,6 @@
 #include "fileio.h"
 #include "selinux-util.h"
 
-int write_string_file_full_label(int atfd, const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts) {
-        int r;
-
-        r = mac_selinux_create_file_prepare_at(atfd, fn, S_IFREG);
-        if (r < 0)
-                return r;
-
-        r = write_string_file_full(atfd, fn, line, flags, ts);
-
-        mac_selinux_create_file_clear();
-
-        return r;
-}
-
 int create_shutdown_run_nologin_or_warn(void) {
         int r;
 
@@ -33,9 +19,10 @@ int create_shutdown_run_nologin_or_warn(void) {
          * 13 years later we stopped managing /etc/nologin, leaving it for the administrator to manage.
          */
 
-        r = write_string_file_atomic_label("/run/nologin",
-                                           "System is going down. Unprivileged users are not permitted to log in anymore. "
-                                           "For technical details, see pam_nologin(8).");
+        r = write_string_file("/run/nologin",
+                              "System is going down. Unprivileged users are not permitted to log in anymore. "
+                              "For technical details, see pam_nologin(8).",
+                              WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
         if (r < 0)
                 return log_error_errno(r, "Failed to create /run/nologin: %m");
 
index 5aa5c40224e7dd8d8faf5f43669221b570a757ec..9fbe0f42e56334be7a9d058d20296a75612d890f 100644 (file)
@@ -9,12 +9,4 @@
 
 #include "fileio.h"
 
-int write_string_file_full_label(int atfd, const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts);
-static inline int write_string_file_at_label(int atfd, const char *fn, const char *line, WriteStringFileFlags flags) {
-        return write_string_file_full_label(atfd, fn, line, flags, /* ts= */ NULL);
-}
-static inline int write_string_file_atomic_label(const char *fn, const char *line) {
-        return write_string_file_at_label(AT_FDCWD, fn, line, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
-}
-
 int create_shutdown_run_nologin_or_warn(void);
index ea99a77c85f10362a27d223ecc7a435ee52171df..c79bb864df0e5bda56a4db94f7df420ce3856d5f 100644 (file)
@@ -24,7 +24,6 @@
 #include "constants.h"
 #include "daemon-util.h"
 #include "fd-util.h"
-#include "fileio-label.h"
 #include "fileio.h"
 #include "fs-util.h"
 #include "hashmap.h"
@@ -395,7 +394,7 @@ static int context_write_data_local_rtc(Context *c) {
         if (r < 0)
                 return r;
 
-        return write_string_file_atomic_label("/etc/adjtime", w);
+        return write_string_file("/etc/adjtime", w, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
 }
 
 static int context_update_ntp_status(Context *c, sd_bus *bus, sd_bus_message *m) {
index 436bae639b27b4d6b5b74840c74741b3edb73861..277d2860b9a05f45b40ab105e8796528a6cfd9bc 100644 (file)
@@ -5,7 +5,7 @@
 #include <unistd.h>
 
 #include "alloc-util.h"
-#include "fileio-label.h"
+#include "fileio.h"
 #include "selinux-util.h"
 #include "time-util.h"
 
@@ -29,7 +29,7 @@ static int apply_timestamp(const char *path, struct timespec *ts) {
                      timespec_load_nsec(ts)) < 0)
                 return log_oom();
 
-        r = write_string_file_full_label(AT_FDCWD, path, message, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC, ts);
+        r = write_string_file_full(AT_FDCWD, path, message, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL, ts);
         if (r == -EROFS)
                 log_debug_errno(r, "Cannot create \"%s\", file system is read-only.", path);
         else if (r < 0)