xref: /openbsd-src/sbin/iked/proc.c (revision 99fd087599a8791921855f21bd7e36130f39aadc)
1 /*	$OpenBSD: proc.c,v 1.31 2018/08/06 06:30:06 mestre Exp $	*/
2 
3 /*
4  * Copyright (c) 2010 - 2014 Reyk Floeter <reyk@openbsd.org>
5  * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/types.h>
21 #include <sys/queue.h>
22 #include <sys/socket.h>
23 #include <sys/wait.h>
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <signal.h>
31 #include <pwd.h>
32 #include <event.h>
33 #include <imsg.h>
34 
35 #include "iked.h"
36 
37 void	 proc_open(struct privsep *, struct privsep_proc *,
38 	    struct privsep_proc *, size_t);
39 void	 proc_close(struct privsep *);
40 int	 proc_ispeer(struct privsep_proc *, unsigned int, enum privsep_procid);
41 void	 proc_shutdown(struct privsep_proc *);
42 void	 proc_sig_handler(int, short, void *);
43 void	 proc_range(struct privsep *, enum privsep_procid, int *, int *);
44 int	 proc_dispatch_null(int, struct privsep_proc *, struct imsg *);
45 
46 int
47 proc_ispeer(struct privsep_proc *procs, unsigned int nproc,
48     enum privsep_procid type)
49 {
50 	unsigned int	i;
51 
52 	for (i = 0; i < nproc; i++)
53 		if (procs[i].p_id == type)
54 			return (1);
55 	return (0);
56 }
57 
58 void
59 proc_init(struct privsep *ps, struct privsep_proc *procs, unsigned int nproc)
60 {
61 	unsigned int		 i, j, src, dst;
62 	struct privsep_pipes	*pp;
63 
64 	/*
65 	 * Allocate pipes for all process instances (incl. parent)
66 	 *
67 	 * - ps->ps_pipes: N:M mapping
68 	 * N source processes connected to M destination processes:
69 	 * [src][instances][dst][instances], for example
70 	 * [PROC_RELAY][3][PROC_CA][3]
71 	 *
72 	 * - ps->ps_pp: per-process 1:M part of ps->ps_pipes
73 	 * Each process instance has a destination array of socketpair fds:
74 	 * [dst][instances], for example
75 	 * [PROC_PARENT][0]
76 	 */
77 	for (src = 0; src < PROC_MAX; src++) {
78 		/* Allocate destination array for each process */
79 		if ((ps->ps_pipes[src] = calloc(ps->ps_ninstances,
80 		    sizeof(struct privsep_pipes))) == NULL)
81 			fatal("proc_init: calloc");
82 
83 		for (i = 0; i < ps->ps_ninstances; i++) {
84 			pp = &ps->ps_pipes[src][i];
85 
86 			for (dst = 0; dst < PROC_MAX; dst++) {
87 				/* Allocate maximum fd integers */
88 				if ((pp->pp_pipes[dst] =
89 				    calloc(ps->ps_ninstances,
90 				    sizeof(int))) == NULL)
91 					fatal("proc_init: calloc");
92 
93 				/* Mark fd as unused */
94 				for (j = 0; j < ps->ps_ninstances; j++)
95 					pp->pp_pipes[dst][j] = -1;
96 			}
97 		}
98 	}
99 
100 	/*
101 	 * Setup and run the parent and its children
102 	 */
103 	privsep_process = PROC_PARENT;
104 	ps->ps_instances[PROC_PARENT] = 1;
105 	ps->ps_title[PROC_PARENT] = "parent";
106 	ps->ps_pid[PROC_PARENT] = getpid();
107 	ps->ps_pp = &ps->ps_pipes[privsep_process][0];
108 
109 	for (i = 0; i < nproc; i++) {
110 		/* Default to 1 process instance */
111 		if (ps->ps_instances[procs[i].p_id] < 1)
112 			ps->ps_instances[procs[i].p_id] = 1;
113 		ps->ps_title[procs[i].p_id] = procs[i].p_title;
114 	}
115 
116 	proc_open(ps, NULL, procs, nproc);
117 
118 	/* Engage! */
119 	for (i = 0; i < nproc; i++)
120 		ps->ps_pid[procs[i].p_id] = (*procs[i].p_init)(ps, &procs[i]);
121 }
122 
123 void
124 proc_kill(struct privsep *ps)
125 {
126 	pid_t		 pid;
127 	unsigned int	 i;
128 
129 	if (privsep_process != PROC_PARENT)
130 		return;
131 
132 	for (i = 0; i < PROC_MAX; i++) {
133 		if (ps->ps_pid[i] == 0)
134 			continue;
135 		killpg(ps->ps_pid[i], SIGTERM);
136 	}
137 
138 	do {
139 		pid = waitpid(WAIT_ANY, NULL, 0);
140 	} while (pid != -1 || (pid == -1 && errno == EINTR));
141 
142 	proc_close(ps);
143 }
144 
145 void
146 proc_open(struct privsep *ps, struct privsep_proc *p,
147     struct privsep_proc *procs, size_t nproc)
148 {
149 	struct privsep_pipes	*pa, *pb;
150 	int			 fds[2];
151 	unsigned int		 i, j, src, proc;
152 
153 	if (p == NULL)
154 		src = privsep_process; /* parent */
155 	else
156 		src = p->p_id;
157 
158 	/*
159 	 * Open socket pairs for our peers
160 	 */
161 	for (proc = 0; proc < nproc; proc++) {
162 		procs[proc].p_ps = ps;
163 		procs[proc].p_env = ps->ps_env;
164 		if (procs[proc].p_cb == NULL)
165 			procs[proc].p_cb = proc_dispatch_null;
166 
167 		for (i = 0; i < ps->ps_instances[src]; i++) {
168 			for (j = 0; j < ps->ps_instances[procs[proc].p_id];
169 			    j++) {
170 				pa = &ps->ps_pipes[src][i];
171 				pb = &ps->ps_pipes[procs[proc].p_id][j];
172 
173 				/* Check if fds are already set by peer */
174 				if (pa->pp_pipes[procs[proc].p_id][j] != -1)
175 					continue;
176 
177 				if (socketpair(AF_UNIX,
178 				    SOCK_STREAM | SOCK_NONBLOCK,
179 				    PF_UNSPEC, fds) == -1)
180 					fatal("socketpair");
181 
182 				pa->pp_pipes[procs[proc].p_id][j] = fds[0];
183 				pb->pp_pipes[src][i] = fds[1];
184 			}
185 		}
186 	}
187 }
188 
189 void
190 proc_listen(struct privsep *ps, struct privsep_proc *procs, size_t nproc)
191 {
192 	unsigned int		 i, dst, src, n, m;
193 	struct privsep_pipes	*pp;
194 
195 	/*
196 	 * Close unused pipes
197 	 */
198 	for (src = 0; src < PROC_MAX; src++) {
199 		for (n = 0; n < ps->ps_instances[src]; n++) {
200 			/* Ingore current process */
201 			if (src == (unsigned int)privsep_process &&
202 			    n == ps->ps_instance)
203 				continue;
204 
205 			pp = &ps->ps_pipes[src][n];
206 
207 			for (dst = 0; dst < PROC_MAX; dst++) {
208 				if (src == dst)
209 					continue;
210 				for (m = 0; m < ps->ps_instances[dst]; m++) {
211 					if (pp->pp_pipes[dst][m] == -1)
212 						continue;
213 
214 					/* Close and invalidate fd */
215 					close(pp->pp_pipes[dst][m]);
216 					pp->pp_pipes[dst][m] = -1;
217 				}
218 			}
219 		}
220 	}
221 
222 	src = privsep_process;
223 	ps->ps_pp = pp = &ps->ps_pipes[src][ps->ps_instance];
224 
225 	/*
226 	 * Listen on appropriate pipes
227 	 */
228 	for (i = 0; i < nproc; i++) {
229 		dst = procs[i].p_id;
230 
231 		if (src == dst)
232 			fatal("proc_listen: cannot peer with oneself");
233 
234 		if ((ps->ps_ievs[dst] = calloc(ps->ps_instances[dst],
235 		    sizeof(struct imsgev))) == NULL)
236 			fatal("proc_open");
237 
238 		for (n = 0; n < ps->ps_instances[dst]; n++) {
239 			if (pp->pp_pipes[dst][n] == -1)
240 				continue;
241 
242 			imsg_init(&(ps->ps_ievs[dst][n].ibuf),
243 			    pp->pp_pipes[dst][n]);
244 			ps->ps_ievs[dst][n].handler = proc_dispatch;
245 			ps->ps_ievs[dst][n].events = EV_READ;
246 			ps->ps_ievs[dst][n].proc = &procs[i];
247 			ps->ps_ievs[dst][n].data = &ps->ps_ievs[dst][n];
248 			procs[i].p_instance = n;
249 
250 			event_set(&(ps->ps_ievs[dst][n].ev),
251 			    ps->ps_ievs[dst][n].ibuf.fd,
252 			    ps->ps_ievs[dst][n].events,
253 			    ps->ps_ievs[dst][n].handler,
254 			    ps->ps_ievs[dst][n].data);
255 			event_add(&(ps->ps_ievs[dst][n].ev), NULL);
256 		}
257 	}
258 }
259 
260 void
261 proc_close(struct privsep *ps)
262 {
263 	unsigned int		 dst, n;
264 	struct privsep_pipes	*pp;
265 
266 	if (ps == NULL)
267 		return;
268 
269 	pp = ps->ps_pp;
270 
271 	for (dst = 0; dst < PROC_MAX; dst++) {
272 		if (ps->ps_ievs[dst] == NULL)
273 			continue;
274 
275 		for (n = 0; n < ps->ps_instances[dst]; n++) {
276 			if (pp->pp_pipes[dst][n] == -1)
277 				continue;
278 
279 			/* Cancel the fd, close and invalidate the fd */
280 			event_del(&(ps->ps_ievs[dst][n].ev));
281 			imsg_clear(&(ps->ps_ievs[dst][n].ibuf));
282 			close(pp->pp_pipes[dst][n]);
283 			pp->pp_pipes[dst][n] = -1;
284 		}
285 		free(ps->ps_ievs[dst]);
286 	}
287 }
288 
289 void
290 proc_shutdown(struct privsep_proc *p)
291 {
292 	struct privsep	*ps = p->p_ps;
293 
294 	if (p->p_shutdown != NULL)
295 		(*p->p_shutdown)();
296 
297 	proc_close(ps);
298 
299 	log_info("%s exiting, pid %d", p->p_title, getpid());
300 
301 	_exit(0);
302 }
303 
304 void
305 proc_sig_handler(int sig, short event, void *arg)
306 {
307 	struct privsep_proc	*p = arg;
308 
309 	switch (sig) {
310 	case SIGINT:
311 	case SIGTERM:
312 		proc_shutdown(p);
313 		break;
314 	case SIGCHLD:
315 	case SIGHUP:
316 	case SIGPIPE:
317 	case SIGUSR1:
318 		/* ignore */
319 		break;
320 	default:
321 		fatalx("proc_sig_handler: unexpected signal");
322 		/* NOTREACHED */
323 	}
324 }
325 
326 pid_t
327 proc_run(struct privsep *ps, struct privsep_proc *p,
328     struct privsep_proc *procs, unsigned int nproc,
329     void (*run)(struct privsep *, struct privsep_proc *, void *), void *arg)
330 {
331 	pid_t			 pid;
332 	struct passwd		*pw;
333 	const char		*root;
334 	struct control_sock	*rcs;
335 	unsigned int		 n;
336 
337 	if (ps->ps_noaction)
338 		return (0);
339 
340 	proc_open(ps, p, procs, nproc);
341 
342 	/* Fork child handlers */
343 	switch (pid = fork()) {
344 	case -1:
345 		fatal("proc_run: cannot fork");
346 	case 0:
347 		log_procinit(p->p_title);
348 
349 		/* Set the process group of the current process */
350 		setpgid(0, 0);
351 		break;
352 	default:
353 		return (pid);
354 	}
355 
356 	pw = ps->ps_pw;
357 
358 	if (p->p_id == PROC_CONTROL && ps->ps_instance == 0) {
359 		if (control_init(ps, &ps->ps_csock) == -1)
360 			fatalx(__func__);
361 		TAILQ_FOREACH(rcs, &ps->ps_rcsocks, cs_entry)
362 			if (control_init(ps, rcs) == -1)
363 				fatalx(__func__);
364 	}
365 
366 	/* Change root directory */
367 	if (p->p_chroot != NULL)
368 		root = p->p_chroot;
369 	else
370 		root = pw->pw_dir;
371 
372 	if (chroot(root) == -1)
373 		fatal("proc_run: chroot");
374 	if (chdir("/") == -1)
375 		fatal("proc_run: chdir(\"/\")");
376 
377 	privsep_process = p->p_id;
378 
379 	setproctitle("%s", p->p_title);
380 
381 	if (setgroups(1, &pw->pw_gid) ||
382 	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
383 	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
384 		fatal("proc_run: cannot drop privileges");
385 
386 	/* Fork child handlers */
387 	for (n = 1; n < ps->ps_instances[p->p_id]; n++) {
388 		if (fork() == 0) {
389 			ps->ps_instance = p->p_instance = n;
390 			break;
391 		}
392 	}
393 
394 #ifdef DEBUG
395 	log_debug("%s: %s %d/%d, pid %d", __func__, p->p_title,
396 	    ps->ps_instance + 1, ps->ps_instances[p->p_id], getpid());
397 #endif
398 
399 	event_init();
400 
401 	signal_set(&ps->ps_evsigint, SIGINT, proc_sig_handler, p);
402 	signal_set(&ps->ps_evsigterm, SIGTERM, proc_sig_handler, p);
403 	signal_set(&ps->ps_evsigchld, SIGCHLD, proc_sig_handler, p);
404 	signal_set(&ps->ps_evsighup, SIGHUP, proc_sig_handler, p);
405 	signal_set(&ps->ps_evsigpipe, SIGPIPE, proc_sig_handler, p);
406 	signal_set(&ps->ps_evsigusr1, SIGUSR1, proc_sig_handler, p);
407 
408 	signal_add(&ps->ps_evsigint, NULL);
409 	signal_add(&ps->ps_evsigterm, NULL);
410 	signal_add(&ps->ps_evsigchld, NULL);
411 	signal_add(&ps->ps_evsighup, NULL);
412 	signal_add(&ps->ps_evsigpipe, NULL);
413 	signal_add(&ps->ps_evsigusr1, NULL);
414 
415 	proc_listen(ps, procs, nproc);
416 
417 	if (p->p_id == PROC_CONTROL && ps->ps_instance == 0) {
418 		TAILQ_INIT(&ctl_conns);
419 		if (control_listen(&ps->ps_csock) == -1)
420 			fatalx(__func__);
421 		TAILQ_FOREACH(rcs, &ps->ps_rcsocks, cs_entry)
422 			if (control_listen(rcs) == -1)
423 				fatalx(__func__);
424 	}
425 
426 	if (run != NULL)
427 		run(ps, p, arg);
428 
429 	event_dispatch();
430 
431 	proc_shutdown(p);
432 
433 	return (0);
434 }
435 
436 void
437 proc_dispatch(int fd, short event, void *arg)
438 {
439 	struct imsgev		*iev = arg;
440 	struct privsep_proc	*p = iev->proc;
441 	struct privsep		*ps = p->p_ps;
442 	struct imsgbuf		*ibuf;
443 	struct imsg		 imsg;
444 	ssize_t			 n;
445 	int			 verbose;
446 	const char		*title;
447 
448 	title = ps->ps_title[privsep_process];
449 	ibuf = &iev->ibuf;
450 
451 	if (event & EV_READ) {
452 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
453 			fatal(__func__);
454 		if (n == 0) {
455 			/* this pipe is dead, so remove the event handler */
456 			event_del(&iev->ev);
457 			event_loopexit(NULL);
458 			return;
459 		}
460 	}
461 
462 	if (event & EV_WRITE) {
463 		if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN)
464 			fatal(__func__);
465 	}
466 
467 	for (;;) {
468 		if ((n = imsg_get(ibuf, &imsg)) == -1)
469 			fatal(__func__);
470 		if (n == 0)
471 			break;
472 
473 #if DEBUG > 1
474 		log_debug("%s: %s %d got imsg %d peerid %d from %s %d",
475 		    __func__, title, ps->ps_instance + 1,
476 		    imsg.hdr.type, imsg.hdr.peerid, p->p_title, p->p_instance);
477 #endif
478 
479 		/*
480 		 * Check the message with the program callback
481 		 */
482 		if ((p->p_cb)(fd, p, &imsg) == 0) {
483 			/* Message was handled by the callback, continue */
484 			imsg_free(&imsg);
485 			continue;
486 		}
487 
488 		/*
489 		 * Generic message handling
490 		 */
491 		switch (imsg.hdr.type) {
492 		case IMSG_CTL_VERBOSE:
493 			IMSG_SIZE_CHECK(&imsg, &verbose);
494 			memcpy(&verbose, imsg.data, sizeof(verbose));
495 			log_setverbose(verbose);
496 			break;
497 		default:
498 			log_warnx("%s: %s %d got invalid imsg %d peerid %d "
499 			    "from %s %d",
500 			    __func__, title, ps->ps_instance + 1,
501 			    imsg.hdr.type, imsg.hdr.peerid,
502 			    p->p_title, p->p_instance);
503 			fatalx(__func__);
504 		}
505 		imsg_free(&imsg);
506 	}
507 	imsg_event_add(iev);
508 }
509 
510 int
511 proc_dispatch_null(int fd, struct privsep_proc *p, struct imsg *imsg)
512 {
513 	return (-1);
514 }
515 
516 /*
517  * imsg helper functions
518  */
519 
520 void
521 imsg_event_add(struct imsgev *iev)
522 {
523 	if (iev->handler == NULL) {
524 		imsg_flush(&iev->ibuf);
525 		return;
526 	}
527 
528 	iev->events = EV_READ;
529 	if (iev->ibuf.w.queued)
530 		iev->events |= EV_WRITE;
531 
532 	event_del(&iev->ev);
533 	event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev->data);
534 	event_add(&iev->ev, NULL);
535 }
536 
537 int
538 imsg_compose_event(struct imsgev *iev, uint16_t type, uint32_t peerid,
539     pid_t pid, int fd, void *data, uint16_t datalen)
540 {
541 	int	ret;
542 
543 	if ((ret = imsg_compose(&iev->ibuf, type, peerid,
544 	    pid, fd, data, datalen)) == -1)
545 		return (ret);
546 	imsg_event_add(iev);
547 	return (ret);
548 }
549 
550 int
551 imsg_composev_event(struct imsgev *iev, uint16_t type, uint32_t peerid,
552     pid_t pid, int fd, const struct iovec *iov, int iovcnt)
553 {
554 	int	ret;
555 
556 	if ((ret = imsg_composev(&iev->ibuf, type, peerid,
557 	    pid, fd, iov, iovcnt)) == -1)
558 		return (ret);
559 	imsg_event_add(iev);
560 	return (ret);
561 }
562 
563 void
564 proc_range(struct privsep *ps, enum privsep_procid id, int *n, int *m)
565 {
566 	if (*n == -1) {
567 		/* Use a range of all target instances */
568 		*n = 0;
569 		*m = ps->ps_instances[id];
570 	} else {
571 		/* Use only a single slot of the specified peer process */
572 		*m = *n + 1;
573 	}
574 }
575 
576 int
577 proc_compose_imsg(struct privsep *ps, enum privsep_procid id, int n,
578     uint16_t type, uint32_t peerid, int fd, void *data, uint16_t datalen)
579 {
580 	int	 m;
581 
582 	proc_range(ps, id, &n, &m);
583 	for (; n < m; n++) {
584 		if (imsg_compose_event(&ps->ps_ievs[id][n],
585 		    type, peerid, 0, fd, data, datalen) == -1)
586 			return (-1);
587 	}
588 
589 	return (0);
590 }
591 
592 int
593 proc_compose(struct privsep *ps, enum privsep_procid id,
594     uint16_t type, void *data, uint16_t datalen)
595 {
596 	return (proc_compose_imsg(ps, id, -1, type, -1, -1, data, datalen));
597 }
598 
599 int
600 proc_composev_imsg(struct privsep *ps, enum privsep_procid id, int n,
601     uint16_t type, uint32_t peerid, int fd, const struct iovec *iov, int iovcnt)
602 {
603 	int	 m;
604 
605 	proc_range(ps, id, &n, &m);
606 	for (; n < m; n++)
607 		if (imsg_composev_event(&ps->ps_ievs[id][n],
608 		    type, peerid, 0, fd, iov, iovcnt) == -1)
609 			return (-1);
610 
611 	return (0);
612 }
613 
614 int
615 proc_composev(struct privsep *ps, enum privsep_procid id,
616     uint16_t type, const struct iovec *iov, int iovcnt)
617 {
618 	return (proc_composev_imsg(ps, id, -1, type, -1, -1, iov, iovcnt));
619 }
620 
621 int
622 proc_forward_imsg(struct privsep *ps, struct imsg *imsg,
623     enum privsep_procid id, int n)
624 {
625 	return (proc_compose_imsg(ps, id, n, imsg->hdr.type,
626 	    imsg->hdr.peerid, imsg->fd, imsg->data, IMSG_DATA_SIZE(imsg)));
627 }
628 
629 struct imsgbuf *
630 proc_ibuf(struct privsep *ps, enum privsep_procid id, int n)
631 {
632 	int	 m;
633 
634 	proc_range(ps, id, &n, &m);
635 	return (&ps->ps_ievs[id][n].ibuf);
636 }
637 
638 struct imsgev *
639 proc_iev(struct privsep *ps, enum privsep_procid id, int n)
640 {
641 	int	 m;
642 
643 	proc_range(ps, id, &n, &m);
644 	return (&ps->ps_ievs[id][n]);
645 }
646