]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
stat-util: also add stat_verify_char() and use it everywhere
authorLennart Poettering <lennart@amutable.com>
Mon, 13 Apr 2026 09:20:57 +0000 (11:20 +0200)
committerLennart Poettering <lennart@amutable.com>
Mon, 13 Apr 2026 11:20:43 +0000 (13:20 +0200)
src/basic/stat-util.c
src/basic/stat-util.h
src/basic/terminal-util.c
src/core/manager.c
src/shared/watchdog.c

index 2bdd8af21dc9e7ccfb4b874d7c530f8fdce264f8..116b36a346fe622e1edefcb5bc54d5fdf3e54f3b 100644 (file)
@@ -225,6 +225,21 @@ int fd_verify_block(int fd) {
         return verify_stat_at(fd, /* path= */ NULL, /* follow= */ false, stat_verify_block, /* verify= */ true);
 }
 
+int stat_verify_char(const struct stat *st) {
+        assert(st);
+
+        if (S_ISDIR(st->st_mode))
+                return -EISDIR;
+
+        if (S_ISLNK(st->st_mode))
+                return -ELOOP;
+
+        if (!S_ISCHR(st->st_mode))
+                return -EBADFD;
+
+        return 0;
+}
+
 int stat_verify_device_node(const struct stat *st) {
         assert(st);
 
index 55bc5b6c7eac0d2a2ddf791c726e5d540ec54a5f..ec04a2b80cd08644a93f99507e67b9e51612cade 100644 (file)
@@ -31,6 +31,8 @@ int fd_verify_linked(int fd);
 int stat_verify_block(const struct stat *st);
 int fd_verify_block(int fd);
 
+int stat_verify_char(const struct stat *st);
+
 int stat_verify_device_node(const struct stat *st);
 int is_device_node(const char *path);
 
index ecdc2412472860372c3efbdf9654973b5542e12b..d7ff92ae89247fd7a8ab2d92a772066aba592147 100644 (file)
@@ -1861,6 +1861,8 @@ int terminal_set_cursor_position(int fd, unsigned row, unsigned column) {
 }
 
 static int terminal_verify_same(int input_fd, int output_fd) {
+        int r;
+
         assert(input_fd >= 0);
         assert(output_fd >= 0);
 
@@ -1871,15 +1873,17 @@ static int terminal_verify_same(int input_fd, int output_fd) {
                 if (fstat(input_fd, &sti) < 0)
                         return -errno;
 
-                if (!S_ISCHR(sti.st_mode)) /* TTYs are character devices */
-                        return -ENOTTY;
+                r = stat_verify_char(&sti); /* TTYs are character devices */
+                if (r < 0)
+                        return r;
 
                 struct stat sto;
                 if (fstat(output_fd, &sto) < 0)
                         return -errno;
 
-                if (!S_ISCHR(sto.st_mode))
-                        return -ENOTTY;
+                r = stat_verify_char(&sto);
+                if (r < 0)
+                        return r;
 
                 if (sti.st_rdev != sto.st_rdev)
                         return -ENOLINK;
index 73368ec18aec960158f664c1843303db489c4670..8db6c471a1206616860a65cf4643242fa8ba5898 100644 (file)
@@ -4519,10 +4519,9 @@ const char* manager_get_confirm_spawn(Manager *m) {
                 goto fail;
         }
 
-        if (!S_ISCHR(st.st_mode)) {
-                r = -ENOTTY;
+        r = stat_verify_char(&st);
+        if (r < 0)
                 goto fail;
-        }
 
         last_errno = 0;
         return m->confirm_spawn;
index 5b113013950f794e6b23fc6512dacdd236c3eac6..8b74bb4bbde6b4b53d1f978541bac6565478d9b3 100644 (file)
@@ -17,6 +17,7 @@
 #include "log.h"
 #include "path-util.h"
 #include "ratelimit.h"
+#include "stat-util.h"
 #include "string-util.h"
 #include "strv.h"
 #include "time-util.h"
@@ -55,6 +56,7 @@ static int saturated_usec_to_sec(usec_t val) {
 
 static int watchdog_get_sysfs_path(const char *filename, char **ret_path) {
         struct stat st;
+        int r;
 
         if (watchdog_fd < 0)
                 return -EBADF;
@@ -62,8 +64,9 @@ static int watchdog_get_sysfs_path(const char *filename, char **ret_path) {
         if (fstat(watchdog_fd, &st))
                 return -errno;
 
-        if (!S_ISCHR(st.st_mode))
-                return -EBADF;
+        r = stat_verify_char(&st);
+        if (r < 0)
+                return r;
 
         if (asprintf(ret_path, "/sys/dev/char/"DEVNUM_FORMAT_STR"/%s", DEVNUM_FORMAT_VAL(st.st_rdev), filename) < 0)
                 return -ENOMEM;