]> git.ipfire.org Git - thirdparty/systemd.git/commit
socket: pass socket FDs to all ExecXYZ= commands but ExecStartPre=
authorJakub Sitnicki <jakub@cloudflare.com>
Thu, 15 Feb 2024 17:02:50 +0000 (18:02 +0100)
committerMike Yuan <me@yhndnzj.com>
Tue, 26 Mar 2024 17:41:26 +0000 (01:41 +0800)
commit97df75d7bd13ae9843fb55dd7285bf113adc2bd2
tree73f7dc8cc183a5e33df2ec4185e9974aedb3f8da
parentd30d0b04aed25db711cff8d3b035acc39dba4b57
socket: pass socket FDs to all ExecXYZ= commands but ExecStartPre=

Today listen file descriptors created by socket unit don't get passed to
commands in Exec{Start,Stop}{Pre,Post}= socket options.

This prevents ExecXYZ= commands from accessing the created socket FDs to do
any kind of system setup which involves the socket but is not covered by
existing socket unit options.

One concrete example is to insert a socket FD into a BPF map capable of
holding socket references, such as BPF sockmap/sockhash [1] or
reuseport_sockarray [2]. Or, similarly, send the file descriptor with
SCM_RIGHTS to another process, which has access to a BPF map for storing
sockets.

To unblock this use case, pass ListenXYZ= file descriptors to ExecXYZ=
commands as listen FDs [4]. As an exception, ExecStartPre= command does not
inherit any file descriptors because it gets invoked before the listen FDs
are created.

This new behavior can potentially break existing configurations. Commands
invoked from ExecXYZ= might not expect to inherit file descriptors through
sd_listen_fds protocol.

To prevent breakage, add a new socket unit parameter,
PassFileDescriptorsToExec=, to control whether ExecXYZ= programs inherit
listen FDs.

[1] https://docs.kernel.org/bpf/map_sockmap.html
[2] https://lore.kernel.org/r/20180808075917.3009181-1-kafai@fb.com
[3] https://man.archlinux.org/man/socket.7#SO_INCOMING_CPU
[4] https://www.freedesktop.org/software/systemd/man/latest/sd_listen_fds.html
man/org.freedesktop.systemd1.xml
man/systemd.socket.xml
src/core/dbus-socket.c
src/core/load-fragment-gperf.gperf.in
src/core/socket.c
src/core/socket.h
src/shared/bus-unit-util.c
test/fuzz/fuzz-unit-file/directives-all.service