]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/socket: introduce AcceptFileDescriptors=
authorMike Yuan <me@yhndnzj.com>
Fri, 6 Jun 2025 19:01:33 +0000 (21:01 +0200)
committerMike Yuan <me@yhndnzj.com>
Tue, 17 Jun 2025 11:16:42 +0000 (13:16 +0200)
This controls the new SO_PASSRIGHTS socket option in kernel v6.16.
Note that I intentionally choose a different naming scheme than
Pass*=, since all other Pass*= options controls whether some extra
bits are attached to the message, while this one's about denying
file descriptor transfer and it feels more explicit this way.
And diverging from underlying socket option name is precedented
by Timestamping=. But happy to change it to just say PassRights=
if people disagree.

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

index 814400ad43e8e76181ab59a48af3138fc97dc824..237394b1faa4602c746df80caf77008358547333 100644 (file)
@@ -4913,6 +4913,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly b PassPacketInfo = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+      readonly b AcceptFileDescriptors = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly s Timestamping = '...';
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly b RemoveOnStop = ...;
@@ -5584,6 +5586,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
 
     <!--property PassPacketInfo is not documented!-->
 
+    <!--property AcceptFileDescriptors is not documented!-->
+
     <!--property Timestamping is not documented!-->
 
     <!--property RemoveOnStop is not documented!-->
@@ -6188,6 +6192,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
 
     <variablelist class="dbus-property" generated="True" extra-ref="PassPacketInfo"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="AcceptFileDescriptors"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="Timestamping"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="RemoveOnStop"/>
@@ -12099,6 +12105,7 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
       <varname>PrivatePIDs</varname> were added in version 257.</para>
       <para><varname>ProtectHostnameEx</varname>,
       <varname>PassPIDFD</varname>,
+      <varname>AcceptFileDescriptors</varname>,
       <varname>DelegateNamespaces</varname>, and
       <function>RemoveSubgroup()</function> were added in version 258.</para>
     </refsect2>
index b43f8e685bfaa8a7a7b78848d9eb7181328c54d6..91552d691f9e716a40ab74ac5f4b9cce1f9a0121 100644 (file)
         <xi:include href="version-info.xml" xpointer="v246"/></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>AcceptFileDescriptors=</varname></term>
