From 3a0c3a66a478e86cbb93f0c8170d3f58ab51c181 Mon Sep 17 00:00:00 2001 From: reyk Date: Tue, 25 Apr 2017 16:38:23 +0000 Subject: [PATCH] Generate randomized MAC addresses earlier to keep them across reboots. OK deraadt@ --- usr.sbin/vmd/virtio.c | 27 ++++----------------------- usr.sbin/vmd/vmd.c | 22 +++++++++++++++++++++- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/usr.sbin/vmd/virtio.c b/usr.sbin/vmd/virtio.c index 5bdb999092d..f84110a5301 100644 --- a/usr.sbin/vmd/virtio.c +++ b/usr.sbin/vmd/virtio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: virtio.c,v 1.42 2017/04/19 15:38:32 reyk Exp $ */ +/* $OpenBSD: virtio.c,v 1.43 2017/04/25 16:38:23 reyk Exp $ */ /* * Copyright (c) 2015 Mike Larkin @@ -1599,10 +1599,9 @@ virtio_init(struct vmd_vm *vm, int *child_disks, int *child_taps) { struct vmop_create_params *vmc = &vm->vm_params; struct vm_create_params *vcp = &vmc->vmc_params; - static const uint8_t zero_mac[6]; uint8_t id; uint8_t i; - int ret, rng; + int ret; off_t sz; /* Virtio entropy device */ @@ -1738,28 +1737,10 @@ virtio_init(struct vmd_vm *vm, int *child_disks, int *child_taps) return; } + /* MAC address has been assigned by the parent */ + memcpy(&vionet[i].mac, &vcp->vcp_macs[i], 6); vionet[i].cfg.device_feature = VIRTIO_NET_F_MAC; - if (memcmp(zero_mac, &vcp->vcp_macs[i], 6) != 0) { - /* User-defined address */ - memcpy(&vionet[i].mac, &vcp->vcp_macs[i], 6); - } else { - /* - * If the address is zero, always randomize - * it in vmd(8) because we cannot rely on - * the guest OS to do the right thing like - * OpenBSD does. Based on ether_fakeaddr() - * from the kernel, incremented by one to - * differentiate the source. - */ - rng = arc4random(); - vionet[i].mac[0] = 0xfe; - vionet[i].mac[1] = 0xe1; - vionet[i].mac[2] = 0xba + 1; - vionet[i].mac[3] = 0xd0 | ((i + 1) & 0xf); - vionet[i].mac[4] = rng; - vionet[i].mac[5] = rng >> 8; - } vionet[i].lockedmac = vmc->vmc_ifflags[i] & VMIFF_LOCKED ? 1 : 0; vionet[i].local = diff --git a/usr.sbin/vmd/vmd.c b/usr.sbin/vmd/vmd.c index 65918419b3b..91f387d09e2 100644 --- a/usr.sbin/vmd/vmd.c +++ b/usr.sbin/vmd/vmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmd.c,v 1.58 2017/04/21 07:03:26 reyk Exp $ */ +/* $OpenBSD: vmd.c,v 1.59 2017/04/25 16:38:23 reyk Exp $ */ /* * Copyright (c) 2015 Reyk Floeter @@ -796,6 +796,8 @@ vm_register(struct privsep *ps, struct vmop_create_params *vmc, { struct vmd_vm *vm = NULL; struct vm_create_params *vcp = &vmc->vmc_params; + static const uint8_t zero_mac[ETHER_ADDR_LEN]; + uint32_t rng; unsigned int i; struct vmd_switch *sw; @@ -851,6 +853,7 @@ vm_register(struct privsep *ps, struct vmop_create_params *vmc, memcpy(&vm->vm_params, vmc, sizeof(vm->vm_params)); vmc = &vm->vm_params; + vcp = &vmc->vmc_params; vm->vm_pid = -1; vm->vm_tty = -1; @@ -863,6 +866,23 @@ vm_register(struct privsep *ps, struct vmop_create_params *vmc, /* inherit per-interface flags from the switch */ vmc->vmc_ifflags[i] |= (sw->sw_flags & VMIFF_OPTMASK); } + + /* + * If the MAC address is zero, always randomize it in vmd(8) + * because we cannot rely on the guest OS to do the right + * thing like OpenBSD does. Based on ether_fakeaddr() + * from the kernel, incremented by one to differentiate + * the source. + */ + if (memcmp(zero_mac, &vcp->vcp_macs[i], ETHER_ADDR_LEN) == 0) { + rng = arc4random(); + vcp->vcp_macs[i][0] = 0xfe; + vcp->vcp_macs[i][1] = 0xe1; + vcp->vcp_macs[i][2] = 0xba + 1; + vcp->vcp_macs[i][3] = 0xd0 | ((i + 1) & 0xf); + vcp->vcp_macs[i][4] = rng; + vcp->vcp_macs[i][5] = rng >> 8; + } } vm->vm_kernel = -1; vm->vm_iev.ibuf.fd = -1; -- 2.20.1