2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2012 The FreeBSD Foundation
5 * Copyright (c) 2015 Mariusz Zaborski <oshogbo@FreeBSD.org>
6 * Copyright (c) 2017 Robert N. M. Watson
8 * This software was developed by Pawel Jakub Dawidek under sponsorship from
9 * the FreeBSD Foundation.
11 * All rights reserved.
12 * This software was developed by SRI International and the University of
13 * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
14 * ("CTSRD"), as part of the DARPA CRASH research programme.
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
41 #include <sys/types.h>
42 #include <sys/capsicum.h>
43 #include <sys/procdesc.h>
44 #include <sys/socket.h>
58 static int zygote_sock = -1;
60 #define ZYGOTE_SERVICE_EXECUTE 1
63 zygote_clone(uint64_t funcidx, int *chanfdp, int *procfdp)
68 if (zygote_sock == -1) {
69 /* Zygote didn't start. */
74 nvl = nvlist_create(0);
75 nvlist_add_number(nvl, "funcidx", funcidx);
76 nvl = nvlist_xfer(zygote_sock, nvl, 0);
79 if (nvlist_exists_number(nvl, "error")) {
80 error = (int)nvlist_get_number(nvl, "error");
86 *chanfdp = nvlist_take_descriptor(nvl, "chanfd");
87 *procfdp = nvlist_take_descriptor(nvl, "procfd");
94 zygote_clone_service_execute(int *chanfdp, int *procfdp)
97 return (zygote_clone(ZYGOTE_SERVICE_EXECUTE, chanfdp, procfdp));
101 * This function creates sandboxes on-demand whoever has access to it via
102 * 'sock' socket. Function sends two descriptors to the caller: process
103 * descriptor of the sandbox and socket pair descriptor for communication
104 * between sandbox and its owner.
107 zygote_main(int sock)
111 nvlist_t *nvlin, *nvlout;
116 assert(sock > STDERR_FILENO);
118 setproctitle("zygote");
121 nvlin = nvlist_recv(sock, 0);
123 if (errno == ENOTCONN) {
129 funcidx = nvlist_get_number(nvlin, "funcidx");
130 nvlist_destroy(nvlin);
133 case ZYGOTE_SERVICE_EXECUTE:
134 func = service_execute;
141 * Someone is requesting a new process, create one.
147 if (socketpair(PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0,
152 pid = pdfork(&procfd, 0);
171 nvlout = nvlist_create(0);
173 nvlist_add_number(nvlout, "error", (uint64_t)error);
179 nvlist_move_descriptor(nvlout, "chanfd", chanfd[0]);
180 nvlist_move_descriptor(nvlout, "procfd", procfd);
182 (void)nvlist_send(sock, nvlout);
183 nvlist_destroy(nvlout);
194 if (socketpair(PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, sp) == -1)