network/tuntap: verify User=/Group= settings earlier

and ignore the settings if we cannot find the specified user/group.

This also replaces get_user_creds()/get_group_creds() with
userdb_by_name()/groupdb_by_name().
This commit is contained in:
Yu Watanabe
2025-04-29 22:51:50 +09:00
parent 52e2a24216
commit 1fae13fbec
2 changed files with 33 additions and 26 deletions

View File

@@ -16,7 +16,7 @@
#include "networkd-manager.h"
#include "socket-util.h"
#include "tuntap.h"
#include "user-util.h"
#include "userdb.h"
#define TUN_DEV "/dev/net/tun"
@@ -174,31 +174,14 @@ static int netdev_create_tuntap(NetDev *netdev) {
return log_netdev_error_errno(netdev, errno, "TUNSETQUEUE failed: %m");
}
if (t->user_name) {
const char *user = t->user_name;
uid_t uid;
r = get_user_creds(&user, &uid, NULL, NULL, NULL, USER_CREDS_ALLOW_MISSING);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Cannot resolve user name %s: %m", t->user_name);
if (ioctl(fd, TUNSETOWNER, uid) < 0)
if (t->uid != 0)
if (ioctl(fd, TUNSETOWNER, t->uid) < 0)
return log_netdev_error_errno(netdev, errno, "TUNSETOWNER failed: %m");
}
if (t->group_name) {
const char *group = t->group_name;
gid_t gid;
r = get_group_creds(&group, &gid, USER_CREDS_ALLOW_MISSING);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Cannot resolve group name %s: %m", t->group_name);
if (ioctl(fd, TUNSETGROUP, gid) < 0)
if (t->gid != 0)
if (ioctl(fd, TUNSETGROUP, t->gid) < 0)
return log_netdev_error_errno(netdev, errno, "TUNSETGROUP failed: %m");
}
if (ioctl(fd, TUNSETPERSIST, 1) < 0)
return log_netdev_error_errno(netdev, errno, "TUNSETPERSIST failed: %m");
@@ -226,6 +209,9 @@ static void tuntap_done(NetDev *netdev) {
}
static int tuntap_verify(NetDev *netdev, const char *filename) {
TunTap *t = TUNTAP(netdev);
int r;
assert(netdev);
if (netdev->mtu != 0)
@@ -240,6 +226,26 @@ static int tuntap_verify(NetDev *netdev, const char *filename) {
"Please set it in the corresponding .network file.",
netdev_kind_to_string(netdev->kind), filename);
if (t->user_name) {
_cleanup_(user_record_unrefp) UserRecord *ur = NULL;
r = userdb_by_name(t->user_name, /* match = */ NULL, USERDB_PARSE_NUMERIC, &ur);
if (r < 0)
log_netdev_warning_errno(netdev, r, "Cannot resolve user name %s, ignoring: %m", t->user_name);
else
t->uid = ur->uid;
}
if (t->group_name) {
_cleanup_(group_record_unrefp) GroupRecord *gr = NULL;
r = groupdb_by_name(t->group_name, /* match = */ NULL, USERDB_PARSE_NUMERIC, &gr);
if (r < 0)
log_netdev_warning_errno(netdev, r, "Cannot resolve group name %s, ignoring: %m", t->group_name);
else
t->gid = gr->gid;
}
return 0;
}

View File

@@ -1,20 +1,21 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
typedef struct TunTap TunTap;
#include "netdev.h"
#include "user-util.h"
struct TunTap {
typedef struct TunTap {
NetDev meta;
char *user_name;
uid_t uid;
char *group_name;
gid_t gid;
bool multi_queue;
bool packet_info;
bool vnet_hdr;
bool keep_fd;
};
} TunTap;
DEFINE_NETDEV_CAST(TUN, TunTap);
DEFINE_NETDEV_CAST(TAP, TunTap);