Page MenuHomeFreeBSD

D8290.id21515.diff
No OneTemporary

D8290.id21515.diff

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 <sys/types.h>
+#include <sys/capsicum.h>
+#include <sys/cpuset.h>
#include <sys/mman.h>
#include <sys/time.h>
@@ -40,7 +42,9 @@
#include <stdlib.h>
#include <string.h>
#include <err.h>
+#include <errno.h>
#include <libgen.h>
+#include <nl_types.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
@@ -48,8 +52,10 @@
#include <pthread_np.h>
#include <sysexits.h>
#include <stdbool.h>
+#include <termios.h>
#include <machine/vmm.h>
+#include <machine/vmm_dev.h>
#include <vmmapi.h>
#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 <sys/param.h>
+#include <sys/capsicum.h>
#include <sys/queue.h>
#include <sys/errno.h>
#include <sys/stat.h>
@@ -45,6 +46,7 @@
#include <pthread.h>
#include <pthread_np.h>
#include <signal.h>
+#include <sysexits.h>
#include <unistd.h>
#include <machine/atomic.h>
@@ -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/bootrom.c
===================================================================
--- usr.sbin/bhyve/bootrom.c
+++ usr.sbin/bhyve/bootrom.c
@@ -63,11 +63,11 @@
goto done;
}
- if (fstat(fd, &sbuf) < 0) {
+ if (fstat(fd, &sbuf) < 0) {
fprintf(stderr, "Could not fstat bootrom file \"%s\": %s\n",
romfile, strerror(errno));
goto done;
- }
+ }
/*
* Limit bootrom size to 16MB so it doesn't encroach into reserved
Index: usr.sbin/bhyve/mevent.c
===================================================================
--- usr.sbin/bhyve/mevent.c
+++ usr.sbin/bhyve/mevent.c
@@ -35,13 +35,16 @@
__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>
+#include <sys/capsicum.h>
#include <sys/event.h>
#include <sys/time.h>
@@ -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 <sys/param.h>
+#include <sys/capsicum.h>
#include <sys/linker_set.h>
#include <sys/stat.h>
#include <sys/uio.h>
@@ -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 <sys/types.h>
+#include <sys/capsicum.h>
#include <sys/limits.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
@@ -38,6 +39,7 @@
#include <netinet/in.h>
#include <netinet/tcp.h>
+#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <md5.h>
@@ -44,6 +46,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sysexits.h>
#include <unistd.h>
#include <pthread.h>
#include <pthread_np.h>
@@ -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 <sys/param.h>
+#include <sys/capsicum.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/pciio.h>
@@ -44,7 +45,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,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 <sys/param.h>
+#include <sys/capsicum.h>
#include <sys/linker_set.h>
#include <sys/uio.h>
#include <sys/types.h>
@@ -38,6 +39,7 @@
#include <sys/socket.h>
#include <sys/un.h>
+#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
@@ -48,6 +50,7 @@
#include <assert.h>
#include <pthread.h>
#include <libgen.h>
+#include <sysexits.h>
#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 <sys/param.h>
+#include <sys/capsicum.h>
#include <sys/linker_set.h>
#include <sys/select.h>
#include <sys/uio.h>
@@ -41,6 +42,7 @@
#endif
#include <net/netmap_user.h>
+#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
@@ -53,6 +55,7 @@
#include <md5.h>
#include <pthread.h>
#include <pthread_np.h>
+#include <sysexits.h>
#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 <sys/param.h>
+#include <sys/capsicum.h>
#include <sys/linker_set.h>
#include <sys/uio.h>
+#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
@@ -46,6 +48,7 @@
#include <unistd.h>
#include <assert.h>
#include <pthread.h>
+#include <sysexits.h>
#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 <sys/param.h>
+#include <sys/capsicum.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
@@ -38,6 +39,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 +48,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <sysexits.h>
#include <unistd.h>
#include <zlib.h>
@@ -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 <sys/types.h>
+#include <sys/capsicum.h>
#include <dev/ic/ns16550.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
+#include <err.h>
+#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
@@ -42,6 +45,7 @@
#include <stdbool.h>
#include <string.h>
#include <pthread.h>
+#include <sysexits.h>
#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);
}

File Metadata

Mime Type
text/plain
Expires
Thu, Mar 13, 7:31 AM (11 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17131747
Default Alt Text
D8290.id21515.diff (17 KB)

Event Timeline