Index: lib/libvmmapi/vmmapi.h
===================================================================
--- lib/libvmmapi/vmmapi.h
+++ lib/libvmmapi/vmmapi.h
@@ -102,6 +102,7 @@
 	    vm_ooffset_t segoff, size_t len, int prot);
 
 int	vm_create(const char *name);
+int	vm_get_device_fd(struct vmctx *ctx);
 struct vmctx *vm_open(const char *name);
 void	vm_destroy(struct vmctx *ctx);
 int	vm_parse_memsize(const char *optarg, size_t *memsize);
Index: lib/libvmmapi/vmmapi.c
===================================================================
--- lib/libvmmapi/vmmapi.c
+++ lib/libvmmapi/vmmapi.c
@@ -1411,3 +1411,10 @@
 
 	return (ioctl(ctx->fd, VM_RESTART_INSTRUCTION, &vcpu));
 }
+
+int
+vm_get_device_fd(struct vmctx *ctx)
+{
+	return ctx->fd;
+}
+
Index: usr.sbin/bhyve/bhyverun.c
===================================================================
--- usr.sbin/bhyve/bhyverun.c
+++ usr.sbin/bhyve/bhyverun.c
@@ -30,16 +30,23 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/types.h>
+#ifndef WITHOUT_CAPSICUM
+#include <sys/capsicum.h>
+#endif
 #include <sys/mman.h>
 #include <sys/time.h>
 
 #include <machine/atomic.h>
 #include <machine/segments.h>
 
+#ifndef WITHOUT_CAPSICUM
+#include <capsicum_helpers.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <err.h>
+#include <errno.h>
 #include <libgen.h>
 #include <unistd.h>
 #include <assert.h>
@@ -48,8 +55,12 @@
 #include <pthread_np.h>
 #include <sysexits.h>
 #include <stdbool.h>
+#include <termios.h>
 
 #include <machine/vmm.h>
+#ifndef WITHOUT_CAPSICUM
+#include <machine/vmm_dev.h>
+#endif
 #include <vmmapi.h>
 
 #include "bhyverun.h"
@@ -706,6 +717,25 @@
 	struct vmctx *ctx;
 	int error;
 	bool reinit, romboot;
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_t rights;
+	/* keep in sync with machine/vmm_dev.h */
+	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}; 
+#endif
 
 	reinit = romboot = false;
 
