1 /* $OpenBSD: vmd.c,v 1.135 2022/12/28 21:30:19 jmc Exp $ */ 2 3 /* 4 * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 #include <sys/queue.h> 21 #include <sys/wait.h> 22 #include <sys/stat.h> 23 #include <sys/sysctl.h> 24 #include <sys/tty.h> 25 #include <sys/ttycom.h> 26 #include <sys/ioctl.h> 27 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <string.h> 31 #include <termios.h> 32 #include <errno.h> 33 #include <event.h> 34 #include <fcntl.h> 35 #include <pwd.h> 36 #include <signal.h> 37 #include <syslog.h> 38 #include <unistd.h> 39 #include <util.h> 40 #include <ctype.h> 41 #include <pwd.h> 42 #include <grp.h> 43 44 #include <machine/specialreg.h> 45 #include <machine/vmmvar.h> 46 47 #include "proc.h" 48 #include "atomicio.h" 49 #include "vmd.h" 50 51 __dead void usage(void); 52 53 int main(int, char **); 54 int vmd_configure(void); 55 void vmd_sighdlr(int sig, short event, void *arg); 56 void vmd_shutdown(void); 57 int vmd_control_run(void); 58 int vmd_dispatch_control(int, struct privsep_proc *, struct imsg *); 59 int vmd_dispatch_vmm(int, struct privsep_proc *, struct imsg *); 60 int vmd_dispatch_agentx(int, struct privsep_proc *, struct imsg *); 61 int vmd_dispatch_priv(int, struct privsep_proc *, struct imsg *); 62 int vmd_check_vmh(struct vm_dump_header *); 63 64 int vm_instance(struct privsep *, struct vmd_vm **, 65 struct vmop_create_params *, uid_t); 66 int vm_checkinsflag(struct vmop_create_params *, unsigned int, uid_t); 67 int vm_claimid(const char *, int, uint32_t *); 68 void start_vm_batch(int, short, void*); 69 70 struct vmd *env; 71 72 static struct privsep_proc procs[] = { 73 /* Keep "priv" on top as procs[0] */ 74 { "priv", PROC_PRIV, vmd_dispatch_priv, priv }, 75 { "control", PROC_CONTROL, vmd_dispatch_control, control }, 76 { "vmm", PROC_VMM, vmd_dispatch_vmm, vmm, vmm_shutdown }, 77 { "agentx", PROC_AGENTX, vmd_dispatch_agentx, vm_agentx, vm_agentx_shutdown, "/" } 78 }; 79 80 enum privsep_procid privsep_process; 81 82 struct event staggered_start_timer; 83 84 /* For the privileged process */ 85 static struct privsep_proc *proc_priv = &procs[0]; 86 static struct passwd proc_privpw; 87 static const uint8_t zero_mac[ETHER_ADDR_LEN]; 88 89 int 90 vmd_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg) 91 { 92 struct privsep *ps = p->p_ps; 93 int res = 0, ret = 0, cmd = 0, verbose; 94 unsigned int v = 0, flags; 95 struct vmop_create_params vmc; 96 struct vmop_id vid; 97 struct vmop_result vmr; 98 struct vm_dump_header vmh; 99 struct vmd_vm *vm = NULL; 100 char *str = NULL; 101 uint32_t id = 0; 102 struct control_sock *rcs; 103 104 switch (imsg->hdr.type) { 105 case IMSG_VMDOP_START_VM_REQUEST: 106 IMSG_SIZE_CHECK(imsg, &vmc); 107 memcpy(&vmc, imsg->data, sizeof(vmc)); 108 ret = vm_register(ps, &vmc, &vm, 0, vmc.vmc_owner.uid); 109 if (vmc.vmc_flags == 0) { 110 /* start an existing VM with pre-configured options */ 111 if (!(ret == -1 && errno == EALREADY && 112 !(vm->vm_state & VM_STATE_RUNNING))) { 113 res = errno; 114 cmd = IMSG_VMDOP_START_VM_RESPONSE; 115 } 116 } else if (ret != 0) { 117 res = errno; 118 cmd = IMSG_VMDOP_START_VM_RESPONSE; 119 } 120 if (res == 0) { 121 res = config_setvm(ps, vm, imsg->hdr.peerid, 122 vm->vm_params.vmc_owner.uid); 123 if (res) 124 cmd = IMSG_VMDOP_START_VM_RESPONSE; 125 } 126 break; 127 case IMSG_VMDOP_WAIT_VM_REQUEST: 128 case IMSG_VMDOP_TERMINATE_VM_REQUEST: 129 IMSG_SIZE_CHECK(imsg, &vid); 130 memcpy(&vid, imsg->data, sizeof(vid)); 131 flags = vid.vid_flags; 132 cmd = IMSG_VMDOP_TERMINATE_VM_RESPONSE; 133 134 if ((id = vid.vid_id) == 0) { 135 /* Lookup vm (id) by name */ 136 if ((vm = vm_getbyname(vid.vid_name)) == NULL) { 137 res = ENOENT; 138 break; 139 } else if ((vm->vm_state & VM_STATE_SHUTDOWN) && 140 (flags & VMOP_FORCE) == 0) { 141 res = EALREADY; 142 break; 143 } else if (!(vm->vm_state & VM_STATE_RUNNING)) { 144 res = EINVAL; 145 break; 146 } 147 id = vm->vm_vmid; 148 } else if ((vm = vm_getbyvmid(id)) == NULL) { 149 res = ENOENT; 150 break; 151 } 152 if (vm_checkperm(vm, &vm->vm_params.vmc_owner, vid.vid_uid)) { 153 res = EPERM; 154 break; 155 } 156 157 /* Only relay TERMINATION requests, not WAIT requests */ 158 if (imsg->hdr.type == IMSG_VMDOP_TERMINATE_VM_REQUEST) { 159 memset(&vid, 0, sizeof(vid)); 160 vid.vid_id = id; 161 vid.vid_flags = flags; 162 163 if (proc_compose_imsg(ps, PROC_VMM, -1, imsg->hdr.type, 164 imsg->hdr.peerid, -1, &vid, sizeof(vid)) == -1) 165 return (-1); 166 } 167 break; 168 case IMSG_VMDOP_GET_INFO_VM_REQUEST: 169 proc_forward_imsg(ps, imsg, PROC_VMM, -1); 170 break; 171 case IMSG_VMDOP_LOAD: 172 IMSG_SIZE_CHECK(imsg, str); /* at least one byte for path */ 173 str = get_string((uint8_t *)imsg->data, 174 IMSG_DATA_SIZE(imsg)); 175 case IMSG_VMDOP_RELOAD: 176 if (vmd_reload(0, str) == -1) 177 cmd = IMSG_CTL_FAIL; 178 else 179 cmd = IMSG_CTL_OK; 180 free(str); 181 break; 182 case IMSG_CTL_RESET: 183 IMSG_SIZE_CHECK(imsg, &v); 184 memcpy(&v, imsg->data, sizeof(v)); 185 if (vmd_reload(v, NULL) == -1) 186 cmd = IMSG_CTL_FAIL; 187 else 188 cmd = IMSG_CTL_OK; 189 break; 190 case IMSG_CTL_VERBOSE: 191 IMSG_SIZE_CHECK(imsg, &verbose); 192 memcpy(&verbose, imsg->data, sizeof(verbose)); 193 log_setverbose(verbose); 194 195 proc_forward_imsg(ps, imsg, PROC_VMM, -1); 196 proc_forward_imsg(ps, imsg, PROC_PRIV, -1); 197 cmd = IMSG_CTL_OK; 198 break; 199 case IMSG_VMDOP_PAUSE_VM: 200 case IMSG_VMDOP_UNPAUSE_VM: 201 IMSG_SIZE_CHECK(imsg, &vid); 202 memcpy(&vid, imsg->data, sizeof(vid)); 203 if (vid.vid_id == 0) { 204 if ((vm = vm_getbyname(vid.vid_name)) == NULL) { 205 res = ENOENT; 206 cmd = imsg->hdr.type == IMSG_VMDOP_PAUSE_VM 207 ? IMSG_VMDOP_PAUSE_VM_RESPONSE 208 : IMSG_VMDOP_UNPAUSE_VM_RESPONSE; 209 break; 210 } else { 211 vid.vid_id = vm->vm_vmid; 212 } 213 } else if ((vm = vm_getbyid(vid.vid_id)) == NULL) { 214 res = ENOENT; 215 cmd = imsg->hdr.type == IMSG_VMDOP_PAUSE_VM 216 ? IMSG_VMDOP_PAUSE_VM_RESPONSE 217 : IMSG_VMDOP_UNPAUSE_VM_RESPONSE; 218 break; 219 } 220 if (vm_checkperm(vm, &vm->vm_params.vmc_owner, 221 vid.vid_uid) != 0) { 222 res = EPERM; 223 cmd = imsg->hdr.type == IMSG_VMDOP_PAUSE_VM 224 ? IMSG_VMDOP_PAUSE_VM_RESPONSE 225 : IMSG_VMDOP_UNPAUSE_VM_RESPONSE; 226 break; 227 } 228 proc_compose_imsg(ps, PROC_VMM, -1, imsg->hdr.type, 229 imsg->hdr.peerid, -1, &vid, sizeof(vid)); 230 break; 231 case IMSG_VMDOP_SEND_VM_REQUEST: 232 IMSG_SIZE_CHECK(imsg, &vid); 233 memcpy(&vid, imsg->data, sizeof(vid)); 234 id = vid.vid_id; 235 if (vid.vid_id == 0) { 236 if ((vm = vm_getbyname(vid.vid_name)) == NULL) { 237 res = ENOENT; 238 cmd = IMSG_VMDOP_SEND_VM_RESPONSE; 239 close(imsg->fd); 240 break; 241 } else { 242 vid.vid_id = vm->vm_vmid; 243 } 244 } else if ((vm = vm_getbyvmid(vid.vid_id)) == NULL) { 245 res = ENOENT; 246 cmd = IMSG_VMDOP_SEND_VM_RESPONSE; 247 close(imsg->fd); 248 break; 249 } 250 vmr.vmr_id = vid.vid_id; 251 log_debug("%s: sending fd to vmm", __func__); 252 proc_compose_imsg(ps, PROC_VMM, -1, imsg->hdr.type, 253 imsg->hdr.peerid, imsg->fd, &vid, sizeof(vid)); 254 break; 255 case IMSG_VMDOP_RECEIVE_VM_REQUEST: 256 IMSG_SIZE_CHECK(imsg, &vid); 257 memcpy(&vid, imsg->data, sizeof(vid)); 258 if (imsg->fd == -1) { 259 log_warnx("%s: invalid fd", __func__); 260 return (-1); 261 } 262 if (atomicio(read, imsg->fd, &vmh, sizeof(vmh)) != 263 sizeof(vmh)) { 264 log_warnx("%s: error reading vmh from received vm", 265 __func__); 266 res = EIO; 267 close(imsg->fd); 268 cmd = IMSG_VMDOP_START_VM_RESPONSE; 269 break; 270 } 271 272 if (vmd_check_vmh(&vmh)) { 273 res = ENOENT; 274 close(imsg->fd); 275 cmd = IMSG_VMDOP_START_VM_RESPONSE; 276 break; 277 } 278 if (atomicio(read, imsg->fd, &vmc, sizeof(vmc)) != 279 sizeof(vmc)) { 280 log_warnx("%s: error reading vmc from received vm", 281 __func__); 282 res = EIO; 283 close(imsg->fd); 284 cmd = IMSG_VMDOP_START_VM_RESPONSE; 285 break; 286 } 287 strlcpy(vmc.vmc_params.vcp_name, vid.vid_name, 288 sizeof(vmc.vmc_params.vcp_name)); 289 vmc.vmc_params.vcp_id = 0; 290 291 ret = vm_register(ps, &vmc, &vm, 0, vmc.vmc_owner.uid); 292 if (ret != 0) { 293 res = errno; 294 cmd = IMSG_VMDOP_START_VM_RESPONSE; 295 close(imsg->fd); 296 } else { 297 vm->vm_state |= VM_STATE_RECEIVED; 298 config_setvm(ps, vm, imsg->hdr.peerid, 299 vmc.vmc_owner.uid); 300 log_debug("%s: sending fd to vmm", __func__); 301 proc_compose_imsg(ps, PROC_VMM, -1, 302 IMSG_VMDOP_RECEIVE_VM_END, vm->vm_vmid, imsg->fd, 303 NULL, 0); 304 } 305 break; 306 case IMSG_VMDOP_DONE: 307 control_reset(&ps->ps_csock); 308 TAILQ_FOREACH(rcs, &ps->ps_rcsocks, cs_entry) 309 control_reset(rcs); 310 cmd = 0; 311 break; 312 default: 313 return (-1); 314 } 315 316 switch (cmd) { 317 case 0: 318 break; 319 case IMSG_VMDOP_START_VM_RESPONSE: 320 case IMSG_VMDOP_TERMINATE_VM_RESPONSE: 321 memset(&vmr, 0, sizeof(vmr)); 322 vmr.vmr_result = res; 323 vmr.vmr_id = id; 324 if (proc_compose_imsg(ps, PROC_CONTROL, -1, cmd, 325 imsg->hdr.peerid, -1, &vmr, sizeof(vmr)) == -1) 326 return (-1); 327 break; 328 default: 329 if (proc_compose_imsg(ps, PROC_CONTROL, -1, cmd, 330 imsg->hdr.peerid, -1, &res, sizeof(res)) == -1) 331 return (-1); 332 break; 333 } 334 335 return (0); 336 } 337 338 int 339 vmd_dispatch_vmm(int fd, struct privsep_proc *p, struct imsg *imsg) 340 { 341 struct vmop_result vmr; 342 struct privsep *ps = p->p_ps; 343 int res = 0; 344 struct vmd_vm *vm; 345 struct vm_create_params *vcp; 346 struct vmop_info_result vir; 347 348 switch (imsg->hdr.type) { 349 case IMSG_VMDOP_PAUSE_VM_RESPONSE: 350 IMSG_SIZE_CHECK(imsg, &vmr); 351 memcpy(&vmr, imsg->data, sizeof(vmr)); 352 if ((vm = vm_getbyvmid(vmr.vmr_id)) == NULL) 353 break; 354 proc_compose_imsg(ps, PROC_CONTROL, -1, 355 imsg->hdr.type, imsg->hdr.peerid, -1, 356 imsg->data, sizeof(imsg->data)); 357 log_info("%s: paused vm %d successfully", 358 vm->vm_params.vmc_params.vcp_name, 359 vm->vm_vmid); 360 vm->vm_state |= VM_STATE_PAUSED; 361 break; 362 case IMSG_VMDOP_UNPAUSE_VM_RESPONSE: 363 IMSG_SIZE_CHECK(imsg, &vmr); 364 memcpy(&vmr, imsg->data, sizeof(vmr)); 365 if ((vm = vm_getbyvmid(vmr.vmr_id)) == NULL) 366 break; 367 proc_compose_imsg(ps, PROC_CONTROL, -1, 368 imsg->hdr.type, imsg->hdr.peerid, -1, 369 imsg->data, sizeof(imsg->data)); 370 log_info("%s: unpaused vm %d successfully.", 371 vm->vm_params.vmc_params.vcp_name, 372 vm->vm_vmid); 373 vm->vm_state &= ~VM_STATE_PAUSED; 374 break; 375 case IMSG_VMDOP_START_VM_RESPONSE: 376 IMSG_SIZE_CHECK(imsg, &vmr); 377 memcpy(&vmr, imsg->data, sizeof(vmr)); 378 if ((vm = vm_getbyvmid(imsg->hdr.peerid)) == NULL) 379 break; 380 vm->vm_pid = vmr.vmr_pid; 381 vcp = &vm->vm_params.vmc_params; 382 vcp->vcp_id = vmr.vmr_id; 383 384 /* 385 * If the peerid is not -1, forward the response back to the 386 * the control socket. If it is -1, the request originated 387 * from the parent, not the control socket. 388 */ 389 if (vm->vm_peerid != (uint32_t)-1) { 390 (void)strlcpy(vmr.vmr_ttyname, vm->vm_ttyname, 391 sizeof(vmr.vmr_ttyname)); 392 if (proc_compose_imsg(ps, PROC_CONTROL, -1, 393 imsg->hdr.type, vm->vm_peerid, -1, 394 &vmr, sizeof(vmr)) == -1) { 395 errno = vmr.vmr_result; 396 log_warn("%s: failed to forward vm result", 397 vcp->vcp_name); 398 vm_remove(vm, __func__); 399 return (-1); 400 } 401 } 402 403 if (vmr.vmr_result) { 404 log_warnx("%s: failed to start vm", vcp->vcp_name); 405 vm_remove(vm, __func__); 406 errno = vmr.vmr_result; 407 break; 408 } 409 410 /* Now configure all the interfaces */ 411 if (vm_priv_ifconfig(ps, vm) == -1) { 412 log_warn("%s: failed to configure vm", vcp->vcp_name); 413 vm_remove(vm, __func__); 414 break; 415 } 416 417 log_info("%s: started vm %d successfully, tty %s", 418 vcp->vcp_name, vm->vm_vmid, vm->vm_ttyname); 419 break; 420 case IMSG_VMDOP_TERMINATE_VM_RESPONSE: 421 IMSG_SIZE_CHECK(imsg, &vmr); 422 memcpy(&vmr, imsg->data, sizeof(vmr)); 423 424 if (vmr.vmr_result) { 425 DPRINTF("%s: forwarding TERMINATE VM for vm id %d", 426 __func__, vmr.vmr_id); 427 proc_forward_imsg(ps, imsg, PROC_CONTROL, -1); 428 } else { 429 if ((vm = vm_getbyvmid(vmr.vmr_id)) == NULL) 430 break; 431 /* Mark VM as shutting down */ 432 vm->vm_state |= VM_STATE_SHUTDOWN; 433 } 434 break; 435 case IMSG_VMDOP_SEND_VM_RESPONSE: 436 IMSG_SIZE_CHECK(imsg, &vmr); 437 memcpy(&vmr, imsg->data, sizeof(vmr)); 438 if ((vm = vm_getbyvmid(vmr.vmr_id)) == NULL) 439 break; 440 if (!vmr.vmr_result) { 441 log_info("%s: sent vm %d successfully.", 442 vm->vm_params.vmc_params.vcp_name, 443 vm->vm_vmid); 444 if (vm->vm_from_config) 445 vm_stop(vm, 0, __func__); 446 else 447 vm_remove(vm, __func__); 448 } 449 450 /* Send a response if a control client is waiting for it */ 451 if (imsg->hdr.peerid != (uint32_t)-1) { 452 /* the error is meaningless for deferred responses */ 453 vmr.vmr_result = 0; 454 455 if (proc_compose_imsg(ps, PROC_CONTROL, -1, 456 IMSG_VMDOP_SEND_VM_RESPONSE, 457 imsg->hdr.peerid, -1, &vmr, sizeof(vmr)) == -1) 458 return (-1); 459 } 460 break; 461 case IMSG_VMDOP_TERMINATE_VM_EVENT: 462 IMSG_SIZE_CHECK(imsg, &vmr); 463 memcpy(&vmr, imsg->data, sizeof(vmr)); 464 DPRINTF("%s: handling TERMINATE_EVENT for vm id %d ret %d", 465 __func__, vmr.vmr_id, vmr.vmr_result); 466 if ((vm = vm_getbyvmid(vmr.vmr_id)) == NULL) { 467 log_debug("%s: vm %d is no longer available", 468 __func__, vmr.vmr_id); 469 break; 470 } 471 if (vmr.vmr_result != EAGAIN || 472 vm->vm_params.vmc_bootdevice) { 473 if (vm->vm_from_config) 474 vm_stop(vm, 0, __func__); 475 else 476 vm_remove(vm, __func__); 477 } else { 478 /* Stop VM instance but keep the tty open */ 479 vm_stop(vm, 1, __func__); 480 config_setvm(ps, vm, (uint32_t)-1, vm->vm_uid); 481 } 482 483 /* The error is meaningless for deferred responses */ 484 vmr.vmr_result = 0; 485 486 if (proc_compose_imsg(ps, PROC_CONTROL, -1, 487 IMSG_VMDOP_TERMINATE_VM_EVENT, 488 imsg->hdr.peerid, -1, &vmr, sizeof(vmr)) == -1) 489 return (-1); 490 break; 491 case IMSG_VMDOP_GET_INFO_VM_DATA: 492 IMSG_SIZE_CHECK(imsg, &vir); 493 memcpy(&vir, imsg->data, sizeof(vir)); 494 if ((vm = vm_getbyvmid(vir.vir_info.vir_id)) != NULL) { 495 memset(vir.vir_ttyname, 0, sizeof(vir.vir_ttyname)); 496 if (vm->vm_ttyname != NULL) 497 strlcpy(vir.vir_ttyname, vm->vm_ttyname, 498 sizeof(vir.vir_ttyname)); 499 log_debug("%s: running vm: %d, vm_state: 0x%x", 500 __func__, vm->vm_vmid, vm->vm_state); 501 vir.vir_state = vm->vm_state; 502 /* get the user id who started the vm */ 503 vir.vir_uid = vm->vm_uid; 504 vir.vir_gid = vm->vm_params.vmc_owner.gid; 505 } 506 if (proc_compose_imsg(ps, 507 imsg->hdr.peerid == IMSG_AGENTX_PEERID ? 508 PROC_AGENTX : PROC_CONTROL, -1, imsg->hdr.type, 509 imsg->hdr.peerid, -1, &vir, sizeof(vir)) == -1) { 510 log_debug("%s: GET_INFO_VM failed for vm %d, removing", 511 __func__, vm->vm_vmid); 512 vm_remove(vm, __func__); 513 return (-1); 514 } 515 break; 516 case IMSG_VMDOP_GET_INFO_VM_END_DATA: 517 /* 518 * PROC_VMM has responded with the *running* VMs, now we 519 * append the others. These use the special value 0 for their 520 * kernel id to indicate that they are not running. 521 */ 522 TAILQ_FOREACH(vm, env->vmd_vms, vm_entry) { 523 if (!(vm->vm_state & VM_STATE_RUNNING)) { 524 memset(&vir, 0, sizeof(vir)); 525 vir.vir_info.vir_id = vm->vm_vmid; 526 strlcpy(vir.vir_info.vir_name, 527 vm->vm_params.vmc_params.vcp_name, 528 VMM_MAX_NAME_LEN); 529 vir.vir_info.vir_memory_size = 530 vm->vm_params.vmc_params. 531 vcp_memranges[0].vmr_size; 532 vir.vir_info.vir_ncpus = 533 vm->vm_params.vmc_params.vcp_ncpus; 534 /* get the configured user id for this vm */ 535 vir.vir_uid = vm->vm_params.vmc_owner.uid; 536 vir.vir_gid = vm->vm_params.vmc_owner.gid; 537 log_debug("%s: vm: %d, vm_state: 0x%x", 538 __func__, vm->vm_vmid, vm->vm_state); 539 vir.vir_state = vm->vm_state; 540 if (proc_compose_imsg(ps, 541 imsg->hdr.peerid == IMSG_AGENTX_PEERID ? 542 PROC_AGENTX : PROC_CONTROL, -1, 543 IMSG_VMDOP_GET_INFO_VM_DATA, 544 imsg->hdr.peerid, -1, &vir, 545 sizeof(vir)) == -1) { 546 log_debug("%s: GET_INFO_VM_END failed", 547 __func__); 548 vm_remove(vm, __func__); 549 return (-1); 550 } 551 } 552 } 553 IMSG_SIZE_CHECK(imsg, &res); 554 proc_forward_imsg(ps, imsg, 555 imsg->hdr.peerid == IMSG_AGENTX_PEERID ? 556 PROC_AGENTX : PROC_CONTROL, -1); 557 break; 558 default: 559 return (-1); 560 } 561 562 return (0); 563 } 564 565 int 566 vmd_dispatch_agentx(int fd, struct privsep_proc *p, struct imsg *imsg) 567 { 568 struct privsep *ps = p->p_ps; 569 570 switch (imsg->hdr.type) { 571 case IMSG_VMDOP_GET_INFO_VM_REQUEST: 572 proc_forward_imsg(ps, imsg, PROC_VMM, -1); 573 return (0); 574 default: 575 break; 576 } 577 return (-1); 578 } 579 580 int 581 vmd_dispatch_priv(int fd, struct privsep_proc *p, struct imsg *imsg) 582 { 583 struct vmop_addr_result var; 584 585 switch (imsg->hdr.type) { 586 case IMSG_VMDOP_PRIV_GET_ADDR_RESPONSE: 587 IMSG_SIZE_CHECK(imsg, &var); 588 memcpy(&var, imsg->data, sizeof(var)); 589 proc_forward_imsg(p->p_ps, imsg, PROC_VMM, -1); 590 break; 591 default: 592 return (-1); 593 } 594 595 return (0); 596 } 597 598 int 599 vmd_check_vmh(struct vm_dump_header *vmh) 600 { 601 int i; 602 unsigned int code, leaf; 603 unsigned int a, b, c, d; 604 605 if (strncmp(vmh->vmh_signature, VM_DUMP_SIGNATURE, strlen(VM_DUMP_SIGNATURE)) != 0) { 606 log_warnx("%s: incompatible dump signature", __func__); 607 return (-1); 608 } 609 610 if (vmh->vmh_version != VM_DUMP_VERSION) { 611 log_warnx("%s: incompatible dump version", __func__); 612 return (-1); 613 } 614 615 for (i = 0; i < VM_DUMP_HEADER_CPUID_COUNT; i++) { 616 code = vmh->vmh_cpuids[i].code; 617 leaf = vmh->vmh_cpuids[i].leaf; 618 if (leaf != 0x00) { 619 log_debug("%s: invalid leaf 0x%x for code 0x%x", 620 __func__, leaf, code); 621 return (-1); 622 } 623 624 switch (code) { 625 case 0x00: 626 CPUID_LEAF(code, leaf, a, b, c, d); 627 if (vmh->vmh_cpuids[i].a > a) { 628 log_debug("%s: incompatible cpuid level", 629 __func__); 630 return (-1); 631 } 632 if (!(vmh->vmh_cpuids[i].b == b && 633 vmh->vmh_cpuids[i].c == c && 634 vmh->vmh_cpuids[i].d == d)) { 635 log_debug("%s: incompatible cpu brand", 636 __func__); 637 return (-1); 638 } 639 break; 640 641 case 0x01: 642 CPUID_LEAF(code, leaf, a, b, c, d); 643 if ((vmh->vmh_cpuids[i].c & c & VMM_CPUIDECX_MASK) != 644 (vmh->vmh_cpuids[i].c & VMM_CPUIDECX_MASK)) { 645 log_debug("%s: incompatible cpu features " 646 "code: 0x%x leaf: 0x%x reg: c", __func__, 647 code, leaf); 648 return (-1); 649 } 650 if ((vmh->vmh_cpuids[i].d & d & VMM_CPUIDEDX_MASK) != 651 (vmh->vmh_cpuids[i].d & VMM_CPUIDEDX_MASK)) { 652 log_debug("%s: incompatible cpu features " 653 "code: 0x%x leaf: 0x%x reg: d", __func__, 654 code, leaf); 655 return (-1); 656 } 657 break; 658 659 case 0x07: 660 CPUID_LEAF(code, leaf, a, b, c, d); 661 if ((vmh->vmh_cpuids[i].b & b & VMM_SEFF0EBX_MASK) != 662 (vmh->vmh_cpuids[i].b & VMM_SEFF0EBX_MASK)) { 663 log_debug("%s: incompatible cpu features " 664 "code: 0x%x leaf: 0x%x reg: c", __func__, 665 code, leaf); 666 return (-1); 667 } 668 if ((vmh->vmh_cpuids[i].c & c & VMM_SEFF0ECX_MASK) != 669 (vmh->vmh_cpuids[i].c & VMM_SEFF0ECX_MASK)) { 670 log_debug("%s: incompatible cpu features " 671 "code: 0x%x leaf: 0x%x reg: d", __func__, 672 code, leaf); 673 return (-1); 674 } 675 break; 676 677 case 0x0d: 678 CPUID_LEAF(code, leaf, a, b, c, d); 679 if (vmh->vmh_cpuids[i].b > b) { 680 log_debug("%s: incompatible cpu: insufficient " 681 "max save area for enabled XCR0 features", 682 __func__); 683 return (-1); 684 } 685 if (vmh->vmh_cpuids[i].c > c) { 686 log_debug("%s: incompatible cpu: insufficient " 687 "max save area for supported XCR0 features", 688 __func__); 689 return (-1); 690 } 691 break; 692 693 case 0x80000001: 694 CPUID_LEAF(code, leaf, a, b, c, d); 695 if ((vmh->vmh_cpuids[i].a & a) != 696 vmh->vmh_cpuids[i].a) { 697 log_debug("%s: incompatible cpu features " 698 "code: 0x%x leaf: 0x%x reg: a", __func__, 699 code, leaf); 700 return (-1); 701 } 702 if ((vmh->vmh_cpuids[i].c & c) != 703 vmh->vmh_cpuids[i].c) { 704 log_debug("%s: incompatible cpu features " 705 "code: 0x%x leaf: 0x%x reg: c", __func__, 706 code, leaf); 707 return (-1); 708 } 709 if ((vmh->vmh_cpuids[i].d & d) != 710 vmh->vmh_cpuids[i].d) { 711 log_debug("%s: incompatible cpu features " 712 "code: 0x%x leaf: 0x%x reg: d", __func__, 713 code, leaf); 714 return (-1); 715 } 716 break; 717 718 default: 719 log_debug("%s: unknown code 0x%x", __func__, code); 720 return (-1); 721 } 722 } 723 724 return (0); 725 } 726 727 void 728 vmd_sighdlr(int sig, short event, void *arg) 729 { 730 if (privsep_process != PROC_PARENT) 731 return; 732 log_debug("%s: handling signal", __func__); 733 734 switch (sig) { 735 case SIGHUP: 736 log_info("%s: reload requested with SIGHUP", __func__); 737 738 /* 739 * This is safe because libevent uses async signal handlers 740 * that run in the event loop and not in signal context. 741 */ 742 (void)vmd_reload(0, NULL); 743 break; 744 case SIGPIPE: 745 log_info("%s: ignoring SIGPIPE", __func__); 746 break; 747 case SIGUSR1: 748 log_info("%s: ignoring SIGUSR1", __func__); 749 break; 750 case SIGTERM: 751 case SIGINT: 752 vmd_shutdown(); 753 break; 754 default: 755 fatalx("unexpected signal"); 756 } 757 } 758 759 __dead void 760 usage(void) 761 { 762 extern char *__progname; 763 fprintf(stderr, "usage: %s [-dnv] [-D macro=value] [-f file]\n", 764 __progname); 765 exit(1); 766 } 767 768 int 769 main(int argc, char **argv) 770 { 771 struct privsep *ps; 772 int ch; 773 const char *conffile = VMD_CONF; 774 enum privsep_procid proc_id = PROC_PARENT; 775 int proc_instance = 0; 776 const char *errp, *title = NULL; 777 int argc0 = argc; 778 779 log_init(0, LOG_DAEMON); 780 781 if ((env = calloc(1, sizeof(*env))) == NULL) 782 fatal("calloc: env"); 783 784 while ((ch = getopt(argc, argv, "D:P:I:df:vn")) != -1) { 785 switch (ch) { 786 case 'D': 787 if (cmdline_symset(optarg) < 0) 788 log_warnx("could not parse macro definition %s", 789 optarg); 790 break; 791 case 'd': 792 env->vmd_debug = 2; 793 break; 794 case 'f': 795 conffile = optarg; 796 break; 797 case 'v': 798 env->vmd_verbose++; 799 break; 800 case 'n': 801 env->vmd_noaction = 1; 802 break; 803 case 'P': 804 title = optarg; 805 proc_id = proc_getid(procs, nitems(procs), title); 806 if (proc_id == PROC_MAX) 807 fatalx("invalid process name"); 808 break; 809 case 'I': 810 proc_instance = strtonum(optarg, 0, 811 PROC_MAX_INSTANCES, &errp); 812 if (errp) 813 fatalx("invalid process instance"); 814 break; 815 default: 816 usage(); 817 } 818 } 819 820 argc -= optind; 821 if (argc > 0) 822 usage(); 823 824 if (env->vmd_noaction && !env->vmd_debug) 825 env->vmd_debug = 1; 826 827 log_init(env->vmd_debug, LOG_DAEMON); 828 log_setverbose(env->vmd_verbose); 829 830 /* check for root privileges */ 831 if (env->vmd_noaction == 0) { 832 if (geteuid()) 833 fatalx("need root privileges"); 834 } 835 836 ps = &env->vmd_ps; 837 ps->ps_env = env; 838 env->vmd_fd = -1; 839 840 if (config_init(env) == -1) 841 fatal("failed to initialize configuration"); 842 843 if ((ps->ps_pw = getpwnam(VMD_USER)) == NULL) 844 fatal("unknown user %s", VMD_USER); 845 846 /* First proc runs as root without pledge but in default chroot */ 847 proc_priv->p_pw = &proc_privpw; /* initialized to all 0 */ 848 proc_priv->p_chroot = ps->ps_pw->pw_dir; /* from VMD_USER */ 849 850 /* Open /dev/vmm */ 851 if (env->vmd_noaction == 0) { 852 env->vmd_fd = open(VMM_NODE, O_RDWR); 853 if (env->vmd_fd == -1) 854 fatal("%s", VMM_NODE); 855 } 856 857 /* Configure the control socket */ 858 ps->ps_csock.cs_name = SOCKET_NAME; 859 TAILQ_INIT(&ps->ps_rcsocks); 860 861 /* Configuration will be parsed after forking the children */ 862 env->vmd_conffile = conffile; 863 864 if (env->vmd_noaction) 865 ps->ps_noaction = 1; 866 ps->ps_instance = proc_instance; 867 if (title != NULL) 868 ps->ps_title[proc_id] = title; 869 870 /* only the parent returns */ 871 proc_init(ps, procs, nitems(procs), env->vmd_debug, argc0, argv, 872 proc_id); 873 874 log_procinit("parent"); 875 if (!env->vmd_debug && daemon(0, 0) == -1) 876 fatal("can't daemonize"); 877 878 if (ps->ps_noaction == 0) 879 log_info("startup"); 880 881 event_init(); 882 883 signal_set(&ps->ps_evsigint, SIGINT, vmd_sighdlr, ps); 884 signal_set(&ps->ps_evsigterm, SIGTERM, vmd_sighdlr, ps); 885 signal_set(&ps->ps_evsighup, SIGHUP, vmd_sighdlr, ps); 886 signal_set(&ps->ps_evsigpipe, SIGPIPE, vmd_sighdlr, ps); 887 signal_set(&ps->ps_evsigusr1, SIGUSR1, vmd_sighdlr, ps); 888 889 signal_add(&ps->ps_evsigint, NULL); 890 signal_add(&ps->ps_evsigterm, NULL); 891 signal_add(&ps->ps_evsighup, NULL); 892 signal_add(&ps->ps_evsigpipe, NULL); 893 signal_add(&ps->ps_evsigusr1, NULL); 894 895 if (!env->vmd_noaction) 896 proc_connect(ps); 897 898 if (vmd_configure() == -1) 899 fatalx("configuration failed"); 900 901 event_dispatch(); 902 903 log_debug("parent exiting"); 904 905 return (0); 906 } 907 908 void 909 start_vm_batch(int fd, short type, void *args) 910 { 911 int i = 0; 912 struct vmd_vm *vm; 913 914 log_debug("%s: starting batch of %d vms", __func__, 915 env->vmd_cfg.parallelism); 916 TAILQ_FOREACH(vm, env->vmd_vms, vm_entry) { 917 if (!(vm->vm_state & VM_STATE_WAITING)) { 918 log_debug("%s: not starting vm %s (disabled)", 919 __func__, 920 vm->vm_params.vmc_params.vcp_name); 921 continue; 922 } 923 i++; 924 if (i > env->vmd_cfg.parallelism) { 925 evtimer_add(&staggered_start_timer, 926 &env->vmd_cfg.delay); 927 break; 928 } 929 vm->vm_state &= ~VM_STATE_WAITING; 930 config_setvm(&env->vmd_ps, vm, -1, vm->vm_params.vmc_owner.uid); 931 } 932 log_debug("%s: done starting vms", __func__); 933 } 934 935 int 936 vmd_configure(void) 937 { 938 int ncpus; 939 struct vmd_switch *vsw; 940 int ncpu_mib[] = {CTL_HW, HW_NCPUONLINE}; 941 size_t ncpus_sz = sizeof(ncpus); 942 943 if ((env->vmd_ptmfd = open(PATH_PTMDEV, O_RDWR|O_CLOEXEC)) == -1) 944 fatal("open %s", PATH_PTMDEV); 945 946 /* 947 * pledge in the parent process: 948 * stdio - for malloc and basic I/O including events. 949 * rpath - for reload to open and read the configuration files. 950 * wpath - for opening disk images and tap devices. 951 * tty - for openpty and TIOCUCNTL. 952 * proc - run kill to terminate its children safely. 953 * sendfd - for disks, interfaces and other fds. 954 * recvfd - for send and receive. 955 * getpw - lookup user or group id by name. 956 * chown, fattr - change tty ownership 957 * flock - locking disk files 958 */ 959 if (pledge("stdio rpath wpath proc tty recvfd sendfd getpw" 960 " chown fattr flock", NULL) == -1) 961 fatal("pledge"); 962 963 if (parse_config(env->vmd_conffile) == -1) { 964 proc_kill(&env->vmd_ps); 965 exit(1); 966 } 967 968 if (env->vmd_noaction) { 969 fprintf(stderr, "configuration OK\n"); 970 proc_kill(&env->vmd_ps); 971 exit(0); 972 } 973 974 /* Send shared global configuration to all children */ 975 if (config_setconfig(env) == -1) 976 return (-1); 977 978 TAILQ_FOREACH(vsw, env->vmd_switches, sw_entry) { 979 if (vsw->sw_running) 980 continue; 981 if (vm_priv_brconfig(&env->vmd_ps, vsw) == -1) { 982 log_warn("%s: failed to create switch %s", 983 __func__, vsw->sw_name); 984 switch_remove(vsw); 985 return (-1); 986 } 987 } 988 989 if (!(env->vmd_cfg.cfg_flags & VMD_CFG_STAGGERED_START)) { 990 env->vmd_cfg.delay.tv_sec = VMD_DEFAULT_STAGGERED_START_DELAY; 991 if (sysctl(ncpu_mib, nitems(ncpu_mib), &ncpus, &ncpus_sz, NULL, 0) == -1) 992 ncpus = 1; 993 env->vmd_cfg.parallelism = ncpus; 994 log_debug("%s: setting staggered start configuration to " 995 "parallelism: %d and delay: %lld", 996 __func__, ncpus, (long long) env->vmd_cfg.delay.tv_sec); 997 } 998 999 log_debug("%s: starting vms in staggered fashion", __func__); 1000 evtimer_set(&staggered_start_timer, start_vm_batch, NULL); 1001 /* start first batch */ 1002 start_vm_batch(0, 0, NULL); 1003 1004 return (0); 1005 } 1006 1007 int 1008 vmd_reload(unsigned int reset, const char *filename) 1009 { 1010 struct vmd_vm *vm, *next_vm; 1011 struct vmd_switch *vsw; 1012 int reload = 0; 1013 1014 /* Switch back to the default config file */ 1015 if (filename == NULL || *filename == '\0') { 1016 filename = env->vmd_conffile; 1017 reload = 1; 1018 } 1019 1020 log_debug("%s: level %d config file %s", __func__, reset, filename); 1021 1022 if (reset) { 1023 /* Purge the configuration */ 1024 config_purge(env, reset); 1025 config_setreset(env, reset); 1026 } else { 1027 /* 1028 * Load or reload the configuration. 1029 * 1030 * Reloading removes all non-running VMs before processing the 1031 * config file, whereas loading only adds to the existing list 1032 * of VMs. 1033 */ 1034 1035 if (reload) { 1036 TAILQ_FOREACH_SAFE(vm, env->vmd_vms, vm_entry, 1037 next_vm) { 1038 if (!(vm->vm_state & VM_STATE_RUNNING)) { 1039 DPRINTF("%s: calling vm_remove", 1040 __func__); 1041 vm_remove(vm, __func__); 1042 } 1043 } 1044 } 1045 1046 if (parse_config(filename) == -1) { 1047 log_debug("%s: failed to load config file %s", 1048 __func__, filename); 1049 return (-1); 1050 } 1051 1052 if (reload) { 1053 /* Update shared global configuration in all children */ 1054 if (config_setconfig(env) == -1) 1055 return (-1); 1056 } 1057 1058 TAILQ_FOREACH(vsw, env->vmd_switches, sw_entry) { 1059 if (vsw->sw_running) 1060 continue; 1061 if (vm_priv_brconfig(&env->vmd_ps, vsw) == -1) { 1062 log_warn("%s: failed to create switch %s", 1063 __func__, vsw->sw_name); 1064 switch_remove(vsw); 1065 return (-1); 1066 } 1067 } 1068 1069 log_debug("%s: starting vms in staggered fashion", __func__); 1070 evtimer_set(&staggered_start_timer, start_vm_batch, NULL); 1071 /* start first batch */ 1072 start_vm_batch(0, 0, NULL); 1073 1074 } 1075 1076 return (0); 1077 } 1078 1079 void 1080 vmd_shutdown(void) 1081 { 1082 struct vmd_vm *vm, *vm_next; 1083 1084 log_debug("%s: performing shutdown", __func__); 1085 1086 TAILQ_FOREACH_SAFE(vm, env->vmd_vms, vm_entry, vm_next) { 1087 vm_remove(vm, __func__); 1088 } 1089 1090 proc_kill(&env->vmd_ps); 1091 free(env); 1092 1093 log_warnx("parent terminating"); 1094 exit(0); 1095 } 1096 1097 struct vmd_vm * 1098 vm_getbyvmid(uint32_t vmid) 1099 { 1100 struct vmd_vm *vm; 1101 1102 if (vmid == 0) 1103 return (NULL); 1104 TAILQ_FOREACH(vm, env->vmd_vms, vm_entry) { 1105 if (vm->vm_vmid == vmid) 1106 return (vm); 1107 } 1108 1109 return (NULL); 1110 } 1111 1112 struct vmd_vm * 1113 vm_getbyid(uint32_t id) 1114 { 1115 struct vmd_vm *vm; 1116 1117 if (id == 0) 1118 return (NULL); 1119 TAILQ_FOREACH(vm, env->vmd_vms, vm_entry) { 1120 if (vm->vm_params.vmc_params.vcp_id == id) 1121 return (vm); 1122 } 1123 1124 return (NULL); 1125 } 1126 1127 uint32_t 1128 vm_id2vmid(uint32_t id, struct vmd_vm *vm) 1129 { 1130 if (vm == NULL && (vm = vm_getbyid(id)) == NULL) 1131 return (0); 1132 DPRINTF("%s: vmm id %u is vmid %u", __func__, 1133 id, vm->vm_vmid); 1134 return (vm->vm_vmid); 1135 } 1136 1137 uint32_t 1138 vm_vmid2id(uint32_t vmid, struct vmd_vm *vm) 1139 { 1140 if (vm == NULL && (vm = vm_getbyvmid(vmid)) == NULL) 1141 return (0); 1142 DPRINTF("%s: vmid %u is vmm id %u", __func__, 1143 vmid, vm->vm_params.vmc_params.vcp_id); 1144 return (vm->vm_params.vmc_params.vcp_id); 1145 } 1146 1147 struct vmd_vm * 1148 vm_getbyname(const char *name) 1149 { 1150 struct vmd_vm *vm; 1151 1152 if (name == NULL) 1153 return (NULL); 1154 TAILQ_FOREACH(vm, env->vmd_vms, vm_entry) { 1155 if (strcmp(vm->vm_params.vmc_params.vcp_name, name) == 0) 1156 return (vm); 1157 } 1158 1159 return (NULL); 1160 } 1161 1162 struct vmd_vm * 1163 vm_getbypid(pid_t pid) 1164 { 1165 struct vmd_vm *vm; 1166 1167 TAILQ_FOREACH(vm, env->vmd_vms, vm_entry) { 1168 if (vm->vm_pid == pid) 1169 return (vm); 1170 } 1171 1172 return (NULL); 1173 } 1174 1175 void 1176 vm_stop(struct vmd_vm *vm, int keeptty, const char *caller) 1177 { 1178 struct privsep *ps = &env->vmd_ps; 1179 unsigned int i, j; 1180 1181 if (vm == NULL) 1182 return; 1183 1184 log_debug("%s: %s %s stopping vm %d%s", 1185 __func__, ps->ps_title[privsep_process], caller, 1186 vm->vm_vmid, keeptty ? ", keeping tty open" : ""); 1187 1188 vm->vm_state &= ~(VM_STATE_RECEIVED | VM_STATE_RUNNING 1189 | VM_STATE_SHUTDOWN); 1190 1191 if (vm->vm_iev.ibuf.fd != -1) { 1192 event_del(&vm->vm_iev.ev); 1193 close(vm->vm_iev.ibuf.fd); 1194 } 1195 for (i = 0; i < VMM_MAX_DISKS_PER_VM; i++) { 1196 for (j = 0; j < VM_MAX_BASE_PER_DISK; j++) { 1197 if (vm->vm_disks[i][j] != -1) { 1198 close(vm->vm_disks[i][j]); 1199 vm->vm_disks[i][j] = -1; 1200 } 1201 } 1202 } 1203 for (i = 0; i < VMM_MAX_NICS_PER_VM; i++) { 1204 if (vm->vm_ifs[i].vif_fd != -1) { 1205 close(vm->vm_ifs[i].vif_fd); 1206 vm->vm_ifs[i].vif_fd = -1; 1207 } 1208 free(vm->vm_ifs[i].vif_name); 1209 free(vm->vm_ifs[i].vif_switch); 1210 free(vm->vm_ifs[i].vif_group); 1211 vm->vm_ifs[i].vif_name = NULL; 1212 vm->vm_ifs[i].vif_switch = NULL; 1213 vm->vm_ifs[i].vif_group = NULL; 1214 } 1215 if (vm->vm_kernel != -1) { 1216 close(vm->vm_kernel); 1217 vm->vm_kernel = -1; 1218 } 1219 if (vm->vm_cdrom != -1) { 1220 close(vm->vm_cdrom); 1221 vm->vm_cdrom = -1; 1222 } 1223 if (!keeptty) { 1224 vm_closetty(vm); 1225 vm->vm_uid = 0; 1226 } 1227 } 1228 1229 void 1230 vm_remove(struct vmd_vm *vm, const char *caller) 1231 { 1232 struct privsep *ps = &env->vmd_ps; 1233 1234 if (vm == NULL) 1235 return; 1236 1237 log_debug("%s: %s %s removing vm %d from running config", 1238 __func__, ps->ps_title[privsep_process], caller, 1239 vm->vm_vmid); 1240 1241 TAILQ_REMOVE(env->vmd_vms, vm, vm_entry); 1242 1243 vm_stop(vm, 0, caller); 1244 free(vm); 1245 } 1246 1247 int 1248 vm_claimid(const char *name, int uid, uint32_t *id) 1249 { 1250 struct name2id *n2i = NULL; 1251 1252 TAILQ_FOREACH(n2i, env->vmd_known, entry) 1253 if (strcmp(n2i->name, name) == 0 && n2i->uid == uid) 1254 goto out; 1255 1256 if (++env->vmd_nvm == 0) { 1257 log_warnx("too many vms"); 1258 return (-1); 1259 } 1260 if ((n2i = calloc(1, sizeof(struct name2id))) == NULL) { 1261 log_warnx("could not alloc vm name"); 1262 return (-1); 1263 } 1264 n2i->id = env->vmd_nvm; 1265 n2i->uid = uid; 1266 if (strlcpy(n2i->name, name, sizeof(n2i->name)) >= sizeof(n2i->name)) { 1267 log_warnx("vm name too long"); 1268 free(n2i); 1269 return (-1); 1270 } 1271 TAILQ_INSERT_TAIL(env->vmd_known, n2i, entry); 1272 1273 out: 1274 *id = n2i->id; 1275 return (0); 1276 } 1277 1278 int 1279 vm_register(struct privsep *ps, struct vmop_create_params *vmc, 1280 struct vmd_vm **ret_vm, uint32_t id, uid_t uid) 1281 { 1282 struct vmd_vm *vm = NULL, *vm_parent = NULL; 1283 struct vm_create_params *vcp = &vmc->vmc_params; 1284 struct vmop_owner *vmo = NULL; 1285 uint32_t nid, rng; 1286 unsigned int i, j; 1287 struct vmd_switch *sw; 1288 char *s; 1289 int ret = 0; 1290 1291 /* Check if this is an instance of another VM */ 1292 if ((ret = vm_instance(ps, &vm_parent, vmc, uid)) != 0) { 1293 errno = ret; /* XXX might set invalid errno */ 1294 return (-1); 1295 } 1296 1297 errno = 0; 1298 *ret_vm = NULL; 1299 1300 if ((vm = vm_getbyname(vcp->vcp_name)) != NULL || 1301 (vm = vm_getbyvmid(vcp->vcp_id)) != NULL) { 1302 if (vm_checkperm(vm, &vm->vm_params.vmc_owner, 1303 uid) != 0) { 1304 errno = EPERM; 1305 goto fail; 1306 } 1307 *ret_vm = vm; 1308 errno = EALREADY; 1309 goto fail; 1310 } 1311 1312 if (vm_parent != NULL) 1313 vmo = &vm_parent->vm_params.vmc_insowner; 1314 1315 /* non-root users can only start existing VMs or instances */ 1316 if (vm_checkperm(NULL, vmo, uid) != 0) { 1317 log_warnx("permission denied"); 1318 errno = EPERM; 1319 goto fail; 1320 } 1321 if (vmc->vmc_flags == 0) { 1322 log_warnx("invalid configuration, no devices"); 1323 errno = VMD_DISK_MISSING; 1324 goto fail; 1325 } 1326 if (vcp->vcp_ncpus == 0) 1327 vcp->vcp_ncpus = 1; 1328 if (vcp->vcp_memranges[0].vmr_size == 0) 1329 vcp->vcp_memranges[0].vmr_size = VM_DEFAULT_MEMORY; 1330 if (vcp->vcp_ncpus > VMM_MAX_VCPUS_PER_VM) { 1331 log_warnx("invalid number of CPUs"); 1332 goto fail; 1333 } else if (vcp->vcp_ndisks > VMM_MAX_DISKS_PER_VM) { 1334 log_warnx("invalid number of disks"); 1335 goto fail; 1336 } else if (vcp->vcp_nnics > VMM_MAX_NICS_PER_VM) { 1337 log_warnx("invalid number of interfaces"); 1338 goto fail; 1339 } else if (strlen(vcp->vcp_kernel) == 0 && 1340 vcp->vcp_ndisks == 0 && strlen(vcp->vcp_cdrom) == 0) { 1341 log_warnx("no kernel or disk/cdrom specified"); 1342 goto fail; 1343 } else if (strlen(vcp->vcp_name) == 0) { 1344 log_warnx("invalid VM name"); 1345 goto fail; 1346 } else if (*vcp->vcp_name == '-' || *vcp->vcp_name == '.' || 1347 *vcp->vcp_name == '_') { 1348 log_warnx("invalid VM name"); 1349 goto fail; 1350 } else { 1351 for (s = vcp->vcp_name; *s != '\0'; ++s) { 1352 if (!(isalnum((unsigned char)*s) || *s == '.' || \ 1353 *s == '-' || *s == '_')) { 1354 log_warnx("invalid VM name"); 1355 goto fail; 1356 } 1357 } 1358 } 1359 1360 if ((vm = calloc(1, sizeof(*vm))) == NULL) 1361 goto fail; 1362 1363 memcpy(&vm->vm_params, vmc, sizeof(vm->vm_params)); 1364 vmc = &vm->vm_params; 1365 vcp = &vmc->vmc_params; 1366 vm->vm_pid = -1; 1367 vm->vm_tty = -1; 1368 vm->vm_receive_fd = -1; 1369 vm->vm_state &= ~VM_STATE_PAUSED; 1370 1371 for (i = 0; i < VMM_MAX_DISKS_PER_VM; i++) 1372 for (j = 0; j < VM_MAX_BASE_PER_DISK; j++) 1373 vm->vm_disks[i][j] = -1; 1374 for (i = 0; i < VMM_MAX_NICS_PER_VM; i++) 1375 vm->vm_ifs[i].vif_fd = -1; 1376 for (i = 0; i < vcp->vcp_nnics; i++) { 1377 if ((sw = switch_getbyname(vmc->vmc_ifswitch[i])) != NULL) { 1378 /* inherit per-interface flags from the switch */ 1379 vmc->vmc_ifflags[i] |= (sw->sw_flags & VMIFF_OPTMASK); 1380 } 1381 1382 /* 1383 * If the MAC address is zero, always randomize it in vmd(8) 1384 * because we cannot rely on the guest OS to do the right 1385 * thing like OpenBSD does. Based on ether_fakeaddr() 1386 * from the kernel, incremented by one to differentiate 1387 * the source. 1388 */ 1389 if (memcmp(zero_mac, &vcp->vcp_macs[i], ETHER_ADDR_LEN) == 0) { 1390 rng = arc4random(); 1391 vcp->vcp_macs[i][0] = 0xfe; 1392 vcp->vcp_macs[i][1] = 0xe1; 1393 vcp->vcp_macs[i][2] = 0xba + 1; 1394 vcp->vcp_macs[i][3] = 0xd0 | ((i + 1) & 0xf); 1395 vcp->vcp_macs[i][4] = rng; 1396 vcp->vcp_macs[i][5] = rng >> 8; 1397 } 1398 } 1399 vm->vm_kernel = -1; 1400 vm->vm_cdrom = -1; 1401 vm->vm_iev.ibuf.fd = -1; 1402 1403 /* 1404 * Assign a new internal Id if not specified and we succeed in 1405 * claiming a new Id. 1406 */ 1407 if (id != 0) 1408 vm->vm_vmid = id; 1409 else if (vm_claimid(vcp->vcp_name, uid, &nid) == -1) 1410 goto fail; 1411 else 1412 vm->vm_vmid = nid; 1413 1414 log_debug("%s: registering vm %d", __func__, vm->vm_vmid); 1415 TAILQ_INSERT_TAIL(env->vmd_vms, vm, vm_entry); 1416 1417 *ret_vm = vm; 1418 return (0); 1419 fail: 1420 if (errno == 0) 1421 errno = EINVAL; 1422 return (-1); 1423 } 1424 1425 int 1426 vm_instance(struct privsep *ps, struct vmd_vm **vm_parent, 1427 struct vmop_create_params *vmc, uid_t uid) 1428 { 1429 char *name; 1430 struct vm_create_params *vcp = &vmc->vmc_params; 1431 struct vmop_create_params *vmcp; 1432 struct vm_create_params *vcpp; 1433 struct vmd_vm *vm = NULL; 1434 unsigned int i, j; 1435 1436 /* return without error if the parent is NULL (nothing to inherit) */ 1437 if ((vmc->vmc_flags & VMOP_CREATE_INSTANCE) == 0 || 1438 vmc->vmc_instance[0] == '\0') 1439 return (0); 1440 1441 if ((*vm_parent = vm_getbyname(vmc->vmc_instance)) == NULL) { 1442 return (VMD_PARENT_INVALID); 1443 } 1444 1445 vmcp = &(*vm_parent)->vm_params; 1446 vcpp = &vmcp->vmc_params; 1447 1448 /* Are we allowed to create an instance from this VM? */ 1449 if (vm_checkperm(NULL, &vmcp->vmc_insowner, uid) != 0) { 1450 log_warnx("vm \"%s\" no permission to create vm instance", 1451 vcpp->vcp_name); 1452 return (ENAMETOOLONG); 1453 } 1454 1455 name = vcp->vcp_name; 1456 1457 if ((vm = vm_getbyname(vcp->vcp_name)) != NULL || 1458 (vm = vm_getbyvmid(vcp->vcp_id)) != NULL) { 1459 return (EPROCLIM); 1460 } 1461 1462 /* CPU */ 1463 if (vcp->vcp_ncpus == 0) 1464 vcp->vcp_ncpus = vcpp->vcp_ncpus; 1465 if (vm_checkinsflag(vmcp, VMOP_CREATE_CPU, uid) != 0 && 1466 vcp->vcp_ncpus != vcpp->vcp_ncpus) { 1467 log_warnx("vm \"%s\" no permission to set cpus", name); 1468 return (EPERM); 1469 } 1470 1471 /* memory */ 1472 if (vcp->vcp_memranges[0].vmr_size == 0) 1473 vcp->vcp_memranges[0].vmr_size = 1474 vcpp->vcp_memranges[0].vmr_size; 1475 if (vm_checkinsflag(vmcp, VMOP_CREATE_MEMORY, uid) != 0 && 1476 vcp->vcp_memranges[0].vmr_size != 1477 vcpp->vcp_memranges[0].vmr_size) { 1478 log_warnx("vm \"%s\" no permission to set memory", name); 1479 return (EPERM); 1480 } 1481 1482 /* disks cannot be inherited */ 1483 if (vm_checkinsflag(vmcp, VMOP_CREATE_DISK, uid) != 0 && 1484 vcp->vcp_ndisks) { 1485 log_warnx("vm \"%s\" no permission to set disks", name); 1486 return (EPERM); 1487 } 1488 for (i = 0; i < vcp->vcp_ndisks; i++) { 1489 /* Check if this disk is already used in the parent */ 1490 for (j = 0; j < vcpp->vcp_ndisks; j++) { 1491 if (strcmp(vcp->vcp_disks[i], 1492 vcpp->vcp_disks[j]) == 0) { 1493 log_warnx("vm \"%s\" disk %s cannot be reused", 1494 name, vcp->vcp_disks[i]); 1495 return (EBUSY); 1496 } 1497 } 1498 vmc->vmc_checkaccess |= VMOP_CREATE_DISK; 1499 } 1500 1501 /* interfaces */ 1502 if (vcp->vcp_nnics > 0 && 1503 vm_checkinsflag(vmcp, VMOP_CREATE_NETWORK, uid) != 0 && 1504 vcp->vcp_nnics != vcpp->vcp_nnics) { 1505 log_warnx("vm \"%s\" no permission to set interfaces", name); 1506 return (EPERM); 1507 } 1508 for (i = 0; i < vcpp->vcp_nnics; i++) { 1509 /* Interface got overwritten */ 1510 if (i < vcp->vcp_nnics) 1511 continue; 1512 1513 /* Copy interface from parent */ 1514 vmc->vmc_ifflags[i] = vmcp->vmc_ifflags[i]; 1515 (void)strlcpy(vmc->vmc_ifnames[i], vmcp->vmc_ifnames[i], 1516 sizeof(vmc->vmc_ifnames[i])); 1517 (void)strlcpy(vmc->vmc_ifswitch[i], vmcp->vmc_ifswitch[i], 1518 sizeof(vmc->vmc_ifswitch[i])); 1519 (void)strlcpy(vmc->vmc_ifgroup[i], vmcp->vmc_ifgroup[i], 1520 sizeof(vmc->vmc_ifgroup[i])); 1521 memcpy(vcp->vcp_macs[i], vcpp->vcp_macs[i], 1522 sizeof(vcp->vcp_macs[i])); 1523 vmc->vmc_ifrdomain[i] = vmcp->vmc_ifrdomain[i]; 1524 vcp->vcp_nnics++; 1525 } 1526 for (i = 0; i < vcp->vcp_nnics; i++) { 1527 for (j = 0; j < vcpp->vcp_nnics; j++) { 1528 if (memcmp(zero_mac, vcp->vcp_macs[i], 1529 sizeof(vcp->vcp_macs[i])) != 0 && 1530 memcmp(vcpp->vcp_macs[i], vcp->vcp_macs[i], 1531 sizeof(vcp->vcp_macs[i])) != 0) { 1532 log_warnx("vm \"%s\" lladdr cannot be reused", 1533 name); 1534 return (EBUSY); 1535 } 1536 if (strlen(vmc->vmc_ifnames[i]) && 1537 strcmp(vmc->vmc_ifnames[i], 1538 vmcp->vmc_ifnames[j]) == 0) { 1539 log_warnx("vm \"%s\" %s cannot be reused", 1540 vmc->vmc_ifnames[i], name); 1541 return (EBUSY); 1542 } 1543 } 1544 } 1545 1546 /* kernel */ 1547 if (strlen(vcp->vcp_kernel) > 0) { 1548 if (vm_checkinsflag(vmcp, VMOP_CREATE_KERNEL, uid) != 0) { 1549 log_warnx("vm \"%s\" no permission to set boot image", 1550 name); 1551 return (EPERM); 1552 } 1553 vmc->vmc_checkaccess |= VMOP_CREATE_KERNEL; 1554 } else if (strlcpy(vcp->vcp_kernel, vcpp->vcp_kernel, 1555 sizeof(vcp->vcp_kernel)) >= sizeof(vcp->vcp_kernel)) { 1556 log_warnx("vm \"%s\" kernel name too long", name); 1557 return (EINVAL); 1558 } 1559 1560 /* cdrom */ 1561 if (strlen(vcp->vcp_cdrom) > 0) { 1562 if (vm_checkinsflag(vmcp, VMOP_CREATE_CDROM, uid) != 0) { 1563 log_warnx("vm \"%s\" no permission to set cdrom", name); 1564 return (EPERM); 1565 } 1566 vmc->vmc_checkaccess |= VMOP_CREATE_CDROM; 1567 } else if (strlcpy(vcp->vcp_cdrom, vcpp->vcp_cdrom, 1568 sizeof(vcp->vcp_cdrom)) >= sizeof(vcp->vcp_cdrom)) { 1569 log_warnx("vm \"%s\" cdrom name too long", name); 1570 return (EINVAL); 1571 } 1572 1573 /* user */ 1574 if (vmc->vmc_owner.uid == 0) 1575 vmc->vmc_owner.uid = vmcp->vmc_owner.uid; 1576 else if (vmc->vmc_owner.uid != uid && 1577 vmc->vmc_owner.uid != vmcp->vmc_owner.uid) { 1578 log_warnx("vm \"%s\" user mismatch", name); 1579 return (EPERM); 1580 } 1581 1582 /* group */ 1583 if (vmc->vmc_owner.gid == 0) 1584 vmc->vmc_owner.gid = vmcp->vmc_owner.gid; 1585 else if (vmc->vmc_owner.gid != vmcp->vmc_owner.gid) { 1586 log_warnx("vm \"%s\" group mismatch", name); 1587 return (EPERM); 1588 } 1589 1590 /* child instances */ 1591 if (vmc->vmc_insflags) { 1592 log_warnx("vm \"%s\" cannot change instance permissions", name); 1593 return (EPERM); 1594 } 1595 if (vmcp->vmc_insflags & VMOP_CREATE_INSTANCE) { 1596 vmc->vmc_insowner.gid = vmcp->vmc_insowner.gid; 1597 vmc->vmc_insowner.uid = vmcp->vmc_insowner.gid; 1598 vmc->vmc_insflags = vmcp->vmc_insflags; 1599 } else { 1600 vmc->vmc_insowner.gid = 0; 1601 vmc->vmc_insowner.uid = 0; 1602 vmc->vmc_insflags = 0; 1603 } 1604 1605 /* finished, remove instance flags */ 1606 vmc->vmc_flags &= ~VMOP_CREATE_INSTANCE; 1607 1608 return (0); 1609 } 1610 1611 /* 1612 * vm_checkperm 1613 * 1614 * Checks if the user represented by the 'uid' parameter is allowed to 1615 * manipulate the VM described by the 'vm' parameter (or connect to said VM's 1616 * console.) 1617 * 1618 * Parameters: 1619 * vm: the VM whose permission is to be checked 1620 * vmo: the required uid/gid to be checked 1621 * uid: the user ID of the user making the request 1622 * 1623 * Return values: 1624 * 0: the permission should be granted 1625 * -1: the permission check failed (also returned if vm == null) 1626 */ 1627 int 1628 vm_checkperm(struct vmd_vm *vm, struct vmop_owner *vmo, uid_t uid) 1629 { 1630 struct group *gr; 1631 struct passwd *pw; 1632 char **grmem; 1633 1634 /* root has no restrictions */ 1635 if (uid == 0) 1636 return (0); 1637 1638 if (vmo == NULL) 1639 return (-1); 1640 1641 /* check user */ 1642 if (vm == NULL) { 1643 if (vmo->uid == uid) 1644 return (0); 1645 } else { 1646 /* 1647 * check user of running vm (the owner of a running vm can 1648 * be different to (or more specific than) the configured owner. 1649 */ 1650 if (((vm->vm_state & VM_STATE_RUNNING) && vm->vm_uid == uid) || 1651 (!(vm->vm_state & VM_STATE_RUNNING) && vmo->uid == uid)) 1652 return (0); 1653 } 1654 1655 /* check groups */ 1656 if (vmo->gid != -1) { 1657 if ((pw = getpwuid(uid)) == NULL) 1658 return (-1); 1659 if (pw->pw_gid == vmo->gid) 1660 return (0); 1661 if ((gr = getgrgid(vmo->gid)) != NULL) { 1662 for (grmem = gr->gr_mem; *grmem; grmem++) 1663 if (strcmp(*grmem, pw->pw_name) == 0) 1664 return (0); 1665 } 1666 } 1667 1668 return (-1); 1669 } 1670 1671 /* 1672 * vm_checkinsflag 1673 * 1674 * Checks whether the non-root user is allowed to set an instance option. 1675 * 1676 * Parameters: 1677 * vmc: the VM create parameters 1678 * flag: the flag to be checked 1679 * uid: the user ID of the user making the request 1680 * 1681 * Return values: 1682 * 0: the permission should be granted 1683 * -1: the permission check failed (also returned if vm == null) 1684 */ 1685 int 1686 vm_checkinsflag(struct vmop_create_params *vmc, unsigned int flag, uid_t uid) 1687 { 1688 /* root has no restrictions */ 1689 if (uid == 0) 1690 return (0); 1691 1692 if ((vmc->vmc_insflags & flag) == 0) 1693 return (-1); 1694 1695 return (0); 1696 } 1697 1698 /* 1699 * vm_checkaccess 1700 * 1701 * Checks if the user represented by the 'uid' parameter is allowed to 1702 * access the file described by the 'path' parameter. 1703 * 1704 * Parameters: 1705 * fd: the file descriptor of the opened file 1706 * uflag: check if the userid has access to the file 1707 * uid: the user ID of the user making the request 1708 * amode: the access flags of R_OK and W_OK 1709 * 1710 * Return values: 1711 * 0: the permission should be granted 1712 * -1: the permission check failed 1713 */ 1714 int 1715 vm_checkaccess(int fd, unsigned int uflag, uid_t uid, int amode) 1716 { 1717 struct group *gr; 1718 struct passwd *pw; 1719 char **grmem; 1720 struct stat st; 1721 mode_t mode; 1722 1723 if (fd == -1) 1724 return (-1); 1725 1726 /* 1727 * File has to be accessible and a regular file 1728 */ 1729 if (fstat(fd, &st) == -1 || !S_ISREG(st.st_mode)) 1730 return (-1); 1731 1732 /* root has no restrictions */ 1733 if (uid == 0 || uflag == 0) 1734 return (0); 1735 1736 /* check other */ 1737 mode = amode & W_OK ? S_IWOTH : 0; 1738 mode |= amode & R_OK ? S_IROTH : 0; 1739 if ((st.st_mode & mode) == mode) 1740 return (0); 1741 1742 /* check user */ 1743 mode = amode & W_OK ? S_IWUSR : 0; 1744 mode |= amode & R_OK ? S_IRUSR : 0; 1745 if (uid == st.st_uid && (st.st_mode & mode) == mode) 1746 return (0); 1747 1748 /* check groups */ 1749 mode = amode & W_OK ? S_IWGRP : 0; 1750 mode |= amode & R_OK ? S_IRGRP : 0; 1751 if ((st.st_mode & mode) != mode) 1752 return (-1); 1753 if ((pw = getpwuid(uid)) == NULL) 1754 return (-1); 1755 if (pw->pw_gid == st.st_gid) 1756 return (0); 1757 if ((gr = getgrgid(st.st_gid)) != NULL) { 1758 for (grmem = gr->gr_mem; *grmem; grmem++) 1759 if (strcmp(*grmem, pw->pw_name) == 0) 1760 return (0); 1761 } 1762 1763 return (-1); 1764 } 1765 1766 int 1767 vm_opentty(struct vmd_vm *vm) 1768 { 1769 struct ptmget ptm; 1770 struct stat st; 1771 struct group *gr; 1772 uid_t uid; 1773 gid_t gid; 1774 mode_t mode; 1775 int on; 1776 1777 /* 1778 * Open tty with pre-opened PTM fd 1779 */ 1780 if ((ioctl(env->vmd_ptmfd, PTMGET, &ptm) == -1)) 1781 return (-1); 1782 1783 /* 1784 * We use user ioctl(2) mode to pass break commands. 1785 */ 1786 on = 1; 1787 if (ioctl(ptm.cfd, TIOCUCNTL, &on) == -1) 1788 fatal("could not enable user ioctl mode"); 1789 1790 vm->vm_tty = ptm.cfd; 1791 close(ptm.sfd); 1792 if ((vm->vm_ttyname = strdup(ptm.sn)) == NULL) 1793 goto fail; 1794 1795 uid = vm->vm_uid; 1796 gid = vm->vm_params.vmc_owner.gid; 1797 1798 if (vm->vm_params.vmc_owner.gid != -1) { 1799 mode = 0660; 1800 } else if ((gr = getgrnam("tty")) != NULL) { 1801 gid = gr->gr_gid; 1802 mode = 0620; 1803 } else { 1804 mode = 0600; 1805 gid = 0; 1806 } 1807 1808 log_debug("%s: vm %s tty %s uid %d gid %d mode %o", 1809 __func__, vm->vm_params.vmc_params.vcp_name, 1810 vm->vm_ttyname, uid, gid, mode); 1811 1812 /* 1813 * Change ownership and mode of the tty as required. 1814 * Loosely based on the implementation of sshpty.c 1815 */ 1816 if (stat(vm->vm_ttyname, &st) == -1) 1817 goto fail; 1818 1819 if (st.st_uid != uid || st.st_gid != gid) { 1820 if (chown(vm->vm_ttyname, uid, gid) == -1) { 1821 log_warn("chown %s %d %d failed, uid %d", 1822 vm->vm_ttyname, uid, gid, getuid()); 1823 1824 /* Ignore failure on read-only filesystems */ 1825 if (!((errno == EROFS) && 1826 (st.st_uid == uid || st.st_uid == 0))) 1827 goto fail; 1828 } 1829 } 1830 1831 if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) { 1832 if (chmod(vm->vm_ttyname, mode) == -1) { 1833 log_warn("chmod %s %o failed, uid %d", 1834 vm->vm_ttyname, mode, getuid()); 1835 1836 /* Ignore failure on read-only filesystems */ 1837 if (!((errno == EROFS) && 1838 (st.st_uid == uid || st.st_uid == 0))) 1839 goto fail; 1840 } 1841 } 1842 1843 return (0); 1844 fail: 1845 vm_closetty(vm); 1846 return (-1); 1847 } 1848 1849 void 1850 vm_closetty(struct vmd_vm *vm) 1851 { 1852 if (vm->vm_tty != -1) { 1853 /* Release and close the tty */ 1854 if (fchown(vm->vm_tty, 0, 0) == -1) 1855 log_warn("chown %s 0 0 failed", vm->vm_ttyname); 1856 if (fchmod(vm->vm_tty, 0666) == -1) 1857 log_warn("chmod %s 0666 failed", vm->vm_ttyname); 1858 close(vm->vm_tty); 1859 vm->vm_tty = -1; 1860 } 1861 free(vm->vm_ttyname); 1862 vm->vm_ttyname = NULL; 1863 } 1864 1865 void 1866 switch_remove(struct vmd_switch *vsw) 1867 { 1868 if (vsw == NULL) 1869 return; 1870 1871 TAILQ_REMOVE(env->vmd_switches, vsw, sw_entry); 1872 1873 free(vsw->sw_group); 1874 free(vsw->sw_name); 1875 free(vsw); 1876 } 1877 1878 struct vmd_switch * 1879 switch_getbyname(const char *name) 1880 { 1881 struct vmd_switch *vsw; 1882 1883 if (name == NULL) 1884 return (NULL); 1885 TAILQ_FOREACH(vsw, env->vmd_switches, sw_entry) { 1886 if (strcmp(vsw->sw_name, name) == 0) 1887 return (vsw); 1888 } 1889 1890 return (NULL); 1891 } 1892 1893 char * 1894 get_string(uint8_t *ptr, size_t len) 1895 { 1896 size_t i; 1897 1898 for (i = 0; i < len; i++) 1899 if (!isprint((unsigned char)ptr[i])) 1900 break; 1901 1902 return strndup(ptr, i); 1903 } 1904 1905 uint32_t 1906 prefixlen2mask(uint8_t prefixlen) 1907 { 1908 if (prefixlen == 0) 1909 return (0); 1910 1911 if (prefixlen > 32) 1912 prefixlen = 32; 1913 1914 return (htonl(0xffffffff << (32 - prefixlen))); 1915 } 1916 1917 void 1918 prefixlen2mask6(uint8_t prefixlen, struct in6_addr *mask) 1919 { 1920 struct in6_addr s6; 1921 int i; 1922 1923 if (prefixlen > 128) 1924 prefixlen = 128; 1925 1926 memset(&s6, 0, sizeof(s6)); 1927 for (i = 0; i < prefixlen / 8; i++) 1928 s6.s6_addr[i] = 0xff; 1929 i = prefixlen % 8; 1930 if (i) 1931 s6.s6_addr[prefixlen / 8] = 0xff00 >> i; 1932 1933 memcpy(mask, &s6, sizeof(s6)); 1934 } 1935 1936 void 1937 getmonotime(struct timeval *tv) 1938 { 1939 struct timespec ts; 1940 1941 if (clock_gettime(CLOCK_MONOTONIC, &ts)) 1942 fatal("clock_gettime"); 1943 1944 TIMESPEC_TO_TIMEVAL(tv, &ts); 1945 } 1946