various: turn off SO_PASSRIGHTS where fds are not expected (#37759)

This commit is contained in:
Lennart Poettering
2025-06-17 15:37:35 +02:00
committed by GitHub
33 changed files with 254 additions and 114 deletions

3
README
View File

@@ -71,7 +71,10 @@ REQUIREMENTS:
and MOVE_MOUNT_BENEATH
≥ 6.6 for quota support on tmpfs
≥ 6.9 for pidfs
≥ 6.10 for fcntl(F_DUPFD_QUERY), unprivileged linkat(AT_EMPTY_PATH),
and block device 'partscan' sysfs attribute
≥ 6.13 for PIDFD_GET_INFO and {set,remove}xattrat()
≥ 6.16 for coredump pattern '%F' (pidfd) specifier and SO_PASSRIGHTS
✅ systemd utilizes several new kernel APIs, but will fall back gracefully
when unavailable.

3
TODO
View File

@@ -128,9 +128,6 @@ Features:
also raises the question whether such sessions shall be considered active or
not
* Add PassPidFileDescriptor= similar in style to PassCredentials= to .socket
units
* automatically reset specific EFI vars on factory reset (make this generic
enough so that infrac can be used to erase shim's mok vars?)

View File

@@ -4907,12 +4907,14 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b PassCredentials = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b PassFileDescriptorsToExec = ...;
readonly b PassPIDFD = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b PassSecurity = ...;
@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 = ...;
@@ -4962,6 +4964,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
readonly u PollLimitBurst = ...;
readonly u UID = ...;
readonly u GID = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b PassFileDescriptorsToExec = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
readonly a(sasbttttuii) ExecStartPre = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
@@ -5576,12 +5580,14 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
<!--property PassCredentials is not documented!-->
<!--property PassFileDescriptorsToExec is not documented!-->
<!--property PassPIDFD is not documented!-->
<!--property PassSecurity is not documented!-->
<!--property PassPacketInfo is not documented!-->
<!--property AcceptFileDescriptors is not documented!-->
<!--property Timestamping is not documented!-->
<!--property RemoveOnStop is not documented!-->
@@ -5624,6 +5630,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
<!--property GID is not documented!-->
<!--property PassFileDescriptorsToExec is not documented!-->
<!--property ExecStopPre is not documented!-->
<!--property ExecStopPost is not documented!-->
@@ -6178,12 +6186,14 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
<variablelist class="dbus-property" generated="True" extra-ref="PassCredentials"/>
<variablelist class="dbus-property" generated="True" extra-ref="PassFileDescriptorsToExec"/>
<variablelist class="dbus-property" generated="True" extra-ref="PassPIDFD"/>
<variablelist class="dbus-property" generated="True" extra-ref="PassSecurity"/>
<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"/>
@@ -6238,6 +6248,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
<variablelist class="dbus-property" generated="True" extra-ref="GID"/>
<variablelist class="dbus-property" generated="True" extra-ref="PassFileDescriptorsToExec"/>
<variablelist class="dbus-property" generated="True" extra-ref="ExecStartPre"/>
<variablelist class="dbus-property" generated="True" extra-ref="ExecStartPost"/>
@@ -12092,6 +12104,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
<varname>ProtectControlGroupsEx</varname>, and
<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>

View File

@@ -742,6 +742,16 @@
process in an ancillary message. Defaults to <option>false</option>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>PassPIDFD=</varname></term>
<listitem><para>Takes a boolean value. This controls the <constant>SO_PASSPIDFD</constant> socket
option, which allows <constant>AF_UNIX</constant> sockets to receive the pidfd of the sending
process in an ancillary message. Defaults to <option>false</option>.</para>
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
</varlistentry>
<varlistentry>
<term><varname>PassSecurity=</varname></term>
<listitem><para>Takes a boolean value. This controls the <constant>SO_PASSSEC</constant> socket
@@ -761,6 +771,17 @@
<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:

View File

@@ -13,6 +13,11 @@
#define SO_PEERPIDFD 77
#endif
/* Supported since kernel v6.16 (77cbe1a6d8730a07f99f9263c2d5f2304cf5e830) */
#ifndef SO_PASSRIGHTS
#define SO_PASSRIGHTS 83
#endif
/* Not exposed yet. Defined in include/linux/socket.h. */
#ifndef SOL_SCTP
#define SOL_SCTP 132

View File

@@ -86,9 +86,10 @@ const sd_bus_vtable bus_socket_vtable[] = {
SD_BUS_PROPERTY("Transparent", "b", bus_property_get_bool, offsetof(Socket, transparent), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Broadcast", "b", bus_property_get_bool, offsetof(Socket, broadcast), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PassCredentials", "b", bus_property_get_bool, offsetof(Socket, pass_cred), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PassFileDescriptorsToExec", "b", bus_property_get_bool, offsetof(Socket, pass_fds_to_exec), SD_BUS_VTABLE_PROPERTY_CONST),
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),
@@ -116,6 +117,7 @@ const sd_bus_vtable bus_socket_vtable[] = {
SD_BUS_PROPERTY("PollLimitBurst", "u", bus_property_get_unsigned, offsetof(Socket, poll_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("UID", "u", bus_property_get_uid, offsetof(Unit, ref_uid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("GID", "u", bus_property_get_gid, offsetof(Unit, ref_gid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("PassFileDescriptorsToExec", "b", bus_property_get_bool, offsetof(Socket, pass_fds_to_exec), SD_BUS_VTABLE_PROPERTY_CONST),
BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPre", offsetof(Socket, exec_command[SOCKET_EXEC_START_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPost", offsetof(Socket, exec_command[SOCKET_EXEC_START_POST]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
BUS_EXEC_COMMAND_LIST_VTABLE("ExecStopPre", offsetof(Socket, exec_command[SOCKET_EXEC_STOP_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
@@ -191,8 +193,8 @@ static int bus_socket_set_transient_property(
if (streq(name, "PassCredentials"))
return bus_set_transient_bool(u, name, &s->pass_cred, message, flags, error);
if (streq(name, "PassFileDescriptorsToExec"))
return bus_set_transient_bool(u, name, &s->pass_fds_to_exec, message, flags, error);
if (streq(name, "PassPIDFD"))
return bus_set_transient_bool(u, name, &s->pass_pidfd, message, flags, error);
if (streq(name, "PassSecurity"))
return bus_set_transient_bool(u, name, &s->pass_sec, message, flags, error);
@@ -200,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);
@@ -311,6 +316,9 @@ static int bus_socket_set_transient_property(
if (streq(name, "SocketProtocol"))
return bus_set_transient_socket_protocol(u, name, &s->socket_protocol, message, flags, error);
if (streq(name, "PassFileDescriptorsToExec"))
return bus_set_transient_bool(u, name, &s->pass_fds_to_exec, message, flags, error);
ci = socket_exec_command_from_string(name);
if (ci >= 0)
return bus_set_transient_exec_command(u, name,
@@ -348,8 +356,9 @@ static int bus_socket_set_transient_property(
}
return 1;
}
} else if (streq(name, "Listen")) {
if (streq(name, "Listen")) {
const char *t, *a;
bool empty = true;

View File

@@ -510,9 +510,10 @@ Socket.FreeBind, config_parse_bool,
Socket.Transparent, config_parse_bool, 0, offsetof(Socket, transparent)
Socket.Broadcast, config_parse_bool, 0, offsetof(Socket, broadcast)
Socket.PassCredentials, config_parse_bool, 0, offsetof(Socket, pass_cred)
Socket.PassFileDescriptorsToExec, config_parse_bool, 0, offsetof(Socket, pass_fds_to_exec)
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)
@@ -522,6 +523,7 @@ Socket.RemoveOnStop, config_parse_bool,
Socket.Symlinks, config_parse_unit_path_strv_printf, 0, offsetof(Socket, symlinks)
Socket.FileDescriptorName, config_parse_fdname, 0, 0
Socket.Service, config_parse_socket_service, 0, 0
Socket.PassFileDescriptorsToExec, config_parse_bool, 0, offsetof(Socket, pass_fds_to_exec)
Socket.TriggerLimitIntervalSec, config_parse_sec, 0, offsetof(Socket, trigger_limit.interval)
Socket.TriggerLimitBurst, config_parse_unsigned, 0, offsetof(Socket, trigger_limit.burst)
Socket.PollLimitIntervalSec, config_parse_sec, 0, offsetof(Socket, poll_limit.interval)

View File

@@ -1136,6 +1136,10 @@ static int manager_setup_user_lookup_fd(Manager *m) {
if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, m->user_lookup_fds) < 0)
return log_error_errno(errno, "Failed to allocate user lookup socket: %m");
r = setsockopt_int(m->user_lookup_fds[0], SOL_SOCKET, SO_PASSRIGHTS, false);
if (r < 0 && !ERRNO_IS_NEG_NOT_SUPPORTED(r))
log_warning_errno(r, "Failed to turn off SO_PASSRIGHTS on user lookup socket, ignoring: %m");
(void) fd_increase_rxbuf(m->user_lookup_fds[0], MANAGER_SOCKET_RCVBUF_SIZE);
}
@@ -1176,7 +1180,11 @@ static int manager_setup_handoff_timestamp_fd(Manager *m) {
r = setsockopt_int(m->handoff_timestamp_fds[0], SOL_SOCKET, SO_PASSCRED, true);
if (r < 0)
return log_error_errno(r, "SO_PASSCRED failed: %m");
return log_error_errno(r, "Failed to enable SO_PASSCRED on handoff timestamp socket: %m");
r = setsockopt_int(m->handoff_timestamp_fds[0], SOL_SOCKET, SO_PASSRIGHTS, false);
if (r < 0 && !ERRNO_IS_NEG_NOT_SUPPORTED(r))
log_warning_errno(r, "Failed to turn off SO_PASSRIGHTS on handoff timestamp socket, ignoring: %m");
/* Mark the receiving socket as O_NONBLOCK (but leave sending side as-is) */
r = fd_nonblock(m->handoff_timestamp_fds[0], true);
@@ -1223,7 +1231,7 @@ static int manager_setup_pidref_transport_fd(Manager *m) {
r = setsockopt_int(m->pidref_transport_fds[0], SOL_SOCKET, SO_PASSPIDFD, true);
if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
log_debug("SO_PASSPIDFD is not supported for pidref socket, ignoring.");
log_debug_errno(r, "SO_PASSPIDFD is not supported for pidref socket, ignoring.");
else if (r < 0)
log_warning_errno(r, "Failed to enable SO_PASSPIDFD for pidref socket, ignoring: %m");

View 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;
@@ -610,13 +611,15 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
"%sTransparent: %s\n"
"%sBroadcast: %s\n"
"%sPassCredentials: %s\n"
"%sPassFileDescriptorsToExec: %s\n"
"%sPassPIDFD: %s\n"
"%sPassSecurity: %s\n"
"%sPassPacketInfo: %s\n"
"%sAcceptFileDescriptors: %s\n"
"%sTCPCongestion: %s\n"
"%sRemoveOnStop: %s\n"
"%sWritable: %s\n"
"%sFileDescriptorName: %s\n"
"%sPassFileDescriptorsToExec: %s\n"
"%sSELinuxContextFromNet: %s\n",
prefix, socket_state_to_string(s->state),
prefix, socket_result_to_string(s->result),
@@ -631,13 +634,15 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
prefix, yes_no(s->transparent),
prefix, yes_no(s->broadcast),
prefix, yes_no(s->pass_cred),
prefix, yes_no(s->pass_fds_to_exec),
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),
prefix, socket_fdname(s),
prefix, yes_no(s->pass_fds_to_exec),
prefix, yes_no(s->selinux_context_from_net));
if (s->timestamping != SOCKET_TIMESTAMPING_OFF)
@@ -1011,6 +1016,10 @@ static void socket_close_fds(Socket *s) {
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(Socket*, socket_close_fds, NULL);
#define SOCKET_OPTION_WARNING_FORMAT_STR "Failed to set %s socket option, ignoring: %m"
#define log_socket_option_warning_errno(s, error, option) \
log_unit_warning_errno(UNIT(s), (error), SOCKET_OPTION_WARNING_FORMAT_STR, STRINGIFY(option))
static void socket_apply_socket_options(Socket *s, SocketPort *p, int fd) {
int r;
@@ -1021,67 +1030,82 @@ static void socket_apply_socket_options(Socket *s, SocketPort *p, int fd) {
if (s->keep_alive) {
r = setsockopt_int(fd, SOL_SOCKET, SO_KEEPALIVE, true);
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "SO_KEEPALIVE failed, ignoring: %m");
log_socket_option_warning_errno(s, r, SO_KEEPALIVE);
}
if (timestamp_is_set(s->keep_alive_time)) {
r = setsockopt_int(fd, SOL_TCP, TCP_KEEPIDLE, s->keep_alive_time / USEC_PER_SEC);
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "TCP_KEEPIDLE failed, ignoring: %m");
log_socket_option_warning_errno(s, r, TCP_KEEPIDLE);
}
if (s->keep_alive_interval > 0) {
r = setsockopt_int(fd, SOL_TCP, TCP_KEEPINTVL, s->keep_alive_interval / USEC_PER_SEC);
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "TCP_KEEPINTVL failed, ignoring: %m");
log_socket_option_warning_errno(s, r, TCP_KEEPINTVL);
}
if (s->keep_alive_cnt > 0) {
r = setsockopt_int(fd, SOL_TCP, TCP_KEEPCNT, s->keep_alive_cnt);
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "TCP_KEEPCNT failed, ignoring: %m");
log_socket_option_warning_errno(s, r, TCP_KEEPCNT);
}
if (s->defer_accept > 0) {
r = setsockopt_int(fd, SOL_TCP, TCP_DEFER_ACCEPT, s->defer_accept / USEC_PER_SEC);
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "TCP_DEFER_ACCEPT failed, ignoring: %m");
log_socket_option_warning_errno(s, r, TCP_DEFER_ACCEPT);
}
if (s->no_delay) {
if (s->socket_protocol == IPPROTO_SCTP) {
r = setsockopt_int(fd, SOL_SCTP, SCTP_NODELAY, true);
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "SCTP_NODELAY failed, ignoring: %m");
log_socket_option_warning_errno(s, r, SCTP_NODELAY);
} else {
r = setsockopt_int(fd, SOL_TCP, TCP_NODELAY, true);
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "TCP_NODELAY failed, ignoring: %m");
log_socket_option_warning_errno(s, r, TCP_NODELAY);
}
}
if (s->broadcast) {
r = setsockopt_int(fd, SOL_SOCKET, SO_BROADCAST, true);
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "SO_BROADCAST failed, ignoring: %m");
log_socket_option_warning_errno(s, r, SO_BROADCAST);
}
if (s->pass_cred) {
r = setsockopt_int(fd, SOL_SOCKET, SO_PASSCRED, true);
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "SO_PASSCRED failed, ignoring: %m");
log_socket_option_warning_errno(s, r, SO_PASSCRED);
}
if (s->pass_pidfd) {
r = setsockopt_int(fd, SOL_SOCKET, SO_PASSPIDFD, true);
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_PASSPIDFD");
}
if (s->pass_sec) {
r = setsockopt_int(fd, SOL_SOCKET, SO_PASSSEC, true);
if (r < 0)
log_unit_full_errno(UNIT(s), ERRNO_IS_NEG_NOT_SUPPORTED(r) ? LOG_DEBUG : LOG_WARNING, r, "SO_PASSSEC failed, ignoring: %m");
log_unit_full_errno(UNIT(s), ERRNO_IS_NEG_NOT_SUPPORTED(r) ? LOG_DEBUG : LOG_WARNING, r,
SOCKET_OPTION_WARNING_FORMAT_STR, "SO_PASSSEC");
}
if (s->pass_pktinfo) {
r = socket_set_recvpktinfo(fd, socket_address_family(&p->address), true);
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "Failed to enable packet info socket option, ignoring: %m");
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) {
@@ -1089,50 +1113,50 @@ static void socket_apply_socket_options(Socket *s, SocketPort *p, int fd) {
s->timestamping == SOCKET_TIMESTAMPING_NS ? SO_TIMESTAMPNS : SO_TIMESTAMP,
true);
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "Failed to enable timestamping socket option, ignoring: %m");
log_unit_warning_errno(UNIT(s), r, SOCKET_OPTION_WARNING_FORMAT_STR, "timestamping");
}
if (s->priority >= 0) {
r = setsockopt_int(fd, SOL_SOCKET, SO_PRIORITY, s->priority);
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "SO_PRIORITY failed, ignoring: %m");
log_socket_option_warning_errno(s, r, SO_PRIORITY);
}
if (s->receive_buffer > 0) {
r = fd_set_rcvbuf(fd, s->receive_buffer, false);
if (r < 0)
log_unit_full_errno(UNIT(s), ERRNO_IS_PRIVILEGE(r) ? LOG_DEBUG : LOG_WARNING, r,
"SO_RCVBUF/SO_RCVBUFFORCE failed, ignoring: %m");
log_unit_full_errno(UNIT(s), ERRNO_IS_NEG_PRIVILEGE(r) ? LOG_DEBUG : LOG_WARNING, r,
SOCKET_OPTION_WARNING_FORMAT_STR, "SO_RCVBUF/SO_RCVBUFFORCE");
}
if (s->send_buffer > 0) {
r = fd_set_sndbuf(fd, s->send_buffer, false);
if (r < 0)
log_unit_full_errno(UNIT(s), ERRNO_IS_PRIVILEGE(r) ? LOG_DEBUG : LOG_WARNING, r,
"SO_SNDBUF/SO_SNDBUFFORCE failed, ignoring: %m");
log_unit_full_errno(UNIT(s), ERRNO_IS_NEG_PRIVILEGE(r) ? LOG_DEBUG : LOG_WARNING, r,
SOCKET_OPTION_WARNING_FORMAT_STR, "SO_SNDBUF/SO_SNDBUFFORCE");
}
if (s->mark >= 0) {
r = setsockopt_int(fd, SOL_SOCKET, SO_MARK, s->mark);
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "SO_MARK failed, ignoring: %m");
log_socket_option_warning_errno(s, r, SO_MARK);
}
if (s->ip_tos >= 0) {
r = setsockopt_int(fd, IPPROTO_IP, IP_TOS, s->ip_tos);
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "IP_TOS failed, ignoring: %m");
log_socket_option_warning_errno(s, r, IP_TOS);
}
if (s->ip_ttl >= 0) {
r = socket_set_ttl(fd, socket_address_family(&p->address), s->ip_ttl);
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "IP_TTL/IPV6_UNICAST_HOPS failed, ignoring: %m");
log_unit_warning_errno(UNIT(s), r, SOCKET_OPTION_WARNING_FORMAT_STR, "IP_TTL/IPV6_UNICAST_HOPS");
}
if (s->tcp_congestion)
if (setsockopt(fd, SOL_TCP, TCP_CONGESTION, s->tcp_congestion, strlen(s->tcp_congestion)+1) < 0)
log_unit_warning_errno(UNIT(s), errno, "TCP_CONGESTION failed, ignoring: %m");
log_socket_option_warning_errno(s, errno, TCP_CONGESTION);
if (s->smack_ip_in) {
r = mac_smack_apply_fd(fd, SMACK_ATTR_IPIN, s->smack_ip_in);

View File

@@ -86,7 +86,7 @@ typedef struct Socket {
usec_t keep_alive_interval;
usec_t defer_accept;
ExecCommand* exec_command[_SOCKET_EXEC_COMMAND_MAX];
ExecCommand *exec_command[_SOCKET_EXEC_COMMAND_MAX];
ExecContext exec_context;
KillContext kill_context;
CGroupContext cgroup_context;
@@ -103,10 +103,12 @@ typedef struct Socket {
sd_event_source *timer_event_source;
ExecCommand* control_command;
ExecCommand *control_command;
SocketExecCommand control_command_id;
PidRef control_pid;
bool pass_fds_to_exec;
mode_t directory_mode;
mode_t socket_mode;
@@ -129,9 +131,10 @@ typedef struct Socket {
bool transparent;
bool broadcast;
bool pass_cred;
bool pass_fds_to_exec;
bool pass_pidfd;
bool pass_sec;
bool pass_pktinfo;
bool pass_rights;
SocketTimestamping timestamping;
/* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */

View File

@@ -1154,15 +1154,16 @@ static int manager_listen_notify(Manager *m) {
assert(m);
assert(!m->notify_socket_path);
r = notify_socket_prepare(
r = notify_socket_prepare_full(
m->event,
SD_EVENT_PRIORITY_NORMAL - 5, /* Make sure we process sd_notify() before SIGCHLD for
* any worker, so that we always know the error number
* of a client before it exits. */
on_notify_socket,
m,
/* accept_fds = */ true,
&m->notify_socket_path,
/* ret_event_source= */ NULL);
/* ret_event_source = */ NULL);
if (r < 0)
return log_error_errno(r, "Failed to prepare notify socket: %m");

View File

@@ -723,8 +723,7 @@ static int manager_new(Manager **ret) {
SD_EVENT_PRIORITY_NORMAL,
manager_on_notify,
m,
&m->notify_socket_path,
/* ret_event_source= */ NULL);
&m->notify_socket_path);
if (r < 0)
return r;

View File

@@ -647,10 +647,6 @@ int stdout_stream_install(Manager *m, int fd, StdoutStream **ret) {
if (r < 0)
return log_ratelimit_error_errno(r, JOURNAL_LOG_RATELIMIT, "Failed to determine peer credentials: %m");
r = setsockopt_int(fd, SOL_SOCKET, SO_PASSCRED, true);
if (r < 0)
return log_error_errno(r, "SO_PASSCRED failed: %m");
if (mac_selinux_use()) {
r = getpeersec(fd, &stream->label);
if (r < 0 && r != -EOPNOTSUPP)
@@ -918,6 +914,14 @@ int manager_open_stdout_socket(Manager *m, const char *stdout_socket) {
} else
(void) fd_nonblock(m->stdout_fd, true);
r = setsockopt_int(m->stdout_fd, SOL_SOCKET, SO_PASSCRED, true);
if (r < 0)
return log_error_errno(r, "Failed to enable SO_PASSCRED: %m");
r = setsockopt_int(m->stdout_fd, SOL_SOCKET, SO_PASSRIGHTS, false);
if (r < 0)
log_debug_errno(r, "Failed to turn off SO_PASSRIGHTS, ignoring: %m");
r = sd_event_add_io(m->event, &m->stdout_event_source, m->stdout_fd, EPOLLIN, stdout_stream_new, m);
if (r < 0)
return log_error_errno(r, "Failed to add stdout server fd to event source: %m");

View File

@@ -504,17 +504,22 @@ int manager_open_syslog_socket(Manager *m, const char *syslog_socket) {
r = setsockopt_int(m->syslog_fd, SOL_SOCKET, SO_PASSCRED, true);
if (r < 0)
return log_error_errno(r, "SO_PASSCRED failed: %m");
return log_error_errno(r, "Failed to enable SO_PASSCRED: %m");
r = setsockopt_int(m->syslog_fd, SOL_SOCKET, SO_PASSRIGHTS, false);
if (r < 0)
log_debug_errno(r, "Failed to turn off SO_PASSRIGHTS, ignoring: %m");
if (mac_selinux_use()) {
r = setsockopt_int(m->syslog_fd, SOL_SOCKET, SO_PASSSEC, true);
if (r < 0)
log_full_errno(ERRNO_IS_NEG_NOT_SUPPORTED(r) ? LOG_DEBUG : LOG_WARNING, r, "SO_PASSSEC failed, ignoring: %m");
log_full_errno(ERRNO_IS_NEG_NOT_SUPPORTED(r) ? LOG_DEBUG : LOG_WARNING, r,
"Failed to enable SO_PASSSEC, ignoring: %m");
}
r = setsockopt_int(m->syslog_fd, SOL_SOCKET, SO_TIMESTAMP, true);
if (r < 0)
return log_error_errno(r, "SO_TIMESTAMP failed: %m");
return log_error_errno(r, "Failed to enable SO_TIMESTAMP: %m");
r = sd_event_add_io(m->event, &m->syslog_event_source, m->syslog_fd, EPOLLIN, manager_process_datagram, m);
if (r < 0)

View File

@@ -139,12 +139,14 @@ static int varlink_new(sd_varlink **ret) {
.ucred = UCRED_INVALID,
.peer_pidfd = -EBADF,
.timestamp = USEC_INFINITY,
.timeout = VARLINK_DEFAULT_TIMEOUT_USEC,
.af = -1,
.allow_fd_passing_input = -1,
.peer_pidfd = -EBADF,
.af = -1,
};
*ret = v;
@@ -327,15 +329,11 @@ static int varlink_connect_ssh_unix(sd_varlink **ret, const char *where) {
if (!h)
return log_oom_debug();
_cleanup_free_ char *c = strdup(e + 1);
if (!c)
return log_oom_debug();
if (!path_is_absolute(c))
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Remote AF_UNIX socket path is not absolute, refusing: %s", c);
if (!path_is_absolute(e + 1))
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Remote AF_UNIX socket path is not absolute, refusing: %s", e + 1);
_cleanup_free_ char *p = NULL;
r = path_simplify_alloc(c, &p);
r = path_simplify_alloc(e + 1, &p);
if (r < 0)
return r;
@@ -853,7 +851,7 @@ static int varlink_read(sd_varlink *v) {
p = v->input_buffer + v->input_buffer_index + v->input_buffer_size;
rs = MALLOC_SIZEOF_SAFE(v->input_buffer) - (v->input_buffer_index + v->input_buffer_size);
if (v->allow_fd_passing_input) {
if (v->allow_fd_passing_input > 0) {
iov = IOVEC_MAKE(p, rs);
/* Allocate the fd buffer on the heap, since we need a lot of space potentially */
@@ -897,14 +895,14 @@ static int varlink_read(sd_varlink *v) {
return n;
if (n == 0) { /* EOF */
if (v->allow_fd_passing_input)
if (v->allow_fd_passing_input > 0)
cmsg_close_all(&mh);
v->read_disconnected = true;
return 1;
}
if (v->allow_fd_passing_input) {
if (v->allow_fd_passing_input > 0) {
struct cmsghdr *cmsg;
cmsg = cmsg_find(&mh, SOL_SOCKET, SCM_RIGHTS, (socklen_t) -1);
@@ -3163,7 +3161,7 @@ _public_ int sd_varlink_peek_fd(sd_varlink *v, size_t i) {
/* Returns one of the file descriptors that were received along with the current message. This does
* not duplicate the fd nor invalidate it, it hence remains in our possession. */
if (!v->allow_fd_passing_input)
if (v->allow_fd_passing_input <= 0)
return -EPERM;
if (i >= v->n_input_fds)
@@ -3189,7 +3187,7 @@ _public_ int sd_varlink_take_fd(sd_varlink *v, size_t i) {
* we'll invalidate the reference to it under our possession. If called twice in a row will return
* -EBADF */
if (!v->allow_fd_passing_input)
if (v->allow_fd_passing_input <= 0)
return -EPERM;
if (i >= v->n_input_fds)
@@ -3201,7 +3199,7 @@ _public_ int sd_varlink_take_fd(sd_varlink *v, size_t i) {
_public_ int sd_varlink_get_n_fds(sd_varlink *v) {
assert_return(v, -EINVAL);
if (!v->allow_fd_passing_input)
if (v->allow_fd_passing_input <= 0)
return -EPERM;
return (int) v->n_input_fds;
@@ -3251,20 +3249,29 @@ _public_ int sd_varlink_set_allow_fd_passing_input(sd_varlink *v, int b) {
assert_return(v, -EINVAL);
if (v->allow_fd_passing_input == !!b)
if (v->allow_fd_passing_input >= 0 && (v->allow_fd_passing_input > 0) == !!b)
return 0;
if (!b) {
v->allow_fd_passing_input = false;
return 1;
r = verify_unix_socket(v);
if (r < 0) {
assert(v->allow_fd_passing_input <= 0);
if (!b) {
v->allow_fd_passing_input = false;
return 0;
}
return r;
}
r = verify_unix_socket(v);
if (r < 0)
return r;
if (!v->server || FLAGS_SET(v->server->flags, SD_VARLINK_SERVER_FD_PASSING_INPUT_STRICT)) {
r = setsockopt_int(v->input_fd, SOL_SOCKET, SO_PASSRIGHTS, !!b);
if (r < 0 && !ERRNO_IS_NEG_NOT_SUPPORTED(r))
log_debug_errno(r, "Failed to set SO_PASSRIGHTS socket option: %m");
}
v->allow_fd_passing_input = true;
return 0;
v->allow_fd_passing_input = !!b;
return 1;
}
_public_ int sd_varlink_set_allow_fd_passing_output(sd_varlink *v, int b) {
@@ -3275,17 +3282,12 @@ _public_ int sd_varlink_set_allow_fd_passing_output(sd_varlink *v, int b) {
if (v->allow_fd_passing_output == !!b)
return 0;
if (!b) {
v->allow_fd_passing_output = false;
return 1;
}
r = verify_unix_socket(v);
if (r < 0)
return r;
v->allow_fd_passing_output = true;
return 0;
v->allow_fd_passing_output = !!b;
return 1;
}
_public_ int sd_varlink_set_input_sensitive(sd_varlink *v) {
@@ -3306,7 +3308,8 @@ _public_ int sd_varlink_server_new(sd_varlink_server **ret, sd_varlink_server_fl
SD_VARLINK_SERVER_INHERIT_USERDATA|
SD_VARLINK_SERVER_INPUT_SENSITIVE|
SD_VARLINK_SERVER_ALLOW_FD_PASSING_INPUT|
SD_VARLINK_SERVER_ALLOW_FD_PASSING_OUTPUT)) == 0, -EINVAL);
SD_VARLINK_SERVER_ALLOW_FD_PASSING_OUTPUT|
SD_VARLINK_SERVER_FD_PASSING_INPUT_STRICT)) == 0, -EINVAL);
s = new(sd_varlink_server, 1);
if (!s)
@@ -3502,6 +3505,12 @@ _public_ int sd_varlink_server_add_connection_pair(
if (r < 0)
return r;
/* Link up the server and the connection, and take reference in both directions. Note that the
* reference on the connection is left dangling. It will be dropped when the connection is closed,
* which happens in varlink_close(), including in the event loop quit callback. */
v->server = sd_varlink_server_ref(server);
sd_varlink_ref(v);
v->input_fd = input_fd;
v->output_fd = output_fd;
if (server->flags & SD_VARLINK_SERVER_INHERIT_USERDATA)
@@ -3519,12 +3528,6 @@ _public_ int sd_varlink_server_add_connection_pair(
(void) sd_varlink_set_allow_fd_passing_input(v, FLAGS_SET(server->flags, SD_VARLINK_SERVER_ALLOW_FD_PASSING_INPUT));
(void) sd_varlink_set_allow_fd_passing_output(v, FLAGS_SET(server->flags, SD_VARLINK_SERVER_ALLOW_FD_PASSING_OUTPUT));
/* Link up the server and the connection, and take reference in both directions. Note that the
* reference on the connection is left dangling. It will be dropped when the connection is closed,
* which happens in varlink_close(), including in the event loop quit callback. */
v->server = sd_varlink_server_ref(server);
sd_varlink_ref(v);
varlink_set_state(v, VARLINK_IDLE_SERVER);
if (server->event) {
@@ -3641,6 +3644,13 @@ _public_ int sd_varlink_server_listen_fd(sd_varlink_server *s, int fd) {
if (r < 0)
return r;
/* If fd passing is disabled on server, and SD_VARLINK_SERVER_FD_PASSING_INPUT_STRICT flag is set,
* turn off SO_PASSRIGHTS immediately on listening socket. The conditionalization behind a flag
* is needed to retain backwards compat, where implementations would register a connection callback
* to enable fd passing after accept(), which might race with clients wrt SO_PASSRIGHTS state. */
if (FLAGS_SET(s->flags, SD_VARLINK_SERVER_FD_PASSING_INPUT_STRICT))
(void) setsockopt_int(fd, SOL_SOCKET, SO_PASSRIGHTS, FLAGS_SET(s->flags, SD_VARLINK_SERVER_ALLOW_FD_PASSING_INPUT));
r = varlink_server_create_listen_fd_socket(s, fd, &ss);
if (r < 0)
return r;
@@ -3682,6 +3692,10 @@ _public_ int sd_varlink_server_listen_address(sd_varlink_server *s, const char *
fd = fd_move_above_stdio(fd);
/* See the comment in sd_varlink_server_listen_fd() */
if (FLAGS_SET(s->flags, SD_VARLINK_SERVER_FD_PASSING_INPUT_STRICT))
(void) setsockopt_int(fd, SOL_SOCKET, SO_PASSRIGHTS, FLAGS_SET(s->flags, SD_VARLINK_SERVER_ALLOW_FD_PASSING_INPUT));
(void) sockaddr_un_unlink(&sockaddr.un);
WITH_UMASK(~m & 0777)

View File

@@ -166,12 +166,12 @@ struct sd_varlink {
bool prefer_write:1;
bool got_pollhup:1;
bool allow_fd_passing_input:1;
bool allow_fd_passing_output:1;
bool output_buffer_sensitive:1; /* whether to erase the output buffer after writing it to the socket */
bool input_sensitive:1; /* Whether incoming messages might be sensitive */
bool allow_fd_passing_output;
int allow_fd_passing_input;
int af; /* address family if socket; AF_UNSPEC if not socket; negative if not known */
usec_t timestamp;

View File

@@ -174,7 +174,7 @@ int varlink_server_new(
_cleanup_(sd_varlink_server_unrefp) sd_varlink_server *s = NULL;
int r;
r = sd_varlink_server_new(&s, flags);
r = sd_varlink_server_new(&s, flags|SD_VARLINK_SERVER_FD_PASSING_INPUT_STRICT);
if (r < 0)
return log_debug_errno(r, "Failed to allocate varlink server object: %m");

View File

@@ -335,16 +335,15 @@ int manager_varlink_init(Manager *m) {
if (m->varlink_server)
return 0;
r = sd_varlink_server_new(
r = varlink_server_new(
&s,
SD_VARLINK_SERVER_ACCOUNT_UID|
SD_VARLINK_SERVER_INHERIT_USERDATA|
SD_VARLINK_SERVER_ALLOW_FD_PASSING_OUTPUT);
SD_VARLINK_SERVER_ALLOW_FD_PASSING_OUTPUT,
m);
if (r < 0)
return log_error_errno(r, "Failed to allocate varlink server object: %m");
sd_varlink_server_set_userdata(s, m);
r = sd_varlink_server_add_interface_many(
s,
&vl_interface_io_systemd_Login,

View File

@@ -511,8 +511,7 @@ static int action_fork(char *const *_command) {
* more interesting, "positive" information. */
on_notify_socket,
&child,
&addr_string,
/* ret_event_source= */ NULL);
&addr_string);
if (r < 0)
return log_error_errno(r, "Failed to prepare notify socket: %m");

View File

@@ -3716,6 +3716,10 @@ static int setup_notify_child(const void *directory) {
if (r < 0)
log_debug_errno(r, "Failed to enable SO_PASSPIDFD, ignoring: %m");
r = setsockopt_int(fd, SOL_SOCKET, SO_PASSRIGHTS, false);
if (r < 0)
log_debug_errno(r, "Failed to turn off SO_PASSRIGHTS, ignoring: %m");
return TAKE_FD(fd);
}

View File

@@ -819,6 +819,8 @@ static int create_socket(const char *askpwdir, char **ret) {
if (r < 0)
return r;
(void) setsockopt_int(fd, SOL_SOCKET, SO_PASSRIGHTS, false);
*ret = TAKE_PTR(path);
return TAKE_FD(fd);
}

View File

@@ -2583,11 +2583,13 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons
"Transparent",
"Broadcast",
"PassCredentials",
"PassFileDescriptorsToExec",
"PassPIDFD",
"PassSecurity",
"PassPacketInfo",
"AcceptFileDescriptors",
"ReusePort",
"RemoveOnStop",
"PassFileDescriptorsToExec",
"SELinuxContextFromNet"))
return bus_append_parse_boolean(m, field, eq);

View File

@@ -108,11 +108,12 @@ int journal_fork(RuntimeScope scope, char * const *units, PidRef *ret_pidref) {
_cleanup_(sd_event_source_disable_unrefp) sd_event_source *notify_event_source = NULL;
_cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL;
_cleanup_free_ char *addr_string = NULL;
r = notify_socket_prepare(
r = notify_socket_prepare_full(
event,
SD_EVENT_PRIORITY_NORMAL-10, /* We want the notification message from the child before the SIGCHLD */
on_child_notify,
&child,
/* accept_fds = */ false,
&addr_string,
&notify_event_source);
if (r < 0)

View File

@@ -15,11 +15,12 @@
#include "socket-util.h"
#include "strv.h"
int notify_socket_prepare(
int notify_socket_prepare_full(
sd_event *event,
int64_t priority,
sd_event_io_handler_t handler,
void *userdata,
bool accept_fds,
char **ret_path,
sd_event_source **ret_event_source) {
@@ -48,6 +49,13 @@ int notify_socket_prepare(
if (r < 0)
log_debug_errno(r, "Failed to enable SO_PASSPIDFD on notification socket, ignoring: %m");
if (!accept_fds) {
/* since kernel v6.16 */
r = setsockopt_int(fd, SOL_SOCKET, SO_PASSRIGHTS, false);
if (r < 0)
log_debug_errno(r, "Failed to disable SO_PASSRIGHTS on notification socket, ignoring: %m");
}
_cleanup_(sd_event_source_unrefp) sd_event_source *s = NULL;
r = sd_event_add_io(event, &s, fd, EPOLLIN, handler, userdata);
if (r < 0)

View File

@@ -3,14 +3,25 @@
#include "forward.h"
int notify_socket_prepare(
int notify_socket_prepare_full(
sd_event *event,
int64_t priority,
sd_event_io_handler_t handler,
void *userdata,
bool accept_fds,
char **ret_path,
sd_event_source **ret_event_source);
static inline int notify_socket_prepare(
sd_event *event,
int64_t priority,
sd_event_io_handler_t handler,
void *userdata,
char **ret_path) {
return notify_socket_prepare_full(event, priority, handler, userdata, false, ret_path, NULL);
}
int notify_recv_with_fds(
int fd,
char **ret_text,

View File

@@ -68,6 +68,7 @@ __extension__ typedef enum _SD_ENUM_TYPE_S64(sd_varlink_server_flags_t) {
SD_VARLINK_SERVER_INPUT_SENSITIVE = 1 << 4, /* Automatically mark all connection input as sensitive */
SD_VARLINK_SERVER_ALLOW_FD_PASSING_INPUT = 1 << 5, /* Allow receiving fds over all connections */
SD_VARLINK_SERVER_ALLOW_FD_PASSING_OUTPUT = 1 << 6, /* Allow sending fds over all connections */
SD_VARLINK_SERVER_FD_PASSING_INPUT_STRICT = 1 << 7, /* Reject input messages with fds if fd passing is disabled (needs kernel v6.16+) */
_SD_ENUM_FORCE_S64(SD_VARLINK_SERVER)
} sd_varlink_server_flags_t;

View File

@@ -1066,8 +1066,7 @@ static int run_callout(
SD_EVENT_PRIORITY_NORMAL - 5,
helper_on_notify,
ctx,
&bind_name,
/* ret_event_source= */ NULL);
&bind_name);
if (r < 0)
return log_error_errno(r, "Failed to prepare notify socket: %m");

View File

@@ -1748,8 +1748,7 @@ static int manager_new(Manager **ret) {
SD_EVENT_PRIORITY_NORMAL,
manager_on_notify,
m,
&m->notify_socket_path,
/* ret_event_source= */ NULL);
&m->notify_socket_path);
if (r < 0)
return r;

View File

@@ -88,7 +88,7 @@ TEST(notify_socket_prepare) {
.pidref = PIDREF_NULL,
};
_cleanup_free_ char *path = NULL;
ASSERT_OK(notify_socket_prepare(e, SD_EVENT_PRIORITY_NORMAL - 10, on_recv, &c, &path, /* ret_event_source= */ NULL));
ASSERT_OK(notify_socket_prepare_full(e, SD_EVENT_PRIORITY_NORMAL - 10, on_recv, &c, true, &path, NULL));
ASSERT_OK(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD));

View File

@@ -44,6 +44,7 @@ struct UdevCtrl {
int udev_ctrl_new_from_fd(UdevCtrl **ret, int fd) {
_cleanup_close_ int sock = -EBADF;
UdevCtrl *uctrl;
int r;
assert(ret);
@@ -53,6 +54,15 @@ int udev_ctrl_new_from_fd(UdevCtrl **ret, int fd) {
return log_error_errno(errno, "Failed to create socket: %m");
}
/* enable receiving of the sender credentials in the messages */
r = setsockopt_int(fd >= 0 ? fd : sock, SOL_SOCKET, SO_PASSCRED, true);
if (r < 0)
log_warning_errno(r, "Failed to set SO_PASSCRED, ignoring: %m");
r = setsockopt_int(fd >= 0 ? fd : sock, SOL_SOCKET, SO_PASSRIGHTS, false);
if (r < 0)
log_debug_errno(r, "Failed to turn off SO_PASSRIGHTS, ignoring: %m");
uctrl = new(UdevCtrl, 1);
if (!uctrl)
return -ENOMEM;
@@ -240,11 +250,6 @@ static int udev_ctrl_event_handler(sd_event_source *s, int fd, uint32_t revents,
return 0;
}
/* enable receiving of the sender credentials in the messages */
r = setsockopt_int(sock, SOL_SOCKET, SO_PASSCRED, true);
if (r < 0)
log_warning_errno(r, "Failed to set SO_PASSCRED, ignoring: %m");
r = sd_event_add_io(uctrl->event, &uctrl->event_source_connect, sock, EPOLLIN, udev_ctrl_connection_event_handler, uctrl);
if (r < 0) {
log_error_errno(r, "Failed to create event source for udev control connection: %m");

View File

@@ -1232,8 +1232,7 @@ static int manager_start_worker_notify(Manager *manager) {
EVENT_PRIORITY_WORKER_NOTIFY,
on_worker_notify,
manager,
&manager->worker_notify_socket_path,
/* ret_event_source= */ NULL);
&manager->worker_notify_socket_path);
if (r < 0)
return log_error_errno(r, "Failed to prepare worker notification socket: %m");

View File

@@ -27,6 +27,7 @@ ListenDatagram=/run/systemd/journal/syslog
SocketMode=0666
PassCredentials=yes
PassSecurity=yes
AcceptFileDescriptors=no
ReceiveBuffer=8M
# The default syslog implementation should make syslog.service a

View File

@@ -22,6 +22,7 @@ PassCredentials=yes
PassSecurity=yes
ReceiveBuffer=8M
SendBuffer=8M
Timestamping=us
[Install]
WantedBy=sockets.target