]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
socket-activate: make a copy of the command name and arguments 28060/head
authorFrantisek Sumsal <fsumsal@redhat.com>
Fri, 16 Jun 2023 17:05:57 +0000 (19:05 +0200)
committerFrantisek Sumsal <fsumsal@redhat.com>
Fri, 16 Jun 2023 18:42:43 +0000 (20:42 +0200)
When we call safe_fork() with the first argument set (process name), we
call rename_process() that zeroes out saved argv (that was saved by
save_argc_argv() in the main func defined by DEFINE_MAIN_FUNC()). In this
case this means that with --accept both the target executable name and
its arguments will be empty strings:

```
$ systemd-socket-activate --accept --listen 1111 cat &
Listening on [::]:1111 as 3.
$ curl localhost:1111
Communication attempt on fd 3.
Connection from 127.0.0.1:52948 to [::ffff:127.0.0.1]:1111
Spawned cat (cat) as PID 10576.
Execing  ()
Failed to execp  (): No such file or directory
Child 10576 died with code 1
curl: (56) Recv failure: Connection reset by peer
```

Let's make a copy of the necessary arguments beforehand and use it
instead to fix this.

src/socket-activate/socket-activate.c

index 1caa30d7d474f7058588124f301b4b0dd11007e5..2e19d125c3981e416fe2a57c92737b72ca52e46a 100644 (file)
@@ -443,6 +443,7 @@ static int parse_argv(int argc, char *argv[]) {
 
 static int run(int argc, char **argv) {
         _cleanup_close_ int epoll_fd = -EBADF;
+        _cleanup_strv_free_ char **exec_argv = NULL;
         int r, n;
 
         log_show_color(true);
@@ -453,6 +454,12 @@ static int run(int argc, char **argv) {
         if (r <= 0)
                 return r;
 
+        exec_argv = strv_copy(arg_args);
+        if (!exec_argv)
+                return log_oom();
+
+        assert(strv_length(exec_argv) > 0);
+
         r = install_chld_handler();
         if (r < 0)
                 return r;
@@ -475,14 +482,14 @@ static int run(int argc, char **argv) {
 
                 log_info("Communication attempt on fd %i.", event.data.fd);
                 if (arg_accept) {
-                        r = do_accept(argv[optind], argv + optind, event.data.fd);
+                        r = do_accept(exec_argv[0], exec_argv, event.data.fd);
                         if (r < 0)
                                 return r;
                 } else
                         break;
         }
 
-        return exec_process(argv[optind], argv + optind, SD_LISTEN_FDS_START, (size_t) n);
+        return exec_process(exec_argv[0], exec_argv, SD_LISTEN_FDS_START, (size_t) n);
 }
 
 DEFINE_MAIN_FUNCTION(run);