Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

disable PassCredentials= on networkd netlink socket, enable NETLINK_PKTINFO instead #15942

Merged
merged 4 commits into from May 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/TRANSIENT-SETTINGS.md
Expand Up @@ -429,6 +429,7 @@ Most socket unit settings are available to transient units.
✓ Broadcast=
✓ PassCredentials=
✓ PassSecurity=
✓ PassPacketInfo=
✓ TCPCongestion=
✓ ReusePort=
✓ MessageQueueMaxMessages=
Expand Down
9 changes: 9 additions & 0 deletions man/systemd.socket.xml
Expand Up @@ -709,6 +709,15 @@
Defaults to <option>false</option>.</para></listitem>
</varlistentry>

<varlistentry>
<term><varname>PassPacketInfo=</varname></term>
<listitem><para>Takes a boolean value. This controls the <constant>IP_PKTINFO</constant>,
<constant>IPV6_RECVPKTINFO</constant> and <constant>NETLINK_PKTINFO</constant> socket options, which
enable reception of additional per-packet metadata as ancillary message, on
<constant>AF_INET</constant>, <constant>AF_INET6</constant> and <constant>AF_UNIX</constant> sockets.
Defaults to <option>false</option>.</para></listitem>
</varlistentry>

<varlistentry>
<term><varname>TCPCongestion=</varname></term>
<listitem><para>Takes a string value. Controls the TCP
Expand Down
22 changes: 22 additions & 0 deletions src/basic/socket-util.c
Expand Up @@ -1174,5 +1174,27 @@ ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags) {
}

return n;
}

int socket_pass_pktinfo(int fd, bool b) {
int af;
socklen_t sl = sizeof(af);

if (getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &af, &sl) < 0)
return -errno;

switch (af) {

case AF_INET:
return setsockopt_int(fd, IPPROTO_IP, IP_PKTINFO, b);

case AF_INET6:
return setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, b);

case AF_NETLINK:
return setsockopt_int(fd, SOL_NETLINK, NETLINK_PKTINFO, b);

default:
return -EAFNOSUPPORT;
}
}
2 changes: 2 additions & 0 deletions src/basic/socket-util.h
Expand Up @@ -220,3 +220,5 @@ int socket_bind_to_ifname(int fd, const char *ifname);
int socket_bind_to_ifindex(int fd, int ifindex);

ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags);

