bhyve: Use VMIO_SIOCSIFFLAGS instead of SIOCGIFFLAGS

Creating an IP socket to invoke the SIOCGIFFLAGS ioctl on is the only
thing preventing bhyve from working inside a bhyve jail with IPv4 and
IPv6 disabled restricting the jailed bhyve process to only access the
host network via a tap/vmnet device node.

PR:		273557
Fixes:		56be282bc9 ("bhyve: net_backends, automatically IFF_UP tap devices")
Reviewed by:	markj
MFC after:	1 week

(cherry picked from commit fd8b9c73a5a63a7aa438a73951d7a535b4f25d9a)
This commit is contained in:
Jan Bramkamp 2023-09-04 10:38:25 +02:00 committed by Mark Johnston
parent c038e80498
commit 700689bc2a

View file

@ -42,9 +42,7 @@
#include <sys/uio.h>
#include <net/if.h>
#if defined(INET6) || defined(INET)
#include <net/if_tap.h>
#endif
#include <net/netmap.h>
#include <net/netmap_virt.h>
#define NETMAP_WITH_LIBS
@ -180,17 +178,6 @@ SET_DECLARE(net_backend_set, struct net_backend);
* The tap backend
*/
#if defined(INET6) || defined(INET)
static const int pf_list[] = {
#if defined(INET6)
PF_INET6,
#endif
#if defined(INET)
PF_INET,
#endif
};
#endif
struct tap_priv {
struct mevent *mevp;
/*
@ -222,11 +209,8 @@ tap_init(struct net_backend *be, const char *devname,
{
struct tap_priv *priv = NET_BE_PRIV(be);
char tbuf[80];
int opt = 1;
#if defined(INET6) || defined(INET)
struct ifreq ifrq;
int s;
#endif
int opt = 1, up = IFF_UP;
#ifndef WITHOUT_CAPSICUM
cap_rights_t rights;
#endif
@ -254,39 +238,11 @@ tap_init(struct net_backend *be, const char *devname,
goto error;
}
#if defined(INET6) || defined(INET)
/*
* Try to UP the interface rather than relying on
* net.link.tap.up_on_open.
*/
bzero(&ifrq, sizeof(ifrq));
if (ioctl(be->fd, TAPGIFNAME, &ifrq) < 0) {
WPRINTF(("Could not get interface name"));
if (ioctl(be->fd, VMIO_SIOCSIFFLAGS, &up)) {
WPRINTF(("tap device link up failed"));
goto error;
}
s = -1;
for (size_t i = 0; s == -1 && i < nitems(pf_list); i++)
s = socket(pf_list[i], SOCK_DGRAM, 0);
if (s == -1) {
WPRINTF(("Could open socket"));
goto error;
}
if (ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {
(void)close(s);
WPRINTF(("Could not get interface flags"));
goto error;
}
ifrq.ifr_flags |= IFF_UP;
if (ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
(void)close(s);
WPRINTF(("Could not set interface flags"));
goto error;
}
(void)close(s);
#endif
#ifndef WITHOUT_CAPSICUM
cap_rights_init(&rights, CAP_EVENT, CAP_READ, CAP_WRITE);
if (caph_rights_limit(be->fd, &rights) == -1)