]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/dbus-service: validate type of received ExecContext fds 39680/head
authorMike Yuan <me@yhndnzj.com>
Tue, 11 Nov 2025 18:13:01 +0000 (19:13 +0100)
committerMike Yuan <me@yhndnzj.com>
Wed, 12 Nov 2025 14:44:51 +0000 (15:44 +0100)
src/core/dbus-service.c

index aa6a587c16d6373d70c95503092b26bbea1ebcd2..79a7e224cc50922bcbf6d31d7a3f08aab3bd0c5a 100644 (file)
@@ -28,6 +28,7 @@
 #include "selinux-access.h"
 #include "service.h"
 #include "signal-util.h"
+#include "stat-util.h"
 #include "string-util.h"
 #include "unit.h"
 
@@ -488,21 +489,32 @@ static int bus_set_transient_exit_status(
 
 static int bus_set_transient_exec_context_fd(
                 Unit *u,
+                const char *name,
                 int *p,
                 bool *b,
+                int verify_mode,
                 sd_bus_message *message,
                 UnitWriteFlags flags,
                 sd_bus_error *error) {
 
         int fd, r;
 
+        assert(name);
         assert(p);
         assert(b);
+        assert(verify_mode == O_DIRECTORY || (verify_mode & ~O_ACCMODE_STRICT) == 0);
 
         r = sd_bus_message_read(message, "h", &fd);
         if (r < 0)
                 return r;
 
+        if (verify_mode == O_DIRECTORY)
+                r = fd_verify_directory(fd);
+        else
+                r = fd_vet_accmode(fd, verify_mode);
+        if (r < 0)
+                return sd_bus_error_set_errnof(error, r, "%s passed is of incompatible type: %m", name);
+
         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                 int copy;
 
@@ -689,13 +701,13 @@ static int bus_service_set_transient_property(
                 return bus_set_transient_exec_command(u, name, &s->exec_command[ci], message, flags, error);
 
         if (streq(name, "StandardInputFileDescriptor"))
-                return bus_set_transient_exec_context_fd(u, &s->stdin_fd, &s->exec_context.stdio_as_fds, message, flags, error);
+                return bus_set_transient_exec_context_fd(u, name, &s->stdin_fd, &s->exec_context.stdio_as_fds, O_RDONLY, message, flags, error);
 
         if (streq(name, "StandardOutputFileDescriptor"))
-                return bus_set_transient_exec_context_fd(u, &s->stdout_fd, &s->exec_context.stdio_as_fds, message, flags, error);
+                return bus_set_transient_exec_context_fd(u, name, &s->stdout_fd, &s->exec_context.stdio_as_fds, O_WRONLY, message, flags, error);
 
         if (streq(name, "StandardErrorFileDescriptor"))
-                return bus_set_transient_exec_context_fd(u, &s->stderr_fd, &s->exec_context.stdio_as_fds, message, flags, error);
+                return bus_set_transient_exec_context_fd(u, name, &s->stderr_fd, &s->exec_context.stdio_as_fds, O_WRONLY, message, flags, error);
 
         if (streq(name, "OpenFile")) {
                 const char *path, *fdname;
@@ -802,7 +814,7 @@ static int bus_service_set_transient_property(
         }
 
         if (streq(name, "RootDirectoryFileDescriptor"))
-                return bus_set_transient_exec_context_fd(u, &s->root_directory_fd, &s->exec_context.root_directory_as_fd, message, flags, error);
+                return bus_set_transient_exec_context_fd(u, name, &s->root_directory_fd, &s->exec_context.root_directory_as_fd, O_DIRECTORY, message, flags, error);
 
         return 0;
 }