@@ -744,6 +774,16 @@
 		exit(1);
 	}
 
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_init(&rights, CAP_IOCTL, CAP_MMAP_RWX);
+	if (cap_rights_limit(vm_get_device_fd(ctx), &rights) == -1 &&
+			errno != ENOSYS)
+		errx(EX_OSERR, "Unable to apply rights for sandbox");
+	if (cap_ioctls_limit(vm_get_device_fd(ctx), cmds, nitems(cmds)) == -1 &&
+			errno != ENOSYS)
+		errx(EX_OSERR, "Unable to apply rights for sandbox");
+#endif
+ 
 	if (reinit) {
 		error = vm_reinit(ctx);
 		if (error) {
@@ -952,6 +992,19 @@
 	if (lpc_bootrom())
 		fwctl_init();
 
+#ifndef WITHOUT_CAPSICUM
+	caph_cache_catpages();
+
+	if ((caph_limit_stdout() == -1 || caph_limit_stderr() == -1) && errno != ENOSYS)
+		errx(EX_OSERR, "Unable to apply rights for sandbox");
+
+	if (cap_enter() == -1) {
+		if (errno != ENOSYS)
+			errx(EX_OSERR, "cap_enter() failed");
+		warn("Capsicum unavailable, running without a sandbox");
+	}
+#endif
+
 	/*
 	 * 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,9 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#ifndef WITHOUT_CAPSICUM
+#include <sys/capsicum.h>
+#endif
 #include <sys/queue.h>
 #include <sys/errno.h>
 #include <sys/stat.h>
@@ -45,6 +48,7 @@
 #include <pthread.h>
 #include <pthread_np.h>
 #include <signal.h>
+#include <sysexits.h>
 #include <unistd.h>
 
 #include <machine/atomic.h>
@@ -400,6 +404,10 @@
 	off_t size, psectsz, psectoff;
 	int extra, fd, i, sectsz;
 	int nocache, sync, ro, candelete, geom, ssopt, pssopt;
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_t rights;
+	u_long cmds[] = {DIOCGFLUSH, DIOCGDELETE};
+#endif
 
 	pthread_once(&blockif_once, blockif_init);
 
@@ -457,6 +465,15 @@
 		goto err;
         }
 
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_init(&rights, CAP_IOCTL, CAP_READ, CAP_SEEK, CAP_WRITE);
+	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");
+#endif
+
         /*
 	 * Deal with raw devices
 	 */
@@ -483,6 +500,11 @@
 	} else
 		psectsz = sbuf.st_blksize;
 
+#ifndef WITHOUT_CAPSICUM
+	if (cap_ioctls_limit(fd, cmds, nitems(cmds)) == -1 && errno != ENOSYS)
+		errx(EX_OSERR, "Unable to apply rights for sandbox");
+#endif
+
 	if (ssopt != 0) {
 		if (!powerof2(ssopt) || !powerof2(pssopt) || ssopt < 512 ||
 		    ssopt > pssopt) {
Index: usr.sbin/bhyve/consport.c
===================================================================
--- usr.sbin/bhyve/consport.c
+++ usr.sbin/bhyve/consport.c
@@ -30,13 +30,19 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/types.h>
+#ifndef WITHOUT_CAPSICUM
+#include <sys/capsicum.h>
+#endif
 #include <sys/select.h>
 
+#include <err.h>
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <termios.h>
 #include <unistd.h>
 #include <stdbool.h>
+#include <sysexits.h>
 
 #include "inout.h"
 #include "pci_lpc.h"
@@ -104,6 +110,10 @@
 		uint32_t *eax, void *arg)
 {
 	static int opened;
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_t rights;
+	u_long cmds[] = {TIOCGETA, TIOCSETA, TIOCGWINSZ};
+#endif
 
 	if (bytes == 2 && in) {
 		*eax = BVM_CONS_SIG;
@@ -123,6 +133,13 @@
 		return (-1);
 
 	if (!opened) {
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ, CAP_WRITE);
+	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");
+#endif
 		ttyopen();
 		opened = 1;
 	}
Index: usr.sbin/bhyve/mevent.c
===================================================================
--- usr.sbin/bhyve/mevent.c
+++ usr.sbin/bhyve/mevent.c
@@ -35,13 +35,18 @@
 __FBSDID("$FreeBSD$");
 
 #include <assert.h>
+#include <err.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <sysexits.h>
 #include <unistd.h>
 
 #include <sys/types.h>
+#ifndef WITHOUT_CAPSICUM
+#include <sys/capsicum.h>
+#endif
 #include <sys/event.h>
 #include <sys/time.h>
 
@@ -401,6 +406,9 @@
 	int mfd;
 	int numev;
 	int ret;
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_t rights;
+#endif
 
 	mevent_tid = pthread_self();
 	mevent_set_name();
@@ -408,6 +416,12 @@
 	mfd = kqueue();
 	assert(mfd > 0);
 
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_init(&rights, CAP_KQUEUE);
+	if (cap_rights_limit(mfd, &rights) == -1 && errno != ENOSYS)
+		errx(EX_OSERR, "Unable to apply rights for sandbox");
+#endif
+
 	/*
 	 * 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 +433,14 @@
 		exit(0);
 	}
 
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_init(&rights, CAP_EVENT, CAP_READ, CAP_WRITE);
+	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");
+#endif
+
 	/*
 	 * 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,9 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#ifndef WITHOUT_CAPSICUM
+#include <sys/capsicum.h>
+#endif
 #include <sys/linker_set.h>
 #include <sys/stat.h>
 #include <sys/uio.h>
@@ -2293,11 +2296,21 @@
 	MD5_CTX mdctx;
 	u_char digest[16];
 	char *next, *next2;
+#ifdef AHCI_DEBUG
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_t rights;
+#endif
+#endif
 
 	ret = 0;
 
 #ifdef AHCI_DEBUG
 	dbg = fopen("/tmp/log", "w+");
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_init(&rights, CAP_WRITE);
+	if (cap_rights_limit(fileno(dbg), &rights) == -1 && errno != ENOSYS)
+		errx(EX_OSERR, "Unable to apply rights for sandbox");
+#endif
 #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,9 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/types.h>
+#ifndef WITHOUT_CAPSICUM
+#include <sys/capsicum.h>
+#endif
 #include <sys/limits.h>
 #include <sys/ioctl.h>
 #include <sys/uio.h>
@@ -38,12 +41,14 @@
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 
+#include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <md5.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sysexits.h>
 #include <unistd.h>
 #include <pthread.h>
 #include <pthread_np.h>
@@ -2202,6 +2207,9 @@
 e82545_open_tap(struct e82545_softc *sc, char *opts)
 {
 	char tbuf[80];
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_t rights;
+#endif
 	
 	if (opts == NULL) {
 		sc->esc_tapfd = -1;
@@ -2228,6 +2236,12 @@
 		sc->esc_tapfd = -1;
 	}
 
+#ifndef WITHOUT_CAPSICUM
+	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");
+#endif
+	
 	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,9 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#ifndef WITHOUT_CAPSICUM
+#include <sys/capsicum.h>
+#endif
 #include <sys/types.h>
 #include <sys/mman.h>
 #include <sys/pciio.h>
@@ -44,7 +47,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <err.h>
+#include <errno.h>
 #include <fcntl.h>
+#include <sysexits.h>
 #include <unistd.h>
 
 #include <machine/vmm.h>
@@ -639,10 +644,19 @@
 {
 	int bus, slot, func, error, memflags;
 	struct passthru_softc *sc;
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_t rights;
+	u_long pci_ioctls[] = {PCIOCREAD, PCIOCWRITE, PCIOCGETBAR};
+	u_long io_ioctls[] = {IODEV_PIO};
+#endif
 
 	sc = NULL;
 	error = 1;
 
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_init(&rights, CAP_IOCTL, CAP_READ, CAP_WRITE);
+#endif
+
 	memflags = vm_get_memflags(ctx);
 	if (!(memflags & VM_MEM_F_WIRED)) {
 		warnx("passthru requires guest memory to be wired");
@@ -657,6 +671,13 @@
 		}
 	}
 
+#ifndef WITHOUT_CAPSICUM
+	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");
+#endif
+
 	if (iofd < 0) {
 		iofd = open(_PATH_DEVIO, O_RDWR, 0);
 		if (iofd < 0) {
@@ -665,6 +686,13 @@
 		}
 	}
 
+#ifndef WITHOUT_CAPSICUM
+	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");
+#endif
+
 	if (memfd < 0) {
 		memfd = open(_PATH_MEM, O_RDWR, 0);
 		if (memfd < 0) {
@@ -673,6 +701,12 @@
 		}
 	}
 
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_clear(&rights, CAP_IOCTL);
+	if (cap_rights_limit(memfd, &rights) == -1 && errno != ENOSYS)
+		errx(EX_OSERR, "Unable to apply rights for sandbox");
+#endif
+
 	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,12 +32,16 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#ifndef WITHOUT_CAPSICUM
+#include <sys/capsicum.h>
+#endif
 #include <sys/linker_set.h>
 #include <sys/uio.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 
+#include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
@@ -48,6 +52,7 @@
 #include <assert.h>
 #include <pthread.h>
 #include <libgen.h>
+#include <sysexits.h>
 
 #include "bhyverun.h"
 #include "pci_emul.h"
@@ -266,6 +271,9 @@
 	struct sockaddr_un sun;
 	char *pathcopy;
 	int s = -1, fd = -1, error = 0;
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_t rights;
+#endif
 
 	sock = calloc(1, sizeof(struct pci_vtcon_sock));
 	if (sock == NULL) {
@@ -313,6 +321,11 @@
 		goto out;
 	}
 
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_init(&rights, CAP_ACCEPT, CAP_EVENT, CAP_READ, CAP_WRITE);
+	if (cap_rights_limit(s, &rights) == -1 && errno != ENOSYS)
+		errx(EX_OSERR, "Unable to apply rights for sandbox");
+#endif
 
 	sock->vss_port = pci_vtcon_port_add(sc, name, pci_vtcon_sock_tx, sock);
 	if (sock->vss_port == NULL) {
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,9 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#ifndef WITHOUT_CAPSICUM
+#include <sys/capsicum.h>
+#endif
 #include <sys/linker_set.h>
 #include <sys/select.h>
 #include <sys/uio.h>
@@ -41,6 +44,7 @@
 #endif
 #include <net/netmap_user.h>
 
+#include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
@@ -53,6 +57,7 @@
 #include <md5.h>
 #include <pthread.h>
 #include <pthread_np.h>
+#include <sysexits.h>
 
 #include "bhyverun.h"
 #include "pci_emul.h"
@@ -743,6 +748,9 @@
 pci_vtnet_tap_setup(struct pci_vtnet_softc *sc, char *devname)
 {
 	char tbuf[80];
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_t rights;
+#endif
 
 	strcpy(tbuf, "/dev/");
 	strlcat(tbuf, devname, sizeof(tbuf));
@@ -767,6 +775,12 @@
 		sc->vsc_tapfd = -1;
 	}
 
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_init(&rights, CAP_EVENT, CAP_READ, CAP_WRITE);
+	if (cap_rights_limit(sc->vsc_tapfd, &rights) == -1 && errno != ENOSYS)
+		errx(EX_OSERR, "Unable to apply rights for sandbox");
+#endif
+
 	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,13 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#ifndef WITHOUT_CAPSICUM
+#include <sys/capsicum.h>
+#endif
 #include <sys/linker_set.h>
 #include <sys/uio.h>
 
+#include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
@@ -46,6 +50,7 @@
 #include <unistd.h>
 #include <assert.h>
 #include <pthread.h>
+#include <sysexits.h>
 
 #include "bhyverun.h"
 #include "pci_emul.h"
@@ -138,6 +143,9 @@
 	int fd;
 	int len;
 	uint8_t v;
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_t rights;
+#endif
 
 	/*
 	 * Should always be able to open /dev/random.
@@ -146,6 +154,12 @@
 
 	assert(fd >= 0);
 
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_init(&rights, CAP_EVENT, CAP_READ);
+	if (cap_rights_limit(fd, &rights) == -1 && errno != ENOSYS)
+		errx(EX_OSERR, "Unable to apply rights for sandbox");
+#endif
+
 	/*
 	 * 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,9 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#ifndef WITHOUT_CAPSICUM
+#include <sys/capsicum.h>
+#endif
 #include <sys/socket.h>
 #include <sys/select.h>
 #include <sys/time.h>
@@ -38,6 +41,8 @@
 #include <netinet/in.h>
 
 #include <assert.h>
+#include <err.h>
+#include <errno.h>
 #include <pthread.h>
 #include <pthread_np.h>
 #include <signal.h>
@@ -45,6 +50,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <sysexits.h>
 #include <unistd.h>
 
 #include <zlib.h>
@@ -868,6 +874,9 @@
 	struct rfb_softc *rc;
 	struct sockaddr_in sin;
 	int on = 1;
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_t rights;
+#endif
 
 	rc = calloc(1, sizeof(struct rfb_softc));
 
@@ -904,6 +913,12 @@
 		return (-1);
 	}
 
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_init(&rights, CAP_ACCEPT, CAP_EVENT, CAP_READ, CAP_WRITE);
+	if (cap_rights_limit(rc->sfd, &rights) == -1 && errno != ENOSYS)
+		errx(EX_OSERR, "Unable to apply rights for sandbox");
+#endif
+
 	rc->hw_crc = sse42_supported();
 
 	rc->conn_wait = wait;
Index: usr.sbin/bhyve/uart_emul.c
===================================================================
--- usr.sbin/bhyve/uart_emul.c
+++ usr.sbin/bhyve/uart_emul.c
@@ -32,16 +32,23 @@
 
 #include <sys/types.h>
 #include <dev/ic/ns16550.h>
+#ifndef WITHOUT_CAPSICUM
+#include <sys/capsicum.h>
+#include <capsicum_helpers.h>
+#endif
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
+#include <err.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <termios.h>
 #include <unistd.h>
 #include <stdbool.h>
 #include <string.h>
 #include <pthread.h>
+#include <sysexits.h>
 
 #include "mevent.h"
 #include "uart_emul.h"
@@ -638,7 +645,7 @@
 		sc->tty.opened = true;
 		retval = 0;
 	}
-	    
+
 	return (retval);
 }
 
@@ -646,6 +653,10 @@
 uart_set_backend(struct uart_softc *sc, const char *opts)
 {
 	int retval;
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_t rights;
+	u_long cmds[] = {TIOCGETA, TIOCSETA, TIOCGWINSZ};
+#endif
 
 	retval = -1;
 
@@ -667,6 +678,18 @@
 	if (retval == 0)
 		retval = fcntl(sc->tty.fd, F_SETFL, O_NONBLOCK);
 
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ, CAP_WRITE);
+	if (cap_rights_limit(sc->tty.fd, &rights) == -1 && errno != ENOSYS)
+		errx(EX_OSERR, "Unable to apply rights for sandbox");
+	if (cap_ioctls_limit(sc->tty.fd, cmds, nitems(cmds)) == -1 && errno != ENOSYS)
+		errx(EX_OSERR, "Unable to apply rights for sandbox");
+	if (!uart_stdio) {
+		if (caph_limit_stdin() == -1 && errno != ENOSYS)
+			errx(EX_OSERR, "Unable to apply rights for sandbox");
+	}
+#endif
+
 	if (retval == 0)
 		uart_opentty(sc);