Index: lib/libvmmapi/vmmapi.h =================================================================== --- lib/libvmmapi/vmmapi.h +++ lib/libvmmapi/vmmapi.h @@ -39,9 +39,18 @@ #define VMMAPI_VERSION 0102 /* 2 digit major followed by 2 digit minor */ struct iovec; -struct vmctx; enum x2apic_state; +struct vmctx { + int fd; + uint32_t lowmem_limit; + int memflags; + size_t lowmem; + size_t highmem; + char *baseaddr; + char *name; +}; + /* * Different styles of mapping the memory assigned to a VM into the address * space of the controlling process. Index: lib/libvmmapi/vmmapi.c =================================================================== --- lib/libvmmapi/vmmapi.c +++ lib/libvmmapi/vmmapi.c @@ -67,16 +67,6 @@ #define PROT_RW (PROT_READ | PROT_WRITE) #define PROT_ALL (PROT_READ | PROT_WRITE | PROT_EXEC) -struct vmctx { - int fd; - uint32_t lowmem_limit; - int memflags; - size_t lowmem; - size_t highmem; - char *baseaddr; - char *name; -}; - #define CREATE(x) sysctlbyname("hw.vmm.create", NULL, NULL, (x), strlen((x))) #define DESTROY(x) sysctlbyname("hw.vmm.destroy", NULL, NULL, (x), strlen((x))) Index: usr.sbin/bhyve/bhyverun.c =================================================================== --- usr.sbin/bhyve/bhyverun.c +++ usr.sbin/bhyve/bhyverun.c @@ -30,6 +30,8 @@ __FBSDID("$FreeBSD$"); #include +#include +#include #include #include @@ -40,7 +42,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -48,8 +52,10 @@ #include #include #include +#include #include +#include #include #include "bhyverun.h" @@ -706,6 +712,21 @@ struct vmctx *ctx; int error; bool reinit, romboot; + cap_rights_t rights; + u_long cmds[] = {VM_RUN, VM_SUSPEND, VM_REINIT, VM_ALLOC_MEMSEG, + VM_GET_MEMSEG, VM_MMAP_MEMSEG, VM_MMAP_MEMSEG, VM_MMAP_GETNEXT, + VM_SET_REGISTER, VM_GET_REGISTER, VM_SET_SEGMENT_DESCRIPTOR, + VM_GET_SEGMENT_DESCRIPTOR, VM_INJECT_EXCEPTION, VM_LAPIC_IRQ, + VM_LAPIC_LOCAL_IRQ, VM_LAPIC_MSI, VM_IOAPIC_ASSERT_IRQ, + VM_IOAPIC_DEASSERT_IRQ, VM_IOAPIC_PULSE_IRQ, VM_IOAPIC_PINCOUNT, + VM_ISA_ASSERT_IRQ, VM_ISA_DEASSERT_IRQ, VM_ISA_PULSE_IRQ, + VM_ISA_SET_IRQ_TRIGGER, VM_SET_CAPABILITY, VM_GET_CAPABILITY, + VM_BIND_PPTDEV, VM_UNBIND_PPTDEV, VM_MAP_PPTDEV_MMIO, VM_PPTDEV_MSI, + VM_PPTDEV_MSIX, VM_INJECT_NMI, VM_STATS, VM_STAT_DESC, + VM_SET_X2APIC_STATE, VM_GET_X2APIC_STATE, VM_GET_HPET_CAPABILITIES, + VM_GET_GPA_PMAP, VM_GLA2GPA, VM_ACTIVATE_CPU, VM_GET_CPUS, + VM_SET_INTINFO, VM_GET_INTINFO, VM_RTC_WRITE, VM_RTC_READ, + VM_RTC_SETTIME, VM_RTC_GETTIME, VM_RESTART_INSTRUCTION}; reinit = romboot = false; @@ -744,6 +765,12 @@ exit(1); } + cap_rights_init(&rights, CAP_IOCTL, CAP_MMAP_RWX); + if (cap_rights_limit(ctx->fd, &rights) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (cap_ioctls_limit(STDIN_FILENO, cmds, nitems(cmds)) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (reinit) { error = vm_reinit(ctx); if (error) { @@ -764,6 +791,10 @@ uint64_t rip; size_t memsize; char *optstr; +#ifdef notyet + cap_rights_t rights; + u_long cmds[] = {TIOCGETA, TIOCSETA, TIOCGWINSZ}; +#endif bvmcons = 0; progname = basename(argv[0]); @@ -952,6 +983,37 @@ if (lpc_bootrom()) fwctl_init(); + catopen("libc", NL_CAT_LOCALE); + +#ifdef notyet + cap_rights_init(&rights, CAP_READ, CAP_FCNTL, CAP_FSTAT, CAP_IOCTL, CAP_EVENT); + + if (cap_rights_limit(STDIN_FILENO, &rights) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (cap_ioctls_limit(STDIN_FILENO, cmds, nitems(cmds)) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox!"); + + cap_rights_clear(&rights, CAP_READ); + cap_rights_set(&rights, CAP_WRITE); + + if (cap_rights_limit(STDOUT_FILENO, &rights) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (cap_ioctls_limit(STDOUT_FILENO, cmds, nitems(cmds)) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + + if (cap_rights_limit(STDERR_FILENO, &rights) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (cap_ioctls_limit(STDERR_FILENO, cmds, nitems(cmds)) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); +#endif + + if (cap_enter() == -1) { + if (errno == ENOSYS) + warn("Capsicum unavailable, running without a sandbox"); + else + errx(EX_OSERR, "cap_enter() failed"); + } + /* * Change the proc title to include the VM name. */ Index: usr.sbin/bhyve/block_if.c =================================================================== --- usr.sbin/bhyve/block_if.c +++ usr.sbin/bhyve/block_if.c @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include @@ -45,6 +46,7 @@ #include #include #include +#include #include #include @@ -400,6 +402,9 @@ off_t size, psectsz, psectoff; int extra, fd, i, sectsz; int nocache, sync, ro, candelete, geom, ssopt, pssopt; + cap_rights_t rights; + u_long cmds[] = {DIOCGFLUSH, DIOCGDELETE, DIOCGMEDIASIZE, DIOCGSECTORSIZE, + DIOCGSTRIPESIZE, DIOCGSTRIPEOFFSET, DIOCGATTR, DIOCGPROVIDERNAME}; pthread_once(&blockif_once, blockif_init); @@ -447,6 +452,16 @@ ro = 1; } + cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_SEEK, CAP_FSTAT, CAP_IOCTL); + if (ro) + cap_rights_clear(&rights, CAP_WRITE); + + if (cap_rights_limit(fd, &rights) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + + if (cap_ioctls_limit(fd, cmds, nitems(cmds)) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (fd < 0) { warn("Could not open backing file: %s", nopt); goto err; Index: usr.sbin/bhyve/mevent.c =================================================================== --- usr.sbin/bhyve/mevent.c +++ usr.sbin/bhyve/mevent.c @@ -35,13 +35,16 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include #include +#include #include #include +#include #include #include @@ -401,6 +404,7 @@ int mfd; int numev; int ret; + cap_rights_t rights; mevent_tid = pthread_self(); mevent_set_name(); @@ -408,6 +412,10 @@ mfd = kqueue(); assert(mfd > 0); + cap_rights_init(&rights, CAP_KQUEUE); + if (cap_rights_limit(mfd, &rights) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + /* * Open the pipe that will be used for other threads to force * the blocking kqueue call to exit by writing to it. Set the @@ -419,6 +427,13 @@ exit(0); } + cap_rights_remove(&rights, &rights); + cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_EVENT); + if (cap_rights_limit(mevent_pipefd[0], &rights) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (cap_rights_limit(mevent_pipefd[1], &rights) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + /* * Add internal event handler for the pipe write fd */ Index: usr.sbin/bhyve/pci_ahci.c =================================================================== --- usr.sbin/bhyve/pci_ahci.c +++ usr.sbin/bhyve/pci_ahci.c @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include @@ -2293,11 +2294,17 @@ MD5_CTX mdctx; u_char digest[16]; char *next, *next2; +#ifdef AHCI_DEBUG + cap_rights_t rights; +#endif ret = 0; #ifdef AHCI_DEBUG dbg = fopen("/tmp/log", "w+"); + cap_rights_init(&rights, CAP_WRITE, CAP_FSTAT, CAP_SEEK); + if (cap_rights_limit(fileno(dbg), &rights) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); #endif sc = calloc(1, sizeof(struct pci_ahci_softc)); Index: usr.sbin/bhyve/pci_e82545.c =================================================================== --- usr.sbin/bhyve/pci_e82545.c +++ usr.sbin/bhyve/pci_e82545.c @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include @@ -38,6 +39,7 @@ #include #include +#include #include #include #include @@ -44,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -2202,6 +2205,7 @@ e82545_open_tap(struct e82545_softc *sc, char *opts) { char tbuf[80]; + cap_rights_t rights; if (opts == NULL) { sc->esc_tapfd = -1; @@ -2228,6 +2232,10 @@ sc->esc_tapfd = -1; } + cap_rights_init(&rights, CAP_READ, CAP_WRITE); + if (cap_rights_limit(sc->esc_tapfd, &rights) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + sc->esc_mevp = mevent_add(sc->esc_tapfd, EVF_READ, e82545_tap_callback, Index: usr.sbin/bhyve/pci_passthru.c =================================================================== --- usr.sbin/bhyve/pci_passthru.c +++ usr.sbin/bhyve/pci_passthru.c @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include @@ -44,7 +45,9 @@ #include #include #include +#include #include +#include #include #include @@ -639,9 +642,13 @@ { int bus, slot, func, error, memflags; struct passthru_softc *sc; + cap_rights_t rights; + u_long pci_ioctls[] = {PCIOCREAD, PCIOCWRITE, PCIOCGETBAR}; + u_long io_ioctls[] = {IODEV_PIO}; sc = NULL; error = 1; + cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_IOCTL); memflags = vm_get_memflags(ctx); if (!(memflags & VM_MEM_F_WIRED)) { @@ -657,6 +664,11 @@ } } + if (cap_rights_limit(pcifd, &rights) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (cap_ioctls_limit(pcifd, pci_ioctls, nitems(pci_ioctls)) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (iofd < 0) { iofd = open(_PATH_DEVIO, O_RDWR, 0); if (iofd < 0) { @@ -665,6 +677,11 @@ } } + if (cap_rights_limit(iofd, &rights) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (cap_ioctls_limit(iofd, io_ioctls, nitems(io_ioctls)) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (memfd < 0) { memfd = open(_PATH_MEM, O_RDWR, 0); if (memfd < 0) { @@ -673,6 +690,10 @@ } } + cap_rights_clear(&rights, CAP_IOCTL); + if (cap_rights_limit(memfd, &rights) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (opts == NULL || sscanf(opts, "%d/%d/%d", &bus, &slot, &func) != 3) { warnx("invalid passthru options"); Index: usr.sbin/bhyve/pci_virtio_console.c =================================================================== --- usr.sbin/bhyve/pci_virtio_console.c +++ usr.sbin/bhyve/pci_virtio_console.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include @@ -38,6 +39,7 @@ #include #include +#include #include #include #include @@ -48,6 +50,7 @@ #include #include #include +#include #include "bhyverun.h" #include "pci_emul.h" @@ -266,6 +269,7 @@ struct sockaddr_un sun; char *pathcopy; int s = -1, fd = -1, error = 0; + cap_rights_t rights; sock = calloc(1, sizeof(struct pci_vtcon_sock)); if (sock == NULL) { @@ -273,12 +277,16 @@ goto out; } - s = socket(AF_UNIX, SOCK_STREAM, 0); + s = socket(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK, 0); if (s < 0) { error = -1; goto out; } + cap_rights_init(&rights, CAP_ACCEPT, CAP_BINDAT, CAP_EVENT, CAP_LISTEN, CAP_READ, CAP_WRITE); + if (cap_rights_limit(s, &rights) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + pathcopy = strdup(path); if (pathcopy == NULL) { error = -1; @@ -303,11 +311,6 @@ goto out; } - if (fcntl(s, F_SETFL, O_NONBLOCK) < 0) { - error = -1; - goto out; - } - if (listen(s, 1) < 0) { error = -1; goto out; Index: usr.sbin/bhyve/pci_virtio_net.c =================================================================== --- usr.sbin/bhyve/pci_virtio_net.c +++ usr.sbin/bhyve/pci_virtio_net.c @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include @@ -41,6 +42,7 @@ #endif #include +#include #include #include #include @@ -53,6 +55,7 @@ #include #include #include +#include #include "bhyverun.h" #include "pci_emul.h" @@ -743,6 +746,7 @@ pci_vtnet_tap_setup(struct pci_vtnet_softc *sc, char *devname) { char tbuf[80]; + cap_rights_t rights; strcpy(tbuf, "/dev/"); strlcat(tbuf, devname, sizeof(tbuf)); @@ -767,6 +771,10 @@ sc->vsc_tapfd = -1; } + cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_EVENT); + if (cap_rights_limit(sc->vsc_tapfd, &rights) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + sc->vsc_mevp = mevent_add(sc->vsc_tapfd, EVF_READ, pci_vtnet_rx_callback, Index: usr.sbin/bhyve/pci_virtio_rnd.c =================================================================== --- usr.sbin/bhyve/pci_virtio_rnd.c +++ usr.sbin/bhyve/pci_virtio_rnd.c @@ -35,9 +35,11 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include +#include #include #include #include @@ -46,6 +48,7 @@ #include #include #include +#include #include "bhyverun.h" #include "pci_emul.h" @@ -138,6 +141,7 @@ int fd; int len; uint8_t v; + cap_rights_t rights; /* * Should always be able to open /dev/random. @@ -146,6 +150,10 @@ assert(fd >= 0); + cap_rights_init(&rights, CAP_READ); + if (cap_rights_limit(fd, &rights) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + /* * Check that device is seeded and non-blocking. */ Index: usr.sbin/bhyve/rfb.c =================================================================== --- usr.sbin/bhyve/rfb.c +++ usr.sbin/bhyve/rfb.c @@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include @@ -38,6 +39,8 @@ #include #include +#include +#include #include #include #include @@ -45,6 +48,7 @@ #include #include #include +#include #include #include @@ -868,6 +872,7 @@ struct rfb_softc *rc; struct sockaddr_in sin; int on = 1; + cap_rights_t rights; rc = calloc(1, sizeof(struct rfb_softc)); @@ -884,6 +889,10 @@ return (-1); } + cap_rights_init(&rights, CAP_ACCEPT, CAP_BIND, CAP_EVENT, CAP_LISTEN, CAP_READ, CAP_SETSOCKOPT, CAP_WRITE); + if (cap_rights_limit(rc->sfd, &rights) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + setsockopt(rc->sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); sin.sin_len = sizeof(sin); Index: usr.sbin/bhyve/uart_emul.c =================================================================== --- usr.sbin/bhyve/uart_emul.c +++ usr.sbin/bhyve/uart_emul.c @@ -31,11 +31,14 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include #include +#include +#include #include #include #include @@ -42,6 +45,7 @@ #include #include #include +#include #include "mevent.h" #include "uart_emul.h" @@ -629,6 +633,8 @@ { int fd; int retval; + cap_rights_t rights; + u_long cmds[] = {TIOCGETA, TIOCSETA, TIOCGWINSZ}; retval = -1; @@ -638,6 +644,12 @@ sc->tty.opened = true; retval = 0; } + cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_FCNTL, CAP_FSTAT, + CAP_IOCTL, CAP_EVENT); + if (cap_rights_limit(fd, &rights) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (cap_ioctls_limit(fd, cmds, nitems(cmds)) == -1 && errno != ENOSYS) + errx(EX_OSERR, "Unable to apply rights for sandbox"); return (retval); }