xref: /dragonfly/contrib/dhcpcd/src/privsep.h (revision a85d0907)
16e63cc1fSRoy Marples /* SPDX-License-Identifier: BSD-2-Clause */
26e63cc1fSRoy Marples /*
36e63cc1fSRoy Marples  * Privilege Separation for dhcpcd
480aa9461SRoy Marples  * Copyright (c) 2006-2023 Roy Marples <roy@marples.name>
56e63cc1fSRoy Marples  * All rights reserved
66e63cc1fSRoy Marples 
76e63cc1fSRoy Marples  * Redistribution and use in source and binary forms, with or without
86e63cc1fSRoy Marples  * modification, are permitted provided that the following conditions
96e63cc1fSRoy Marples  * are met:
106e63cc1fSRoy Marples  * 1. Redistributions of source code must retain the above copyright
116e63cc1fSRoy Marples  *    notice, this list of conditions and the following disclaimer.
126e63cc1fSRoy Marples  * 2. Redistributions in binary form must reproduce the above copyright
136e63cc1fSRoy Marples  *    notice, this list of conditions and the following disclaimer in the
146e63cc1fSRoy Marples  *    documentation and/or other materials provided with the distribution.
156e63cc1fSRoy Marples  *
166e63cc1fSRoy Marples  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
176e63cc1fSRoy Marples  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
186e63cc1fSRoy Marples  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
196e63cc1fSRoy Marples  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
206e63cc1fSRoy Marples  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
216e63cc1fSRoy Marples  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
226e63cc1fSRoy Marples  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
236e63cc1fSRoy Marples  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
246e63cc1fSRoy Marples  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
256e63cc1fSRoy Marples  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
266e63cc1fSRoy Marples  * SUCH DAMAGE.
276e63cc1fSRoy Marples  */
286e63cc1fSRoy Marples 
296e63cc1fSRoy Marples #ifndef PRIVSEP_H
306e63cc1fSRoy Marples #define PRIVSEP_H
316e63cc1fSRoy Marples 
326e63cc1fSRoy Marples //#define PRIVSEP_DEBUG
336e63cc1fSRoy Marples 
346e63cc1fSRoy Marples /* Start flags */
356e63cc1fSRoy Marples #define	PSF_DROPPRIVS		0x01
3680aa9461SRoy Marples #define	PSF_ELOOP		0x02
376e63cc1fSRoy Marples 
38d4fb1e02SRoy Marples /* Protocols */
39d4fb1e02SRoy Marples #define	PS_BOOTP		0x0001
40d4fb1e02SRoy Marples #define	PS_ND			0x0002
41d4fb1e02SRoy Marples #define	PS_DHCP6		0x0003
42d4fb1e02SRoy Marples #define	PS_BPF_BOOTP		0x0004
43d4fb1e02SRoy Marples #define	PS_BPF_ARP		0x0005
446e63cc1fSRoy Marples 
45d4fb1e02SRoy Marples /* Generic commands */
46d4fb1e02SRoy Marples #define	PS_IOCTL		0x0010
47d4fb1e02SRoy Marples #define	PS_ROUTE		0x0011	/* Also used for NETLINK */
48d4fb1e02SRoy Marples #define	PS_SCRIPT		0x0012
49d4fb1e02SRoy Marples #define	PS_UNLINK		0x0013
50d4fb1e02SRoy Marples #define	PS_READFILE		0x0014
51d4fb1e02SRoy Marples #define	PS_WRITEFILE		0x0015
52d4fb1e02SRoy Marples #define	PS_FILEMTIME		0x0016
53acd7a309SRoy Marples #define	PS_AUTH_MONORDM		0x0017
547f8103cdSRoy Marples #define	PS_CTL			0x0018
557f8103cdSRoy Marples #define	PS_CTL_EOF		0x0019
5639994b17SRoy Marples #define	PS_LOGREOPEN		0x0020
5780aa9461SRoy Marples #define	PS_STOPPROCS		0x0021
58*a85d0907SRoy Marples #define	PS_DAEMONISED		0x0022
5980aa9461SRoy Marples 
6080aa9461SRoy Marples /* Domains */
6180aa9461SRoy Marples #define	PS_ROOT			0x0101
6280aa9461SRoy Marples #define	PS_INET			0x0102
6380aa9461SRoy Marples #define	PS_CONTROL		0x0103
646e63cc1fSRoy Marples 
656e63cc1fSRoy Marples /* BSD Commands */
6680aa9461SRoy Marples #define	PS_IOCTLLINK		0x0201
6780aa9461SRoy Marples #define	PS_IOCTL6		0x0202
6880aa9461SRoy Marples #define	PS_IOCTLINDIRECT	0x0203
6980aa9461SRoy Marples #define	PS_IP6FORWARDING	0x0204
7080aa9461SRoy Marples #define	PS_GETIFADDRS		0x0205
7180aa9461SRoy Marples #define	PS_IFIGNOREGRP		0x0206
7280aa9461SRoy Marples #define	PS_SYSCTL		0x0207
736e63cc1fSRoy Marples 
74d4fb1e02SRoy Marples /* Dev Commands */
757f8103cdSRoy Marples #define	PS_DEV_LISTENING	0x1001
767f8103cdSRoy Marples #define	PS_DEV_INITTED		0x1002
777f8103cdSRoy Marples #define	PS_DEV_IFCMD		0x1003
786e63cc1fSRoy Marples 
79d4fb1e02SRoy Marples /* Dev Interface Commands (via flags) */
80d4fb1e02SRoy Marples #define	PS_DEV_IFADDED		0x0001
81d4fb1e02SRoy Marples #define	PS_DEV_IFREMOVED	0x0002
82d4fb1e02SRoy Marples #define	PS_DEV_IFUPDATED	0x0003
83d4fb1e02SRoy Marples 
847f8103cdSRoy Marples /* Control Type (via flags) */
857f8103cdSRoy Marples #define	PS_CTL_PRIV		0x0004
867f8103cdSRoy Marples #define	PS_CTL_UNPRIV		0x0005
877f8103cdSRoy Marples 
8880aa9461SRoy Marples /* Sysctl Needs (via flags) */
8980aa9461SRoy Marples #define	PS_SYSCTL_OLEN		0x0001
9080aa9461SRoy Marples #define	PS_SYSCTL_ODATA		0x0002
9180aa9461SRoy Marples 
92d4fb1e02SRoy Marples /* Process commands */
93d4fb1e02SRoy Marples #define	PS_START		0x4000
94d4fb1e02SRoy Marples #define	PS_STOP			0x8000
956e63cc1fSRoy Marples 
966e63cc1fSRoy Marples /* Max INET message size + meta data for IPC */
976e63cc1fSRoy Marples #define	PS_BUFLEN		((64 * 1024) +			\
986e63cc1fSRoy Marples 				 sizeof(struct ps_msghdr) +	\
996e63cc1fSRoy Marples 				 sizeof(struct msghdr) +	\
1006e63cc1fSRoy Marples 				 CMSG_SPACE(sizeof(struct in6_pktinfo) + \
1016e63cc1fSRoy Marples 					    sizeof(int)))
1026e63cc1fSRoy Marples 
10380aa9461SRoy Marples #define	PSP_NAMESIZE		16 + INET_MAX_ADDRSTRLEN
10480aa9461SRoy Marples 
1056e63cc1fSRoy Marples /* Handy macro to work out if in the privsep engine or not. */
1066e63cc1fSRoy Marples #define	IN_PRIVSEP(ctx)	\
1076e63cc1fSRoy Marples 	((ctx)->options & DHCPCD_PRIVSEP)
1086e63cc1fSRoy Marples #define	IN_PRIVSEP_SE(ctx)	\
1096e63cc1fSRoy Marples 	(((ctx)->options & (DHCPCD_PRIVSEP | DHCPCD_FORKED)) == DHCPCD_PRIVSEP)
1106e63cc1fSRoy Marples 
11180aa9461SRoy Marples #define	PS_PROCESS_TIMEOUT	5	/* seconds to stop all processes */
11280aa9461SRoy Marples 
1137f8103cdSRoy Marples #if defined(PRIVSEP) && defined(HAVE_CAPSICUM)
1147f8103cdSRoy Marples #define PRIVSEP_RIGHTS
1157f8103cdSRoy Marples #endif
1167f8103cdSRoy Marples 
117f3744ac9SRoy Marples #define PS_ROOT_FD(ctx) ((ctx)->ps_root ? (ctx)->ps_root->psp_fd : -1)
118f3744ac9SRoy Marples 
1194f235d86SRoy Marples #if !defined(DISABLE_SECCOMP) && defined(__linux__)
120a0d9933aSRoy Marples # include <linux/version.h>
121a0d9933aSRoy Marples # if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
122a0d9933aSRoy Marples #  define HAVE_SECCOMP
123a0d9933aSRoy Marples # endif
124a0d9933aSRoy Marples #endif
125a0d9933aSRoy Marples 
1266e63cc1fSRoy Marples #include "config.h"
1276e63cc1fSRoy Marples #include "arp.h"
1286e63cc1fSRoy Marples #include "dhcp.h"
1296e63cc1fSRoy Marples #include "dhcpcd.h"
1306e63cc1fSRoy Marples 
1316e63cc1fSRoy Marples struct ps_addr {
1326e63cc1fSRoy Marples 	sa_family_t psa_family;
1336e63cc1fSRoy Marples 	uint8_t psa_pad[4 - sizeof(sa_family_t)];
1346e63cc1fSRoy Marples 	union {
1356e63cc1fSRoy Marples 		struct in_addr psau_in_addr;
1366e63cc1fSRoy Marples 		struct in6_addr psau_in6_addr;
1376e63cc1fSRoy Marples 	} psa_u;
1386e63cc1fSRoy Marples #define	psa_in_addr	psa_u.psau_in_addr
1396e63cc1fSRoy Marples #define	psa_in6_addr	psa_u.psau_in6_addr
1406e63cc1fSRoy Marples };
1416e63cc1fSRoy Marples 
1426e63cc1fSRoy Marples /* Uniquely identify a process */
1436e63cc1fSRoy Marples struct ps_id {
1446e63cc1fSRoy Marples 	struct ps_addr psi_addr;
1456e63cc1fSRoy Marples 	unsigned int psi_ifindex;
146d4fb1e02SRoy Marples 	uint16_t psi_cmd;
147d4fb1e02SRoy Marples 	uint8_t psi_pad[2];
1486e63cc1fSRoy Marples };
1496e63cc1fSRoy Marples 
1506e63cc1fSRoy Marples struct ps_msghdr {
151d4fb1e02SRoy Marples 	uint16_t ps_cmd;
152d4fb1e02SRoy Marples 	uint8_t ps_pad[sizeof(unsigned long) - sizeof(uint16_t)];
1536e63cc1fSRoy Marples 	unsigned long ps_flags;
1546e63cc1fSRoy Marples 	struct ps_id ps_id;
1556e63cc1fSRoy Marples 	socklen_t ps_namelen;
1566e63cc1fSRoy Marples 	socklen_t ps_controllen;
1576e63cc1fSRoy Marples 	uint8_t ps_pad2[sizeof(size_t) - sizeof(socklen_t)];
1586e63cc1fSRoy Marples 	size_t ps_datalen;
1596e63cc1fSRoy Marples };
1606e63cc1fSRoy Marples 
1616e63cc1fSRoy Marples struct ps_msg {
1626e63cc1fSRoy Marples 	struct ps_msghdr psm_hdr;
1636e63cc1fSRoy Marples 	uint8_t psm_data[PS_BUFLEN];
1646e63cc1fSRoy Marples };
1656e63cc1fSRoy Marples 
166d4fb1e02SRoy Marples struct bpf;
16780aa9461SRoy Marples 
1686e63cc1fSRoy Marples struct ps_process {
1696e63cc1fSRoy Marples 	TAILQ_ENTRY(ps_process) next;
1706e63cc1fSRoy Marples 	struct dhcpcd_ctx *psp_ctx;
1716e63cc1fSRoy Marples 	struct ps_id psp_id;
1726e63cc1fSRoy Marples 	pid_t psp_pid;
1736e63cc1fSRoy Marples 	int psp_fd;
1746e63cc1fSRoy Marples 	int psp_work_fd;
1756e63cc1fSRoy Marples 	unsigned int psp_ifindex;
1766e63cc1fSRoy Marples 	char psp_ifname[IF_NAMESIZE];
17780aa9461SRoy Marples 	char psp_name[PSP_NAMESIZE];
1786e63cc1fSRoy Marples 	uint16_t psp_proto;
1796e63cc1fSRoy Marples 	const char *psp_protostr;
18080aa9461SRoy Marples 	bool psp_started;
1816e63cc1fSRoy Marples 
1826e63cc1fSRoy Marples #ifdef INET
183d4fb1e02SRoy Marples 	int (*psp_filter)(const struct bpf *, const struct in_addr *);
1846e63cc1fSRoy Marples 	struct interface psp_ifp; /* Move BPF gubbins elsewhere */
185d4fb1e02SRoy Marples 	struct bpf *psp_bpf;
1866e63cc1fSRoy Marples #endif
18780aa9461SRoy Marples 
18880aa9461SRoy Marples #ifdef HAVE_CAPSICUM
18980aa9461SRoy Marples 	int psp_pfd;
19080aa9461SRoy Marples #endif
1916e63cc1fSRoy Marples };
1926e63cc1fSRoy Marples TAILQ_HEAD(ps_process_head, ps_process);
1936e63cc1fSRoy Marples 
1947f8103cdSRoy Marples #include "privsep-control.h"
1956e63cc1fSRoy Marples #include "privsep-inet.h"
1966e63cc1fSRoy Marples #include "privsep-root.h"
1976e63cc1fSRoy Marples #ifdef INET
1986e63cc1fSRoy Marples #include "privsep-bpf.h"
1996e63cc1fSRoy Marples #endif
2006e63cc1fSRoy Marples 
2016e63cc1fSRoy Marples int ps_init(struct dhcpcd_ctx *);
2026e63cc1fSRoy Marples int ps_start(struct dhcpcd_ctx *);
2036e63cc1fSRoy Marples int ps_stop(struct dhcpcd_ctx *);
20480aa9461SRoy Marples int ps_stopwait(struct dhcpcd_ctx *);
205a0d9933aSRoy Marples int ps_entersandbox(const char *, const char **);
2060a68f8d2SRoy Marples int ps_managersandbox(struct dhcpcd_ctx *, const char *);
207*a85d0907SRoy Marples ssize_t ps_daemonised(struct dhcpcd_ctx *);
2086e63cc1fSRoy Marples 
2096e63cc1fSRoy Marples int ps_unrollmsg(struct msghdr *, struct ps_msghdr *, const void *, size_t);
2106e63cc1fSRoy Marples ssize_t ps_sendpsmmsg(struct dhcpcd_ctx *, int,
2116e63cc1fSRoy Marples     struct ps_msghdr *, const struct msghdr *);
2126e63cc1fSRoy Marples ssize_t ps_sendpsmdata(struct dhcpcd_ctx *, int,
2136e63cc1fSRoy Marples     struct ps_msghdr *, const void *, size_t);
214d4fb1e02SRoy Marples ssize_t ps_sendmsg(struct dhcpcd_ctx *, int, uint16_t, unsigned long,
2156e63cc1fSRoy Marples     const struct msghdr *);
216d4fb1e02SRoy Marples ssize_t ps_sendcmd(struct dhcpcd_ctx *, int, uint16_t, unsigned long,
2176e63cc1fSRoy Marples     const void *data, size_t len);
218f3744ac9SRoy Marples ssize_t ps_recvmsg(int, unsigned short, uint16_t, int);
21980aa9461SRoy Marples ssize_t ps_recvpsmsg(struct dhcpcd_ctx *, int, unsigned short,
2206e63cc1fSRoy Marples     ssize_t (*callback)(void *, struct ps_msghdr *, struct msghdr *), void *);
2216e63cc1fSRoy Marples 
2226e63cc1fSRoy Marples /* Internal privsep functions. */
2237f8103cdSRoy Marples int ps_setbuf_fdpair(int []);
224a0d9933aSRoy Marples 
2257f8103cdSRoy Marples #ifdef PRIVSEP_RIGHTS
2267f8103cdSRoy Marples int ps_rights_limit_ioctl(int);
2277f8103cdSRoy Marples int ps_rights_limit_fd_fctnl(int);
2287f8103cdSRoy Marples int ps_rights_limit_fd_rdonly(int);
229a0d9933aSRoy Marples int ps_rights_limit_fd_sockopt(int);
2307f8103cdSRoy Marples int ps_rights_limit_fd(int);
2317f8103cdSRoy Marples int ps_rights_limit_fdpair(int []);
2327f8103cdSRoy Marples #endif
233a0d9933aSRoy Marples 
234a0d9933aSRoy Marples #ifdef HAVE_SECCOMP
235a0d9933aSRoy Marples int ps_seccomp_enter(void);
236a0d9933aSRoy Marples #endif
237a0d9933aSRoy Marples 
23880aa9461SRoy Marples pid_t ps_startprocess(struct ps_process *,
23980aa9461SRoy Marples     void (*recv_msg)(void *, unsigned short),
24080aa9461SRoy Marples     void (*recv_unpriv_msg)(void *, unsigned short),
24180aa9461SRoy Marples     int (*callback)(struct ps_process *), void (*)(int, void *),
2426e63cc1fSRoy Marples     unsigned int);
24380aa9461SRoy Marples int ps_stopprocess(struct ps_process *);
2446e63cc1fSRoy Marples struct ps_process *ps_findprocess(struct dhcpcd_ctx *, struct ps_id *);
24580aa9461SRoy Marples struct ps_process *ps_findprocesspid(struct dhcpcd_ctx *, pid_t);
2466e63cc1fSRoy Marples struct ps_process *ps_newprocess(struct dhcpcd_ctx *, struct ps_id *);
24780aa9461SRoy Marples bool ps_waitforprocs(struct dhcpcd_ctx *ctx);
24880aa9461SRoy Marples void ps_process_timeout(void *);
2496e63cc1fSRoy Marples void ps_freeprocess(struct ps_process *);
2506e63cc1fSRoy Marples void ps_freeprocesses(struct dhcpcd_ctx *, struct ps_process *);
2516e63cc1fSRoy Marples #endif
252