int socket_pass_pktinfo(int fd, bool b);
4 changes: 4 additions & 0 deletions src/core/dbus-socket.c
Expand Up @@ -104,6 +104,7 @@ const sd_bus_vtable bus_socket_vtable[] = {
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("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("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),
SD_BUS_PROPERTY("Symlinks", "as", NULL, offsetof(Socket, symlinks), SD_BUS_VTABLE_PROPERTY_CONST),
Expand Down Expand Up @@ -202,6 +203,9 @@ static int bus_socket_set_transient_property(
if (streq(name, "PassSecurity"))
return bus_set_transient_bool(u, name, &s->pass_sec, message, flags, error);

if (streq(name, "PassPacketInfo"))
return bus_set_transient_bool(u, name, &s->pass_pktinfo, message, flags, error);

if (streq(name, "ReusePort"))
return bus_set_transient_bool(u, name, &s->reuse_port, message, flags, error);

Expand Down
1 change: 1 addition & 0 deletions src/core/load-fragment-gperf.gperf.m4
Expand Up @@ -396,6 +396,7 @@ Socket.Transparent, config_parse_bool, 0,
Socket.Broadcast, config_parse_bool, 0, offsetof(Socket, broadcast)
Socket.PassCredentials, config_parse_bool, 0, offsetof(Socket, pass_cred)
Socket.PassSecurity, config_parse_bool, 0, offsetof(Socket, pass_sec)
Socket.PassPacketInfo, config_parse_bool, 0, offsetof(Socket, pass_pktinfo)
Socket.TCPCongestion, config_parse_string, 0, offsetof(Socket, tcp_congestion)
Socket.ReusePort, config_parse_bool, 0, offsetof(Socket, reuse_port)
Socket.MessageQueueMaxMessages, config_parse_long, 0, offsetof(Socket, mq_maxmsg)
Expand Down
8 changes: 8 additions & 0 deletions src/core/socket.c
Expand Up @@ -635,6 +635,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
"%sBroadcast: %s\n"
"%sPassCredentials: %s\n"
"%sPassSecurity: %s\n"
"%sPassPacketInfo: %s\n"
"%sTCPCongestion: %s\n"
"%sRemoveOnStop: %s\n"
"%sWritable: %s\n"
Expand All @@ -654,6 +655,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
prefix, yes_no(s->broadcast),
prefix, yes_no(s->pass_cred),
prefix, yes_no(s->pass_sec),
prefix, yes_no(s->pass_pktinfo),
prefix, strna(s->tcp_congestion),
prefix, yes_no(s->remove_on_stop),
prefix, yes_no(s->writable),
Expand Down Expand Up @@ -1070,6 +1072,12 @@ static void socket_apply_socket_options(Socket *s, int fd) {
log_unit_warning_errno(UNIT(s), r, "SO_PASSSEC failed: %m");
}

if (s->pass_pktinfo) {
r = socket_pass_pktinfo(fd, true);
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "Failed to enable packet info socket option: %m");
}

if (s->priority >= 0) {
r = setsockopt_int(fd, SOL_SOCKET, SO_PRIORITY, s->priority);
if (r < 0)
Expand Down
1 change: 1 addition & 0 deletions src/core/socket.h
Expand Up @@ -121,6 +121,7 @@ struct Socket {
bool broadcast;
bool pass_cred;
bool pass_sec;
bool pass_pktinfo;

/* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */
SocketAddressBindIPv6Only bind_ipv6_only;
Expand Down
6 changes: 1 addition & 5 deletions src/libsystemd/sd-netlink/netlink-socket.c
Expand Up @@ -16,10 +16,6 @@
#include "socket-util.h"
#include "util.h"

/* For some reason we need some extra cmsg space on some kernels. It's not clear why, and one of those days
* we need to track this down. See: https://github.com/systemd/systemd/pull/15457 */
#define EXTRA_CMSG_SPACE 1024

int socket_open(int family) {
int fd;

Expand Down Expand Up @@ -244,7 +240,7 @@ int socket_write_message(sd_netlink *nl, sd_netlink_message *m) {

static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_group, bool peek) {
union sockaddr_union sender;
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct nl_pktinfo)) + EXTRA_CMSG_SPACE) control;
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct nl_pktinfo))) control;
struct msghdr msg = {
.msg_iov = iov,
.msg_iovlen = 1,
Expand Down
1 change: 1 addition & 0 deletions src/resolve/resolved-dns-stream.c
Expand Up @@ -88,6 +88,7 @@ static int dns_stream_complete(DnsStream *s, int error) {

static int dns_stream_identify(DnsStream *s) {
CMSG_BUFFER_TYPE(CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
+ CMSG_SPACE(int) + /* for the TTL */
+ EXTRA_CMSG_SPACE /* kernel appears to require extra space */) control;
struct msghdr mh = {};
struct cmsghdr *cmsg;
Expand Down
1 change: 1 addition & 0 deletions src/shared/bus-unit-util.c
Expand Up @@ -1632,6 +1632,7 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons
"Broadcast",
"PassCredentials",
"PassSecurity",
"PassPacketInfo",
"ReusePort",
"RemoveOnStop",
"SELinuxContextFromNet"))
Expand Down
1 change: 1 addition & 0 deletions test/fuzz/fuzz-unit-file/directives.service
Expand Up @@ -164,6 +164,7 @@ PIDFile=
PartOf=
PassCredentials=
PassSecurity=
PassPacketInfo=
PathChanged=
PathExists=
PathExistsGlob=
Expand Down
2 changes: 1 addition & 1 deletion units/systemd-networkd.socket
Expand Up @@ -17,7 +17,7 @@ Before=sockets.target
[Socket]
ReceiveBuffer=128M
ListenNetlink=route 1361
PassCredentials=yes
PassPacketInfo=yes

[Install]
WantedBy=sockets.target