network/tuntap: deny non-system users/groups from owning Tun/Tap interfaces
This is analogous to #36123, but for Tun/Tap interfaces created by systemd-networkd. If a regular user account want to control a Tun/Tap interface, then assign the interface to a system group, e.g., vpn, and add the user to the group. Closes #37279.
This commit is contained in:
@@ -46,6 +46,9 @@ CHANGES WITH 258 in spe:
|
||||
owned by a non-system user/group. It is recommended to check udev
|
||||
rules files with 'udevadm verify' and/or 'udevadm test' commands if
|
||||
the specified user/group in OWNER=/GROUP= are valid.
|
||||
Similarly, systemd-networkd refuses User=/Group= settings with a
|
||||
non-system user/group specified in .netdev files for Tun/Tap
|
||||
interfaces.
|
||||
|
||||
* systemd-cryptenroll, systemd-repart and systemd-creds no longer
|
||||
default to locking TPM2 enrollments to the current, literal value of
|
||||
|
||||
@@ -1970,16 +1970,16 @@ Ports=eth2</programlisting>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>User=</varname></term>
|
||||
<listitem><para>User to grant access to the
|
||||
<filename>/dev/net/tun</filename> device.</para>
|
||||
<listitem><para>User to grant access to the <filename>/dev/net/tun</filename> device. The specified
|
||||
user must be a system user.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v215"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>Group=</varname></term>
|
||||
<listitem><para>Group to grant access to the
|
||||
<filename>/dev/net/tun</filename> device.</para>
|
||||
<listitem><para>Group to grant access to the <filename>/dev/net/tun</filename> device. The specified
|
||||
group must be a system group.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v215"/>
|
||||
</listitem>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "bitfield.h"
|
||||
#include "daemon-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "networkd-link.h"
|
||||
@@ -228,9 +229,14 @@ static int tuntap_verify(NetDev *netdev, const char *filename) {
|
||||
|
||||
if (t->user_name) {
|
||||
_cleanup_(user_record_unrefp) UserRecord *ur = NULL;
|
||||
UserDBMatch match = USERDB_MATCH_NULL;
|
||||
|
||||
r = userdb_by_name(t->user_name, /* match = */ NULL, USERDB_PARSE_NUMERIC, &ur);
|
||||
if (r < 0)
|
||||
match.disposition_mask = INDEX_TO_MASK(uint64_t, USER_SYSTEM);
|
||||
|
||||
r = userdb_by_name(t->user_name, &match, USERDB_PARSE_NUMERIC, &ur);
|
||||
if (r == -ENOEXEC)
|
||||
log_netdev_warning_errno(netdev, r, "User %s is not a system user, ignoring.", t->user_name);
|
||||
else if (r < 0)
|
||||
log_netdev_warning_errno(netdev, r, "Cannot resolve user name %s, ignoring: %m", t->user_name);
|
||||
else
|
||||
t->uid = ur->uid;
|
||||
@@ -238,9 +244,14 @@ static int tuntap_verify(NetDev *netdev, const char *filename) {
|
||||
|
||||
if (t->group_name) {
|
||||
_cleanup_(group_record_unrefp) GroupRecord *gr = NULL;
|
||||
UserDBMatch match = USERDB_MATCH_NULL;
|
||||
|
||||
r = groupdb_by_name(t->group_name, /* match = */ NULL, USERDB_PARSE_NUMERIC, &gr);
|
||||
if (r < 0)
|
||||
match.disposition_mask = INDEX_TO_MASK(uint64_t, USER_SYSTEM);
|
||||
|
||||
r = groupdb_by_name(t->group_name, &match, USERDB_PARSE_NUMERIC, &gr);
|
||||
if (r == -ENOEXEC)
|
||||
log_netdev_warning_errno(netdev, r, "Group %s is not a system group, ignoring.", t->group_name);
|
||||
else if (r < 0)
|
||||
log_netdev_warning_errno(netdev, r, "Cannot resolve group name %s, ignoring: %m", t->group_name);
|
||||
else
|
||||
t->gid = gr->gid;
|
||||
|
||||
Reference in New Issue
Block a user