+
+        <listitem><para>Takes a boolean value. This controls the <constant>SO_PASSRIGHTS</constant> socket
+        option, which when disabled prohibits the peer from sending <constant>SCM_RIGHTS</constant>
+        ancillary messages (aka file descriptors) via <constant>AF_UNIX</constant> sockets. Defaults to
+        <option>true</option>.</para>
+
+        <xi:include href="version-info.xml" xpointer="v258"/></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>Timestamping=</varname></term>
         <listitem><para>Takes one of <literal>off</literal>, <literal>us</literal> (alias:
index b07b3c93c539935203f0f9524840c3e9fc2e517d..de96f00a15832a5f12eae0be1bbb2af968380da7 100644 (file)
@@ -89,6 +89,7 @@ const sd_bus_vtable bus_socket_vtable[] = {
         SD_BUS_PROPERTY("PassPIDFD", "b", bus_property_get_bool, offsetof(Socket, pass_pidfd), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("PassSecurity", "b", bus_property_get_bool, offsetof(Socket, pass_sec), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("PassPacketInfo", "b", bus_property_get_bool, offsetof(Socket, pass_pktinfo), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("AcceptFileDescriptors", "b", bus_property_get_bool, offsetof(Socket, pass_rights), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Timestamping", "s", property_get_timestamping, offsetof(Socket, timestamping), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RemoveOnStop", "b", bus_property_get_bool, offsetof(Socket, remove_on_stop), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Listen", "a(ss)", property_get_listen, 0, SD_BUS_VTABLE_PROPERTY_CONST),
@@ -201,6 +202,9 @@ static int bus_socket_set_transient_property(
         if (streq(name, "PassPacketInfo"))
                 return bus_set_transient_bool(u, name, &s->pass_pktinfo, message, flags, error);
 
+        if (streq(name, "AcceptFileDescriptors"))
+                return bus_set_transient_bool(u, name, &s->pass_rights, message, flags, error);
+
         if (streq(name, "Timestamping"))
                 return bus_set_transient_socket_timestamping(u, name, &s->timestamping, message, flags, error);
 
index e3c23337319b5cbcf21c133f1e22953df6658cb4..918228fea16271c59ad5dd0baeba39c2b596ea9f 100644 (file)
@@ -513,6 +513,7 @@ Socket.PassCredentials,                       config_parse_bool,
 Socket.PassPIDFD,                             config_parse_bool,                                  0,                                  offsetof(Socket, pass_pidfd)
 Socket.PassSecurity,                          config_parse_bool,                                  0,                                  offsetof(Socket, pass_sec)
 Socket.PassPacketInfo,                        config_parse_bool,                                  0,                                  offsetof(Socket, pass_pktinfo)
+Socket.AcceptFileDescriptors,                 config_parse_bool,                                  0,                                  offsetof(Socket, pass_rights)
 Socket.Timestamping,                          config_parse_socket_timestamping,                   0,                                  offsetof(Socket, timestamping)
 Socket.TCPCongestion,                         config_parse_string,                                0,                                  offsetof(Socket, tcp_congestion)
 Socket.ReusePort,                             config_parse_bool,                                  0,                                  offsetof(Socket, reuse_port)
index 6d69d6cb4254279603cc76f063994727cdd53ec1..e5cff0de7610518042ad06497f0ab01c9b7cdf6c 100644 (file)
@@ -129,6 +129,7 @@ static void socket_init(Unit *u) {
 
         s->max_connections = 64;
 
+        s->pass_rights = true; /* defaults to enabled in kernel */
         s->priority = -1;
         s->ip_tos = -1;
         s->ip_ttl = -1;
@@ -613,6 +614,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
                 "%sPassPIDFD: %s\n"
                 "%sPassSecurity: %s\n"
                 "%sPassPacketInfo: %s\n"
+                "%sAcceptFileDescriptors: %s\n"
                 "%sTCPCongestion: %s\n"
                 "%sRemoveOnStop: %s\n"
                 "%sWritable: %s\n"
@@ -635,6 +637,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
                 prefix, yes_no(s->pass_pidfd),
                 prefix, yes_no(s->pass_sec),
                 prefix, yes_no(s->pass_pktinfo),
+                prefix, yes_no(s->pass_rights),
                 prefix, strna(s->tcp_congestion),
                 prefix, yes_no(s->remove_on_stop),
                 prefix, yes_no(s->writable),
@@ -1098,6 +1101,13 @@ static void socket_apply_socket_options(Socket *s, SocketPort *p, int fd) {
                         log_unit_warning_errno(UNIT(s), r, SOCKET_OPTION_WARNING_FORMAT_STR, "packet info");
         }
 
+        if (!s->pass_rights) {
+                r = setsockopt_int(fd, SOL_SOCKET, SO_PASSRIGHTS, false);
+                if (r < 0)
+                        log_unit_full_errno(UNIT(s), ERRNO_IS_NEG_NOT_SUPPORTED(r) ? LOG_DEBUG : LOG_WARNING, r,
+                                            SOCKET_OPTION_WARNING_FORMAT_STR, "SO_PASSRIGHTS");
+        }
+
         if (s->timestamping != SOCKET_TIMESTAMPING_OFF) {
                 r = setsockopt_int(fd, SOL_SOCKET,
                                    s->timestamping == SOCKET_TIMESTAMPING_NS ? SO_TIMESTAMPNS : SO_TIMESTAMP,
index 99fcc0cbe659788f22ccfbf964f2262813c2e551..70291fb0d266c96d5b67a76ab2d91fe80accb6d0 100644 (file)
@@ -134,6 +134,7 @@ typedef struct Socket {
         bool pass_pidfd;
         bool pass_sec;
         bool pass_pktinfo;
+        bool pass_rights;
         SocketTimestamping timestamping;
 
         /* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */
index aebeaa15ced1b53c5d8bef2976dcf75c3ab40f3d..ce56defeacc1fcf91253b904e5462241fd295540 100644 (file)
@@ -2586,6 +2586,7 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons
                               "PassPIDFD",
                               "PassSecurity",
                               "PassPacketInfo",
+                              "AcceptFileDescriptors",
                               "ReusePort",
                               "RemoveOnStop",
                               "PassFileDescriptorsToExec",