xref: /dragonfly/contrib/dhcpcd/src/privsep.h (revision 0a68f8d2)
16e63cc1fSRoy Marples /* SPDX-License-Identifier: BSD-2-Clause */
26e63cc1fSRoy Marples /*
36e63cc1fSRoy Marples  * Privilege Separation for dhcpcd
40a68f8d2SRoy Marples  * Copyright (c) 2006-2021 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
366e63cc1fSRoy Marples 
37d4fb1e02SRoy Marples /* Protocols */
38d4fb1e02SRoy Marples #define	PS_BOOTP		0x0001
39d4fb1e02SRoy Marples #define	PS_ND			0x0002
40d4fb1e02SRoy Marples #define	PS_DHCP6		0x0003
41d4fb1e02SRoy Marples #define	PS_BPF_BOOTP		0x0004
42d4fb1e02SRoy Marples #define	PS_BPF_ARP		0x0005
436e63cc1fSRoy Marples 
44d4fb1e02SRoy Marples /* Generic commands */
45d4fb1e02SRoy Marples #define	PS_IOCTL		0x0010
46d4fb1e02SRoy Marples #define	PS_ROUTE		0x0011	/* Also used for NETLINK */
47d4fb1e02SRoy Marples #define	PS_SCRIPT		0x0012
48d4fb1e02SRoy Marples #define	PS_UNLINK		0x0013
49d4fb1e02SRoy Marples #define	PS_READFILE		0x0014
50d4fb1e02SRoy Marples #define	PS_WRITEFILE		0x0015
51d4fb1e02SRoy Marples #define	PS_FILEMTIME		0x0016
52acd7a309SRoy Marples #define	PS_AUTH_MONORDM		0x0017
537f8103cdSRoy Marples #define	PS_CTL			0x0018
547f8103cdSRoy Marples #define	PS_CTL_EOF		0x0019
5539994b17SRoy Marples #define	PS_LOGREOPEN		0x0020
566e63cc1fSRoy Marples 
576e63cc1fSRoy Marples /* BSD Commands */
58d4fb1e02SRoy Marples #define	PS_IOCTLLINK		0x0101
59d4fb1e02SRoy Marples #define	PS_IOCTL6		0x0102
60d4fb1e02SRoy Marples #define	PS_IOCTLINDIRECT	0x0103
61d4fb1e02SRoy Marples #define	PS_IP6FORWARDING	0x0104
62d4fb1e02SRoy Marples #define	PS_GETIFADDRS		0x0105
637f8103cdSRoy Marples #define	PS_IFIGNOREGRP		0x0106
646e63cc1fSRoy Marples 
65d4fb1e02SRoy Marples /* Dev Commands */
667f8103cdSRoy Marples #define	PS_DEV_LISTENING	0x1001
677f8103cdSRoy Marples #define	PS_DEV_INITTED		0x1002
687f8103cdSRoy Marples #define	PS_DEV_IFCMD		0x1003
696e63cc1fSRoy Marples 
70d4fb1e02SRoy Marples /* Dev Interface Commands (via flags) */
71d4fb1e02SRoy Marples #define	PS_DEV_IFADDED		0x0001
72d4fb1e02SRoy Marples #define	PS_DEV_IFREMOVED	0x0002
73d4fb1e02SRoy Marples #define	PS_DEV_IFUPDATED	0x0003
74d4fb1e02SRoy Marples 
757f8103cdSRoy Marples /* Control Type (via flags) */
767f8103cdSRoy Marples #define	PS_CTL_PRIV		0x0004
777f8103cdSRoy Marples #define	PS_CTL_UNPRIV		0x0005
787f8103cdSRoy Marples 
79d4fb1e02SRoy Marples /* Process commands */
80d4fb1e02SRoy Marples #define	PS_START		0x4000
81d4fb1e02SRoy Marples #define	PS_STOP			0x8000
826e63cc1fSRoy Marples 
836e63cc1fSRoy Marples /* Max INET message size + meta data for IPC */
846e63cc1fSRoy Marples #define	PS_BUFLEN		((64 * 1024) +			\
856e63cc1fSRoy Marples 				 sizeof(struct ps_msghdr) +	\
866e63cc1fSRoy Marples 				 sizeof(struct msghdr) +	\
876e63cc1fSRoy Marples 				 CMSG_SPACE(sizeof(struct in6_pktinfo) + \
886e63cc1fSRoy Marples 					    sizeof(int)))
896e63cc1fSRoy Marples 
906e63cc1fSRoy Marples /* Handy macro to work out if in the privsep engine or not. */
916e63cc1fSRoy Marples #define	IN_PRIVSEP(ctx)	\
926e63cc1fSRoy Marples 	((ctx)->options & DHCPCD_PRIVSEP)
936e63cc1fSRoy Marples #define	IN_PRIVSEP_SE(ctx)	\
946e63cc1fSRoy Marples 	(((ctx)->options & (DHCPCD_PRIVSEP | DHCPCD_FORKED)) == DHCPCD_PRIVSEP)
956e63cc1fSRoy Marples 
967f8103cdSRoy Marples #if defined(PRIVSEP) && defined(HAVE_CAPSICUM)
977f8103cdSRoy Marples #define PRIVSEP_RIGHTS
987f8103cdSRoy Marples #endif
997f8103cdSRoy Marples 
100a0d9933aSRoy Marples #ifdef __linux__
101a0d9933aSRoy Marples # include <linux/version.h>
102a0d9933aSRoy Marples # if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
103a0d9933aSRoy Marples #  define HAVE_SECCOMP
104a0d9933aSRoy Marples # endif
105a0d9933aSRoy Marples #endif
106a0d9933aSRoy Marples 
1076e63cc1fSRoy Marples #include "config.h"
1086e63cc1fSRoy Marples #include "arp.h"
1096e63cc1fSRoy Marples #include "dhcp.h"
1106e63cc1fSRoy Marples #include "dhcpcd.h"
1116e63cc1fSRoy Marples 
1126e63cc1fSRoy Marples struct ps_addr {
1136e63cc1fSRoy Marples 	sa_family_t psa_family;
1146e63cc1fSRoy Marples 	uint8_t psa_pad[4 - sizeof(sa_family_t)];
1156e63cc1fSRoy Marples 	union {
1166e63cc1fSRoy Marples 		struct in_addr psau_in_addr;
1176e63cc1fSRoy Marples 		struct in6_addr psau_in6_addr;
1186e63cc1fSRoy Marples 	} psa_u;
1196e63cc1fSRoy Marples #define	psa_in_addr	psa_u.psau_in_addr
1206e63cc1fSRoy Marples #define	psa_in6_addr	psa_u.psau_in6_addr
1216e63cc1fSRoy Marples };
1226e63cc1fSRoy Marples 
1236e63cc1fSRoy Marples /* Uniquely identify a process */
1246e63cc1fSRoy Marples struct ps_id {
1256e63cc1fSRoy Marples 	struct ps_addr psi_addr;
1266e63cc1fSRoy Marples 	unsigned int psi_ifindex;
127d4fb1e02SRoy Marples 	uint16_t psi_cmd;
128d4fb1e02SRoy Marples 	uint8_t psi_pad[2];
1296e63cc1fSRoy Marples };
1306e63cc1fSRoy Marples 
1316e63cc1fSRoy Marples struct ps_msghdr {
132d4fb1e02SRoy Marples 	uint16_t ps_cmd;
133d4fb1e02SRoy Marples 	uint8_t ps_pad[sizeof(unsigned long) - sizeof(uint16_t)];
1346e63cc1fSRoy Marples 	unsigned long ps_flags;
1356e63cc1fSRoy Marples 	struct ps_id ps_id;
1366e63cc1fSRoy Marples 	socklen_t ps_namelen;
1376e63cc1fSRoy Marples 	socklen_t ps_controllen;
1386e63cc1fSRoy Marples 	uint8_t ps_pad2[sizeof(size_t) - sizeof(socklen_t)];
1396e63cc1fSRoy Marples 	size_t ps_datalen;
1406e63cc1fSRoy Marples };
1416e63cc1fSRoy Marples 
1426e63cc1fSRoy Marples struct ps_msg {
1436e63cc1fSRoy Marples 	struct ps_msghdr psm_hdr;
1446e63cc1fSRoy Marples 	uint8_t psm_data[PS_BUFLEN];
1456e63cc1fSRoy Marples };
1466e63cc1fSRoy Marples 
147d4fb1e02SRoy Marples struct bpf;
1486e63cc1fSRoy Marples struct ps_process {
1496e63cc1fSRoy Marples 	TAILQ_ENTRY(ps_process) next;
1506e63cc1fSRoy Marples 	struct dhcpcd_ctx *psp_ctx;
1516e63cc1fSRoy Marples 	struct ps_id psp_id;
1526e63cc1fSRoy Marples 	pid_t psp_pid;
1536e63cc1fSRoy Marples 	int psp_fd;
1546e63cc1fSRoy Marples 	int psp_work_fd;
1556e63cc1fSRoy Marples 	unsigned int psp_ifindex;
1566e63cc1fSRoy Marples 	char psp_ifname[IF_NAMESIZE];
1576e63cc1fSRoy Marples 	uint16_t psp_proto;
1586e63cc1fSRoy Marples 	const char *psp_protostr;
1596e63cc1fSRoy Marples 
1606e63cc1fSRoy Marples #ifdef INET
161d4fb1e02SRoy Marples 	int (*psp_filter)(const struct bpf *, const struct in_addr *);
1626e63cc1fSRoy Marples 	struct interface psp_ifp; /* Move BPF gubbins elsewhere */
163d4fb1e02SRoy Marples 	struct bpf *psp_bpf;
1646e63cc1fSRoy Marples #endif
1656e63cc1fSRoy Marples };
1666e63cc1fSRoy Marples TAILQ_HEAD(ps_process_head, ps_process);
1676e63cc1fSRoy Marples 
1687f8103cdSRoy Marples #include "privsep-control.h"
1696e63cc1fSRoy Marples #include "privsep-inet.h"
1706e63cc1fSRoy Marples #include "privsep-root.h"
1716e63cc1fSRoy Marples #ifdef INET
1726e63cc1fSRoy Marples #include "privsep-bpf.h"
1736e63cc1fSRoy Marples #endif
1746e63cc1fSRoy Marples 
1756e63cc1fSRoy Marples int ps_init(struct dhcpcd_ctx *);
1766e63cc1fSRoy Marples int ps_start(struct dhcpcd_ctx *);
1776e63cc1fSRoy Marples int ps_stop(struct dhcpcd_ctx *);
178a0d9933aSRoy Marples int ps_entersandbox(const char *, const char **);
1790a68f8d2SRoy Marples int ps_managersandbox(struct dhcpcd_ctx *, const char *);
1806e63cc1fSRoy Marples 
1816e63cc1fSRoy Marples int ps_unrollmsg(struct msghdr *, struct ps_msghdr *, const void *, size_t);
1826e63cc1fSRoy Marples ssize_t ps_sendpsmmsg(struct dhcpcd_ctx *, int,
1836e63cc1fSRoy Marples     struct ps_msghdr *, const struct msghdr *);
1846e63cc1fSRoy Marples ssize_t ps_sendpsmdata(struct dhcpcd_ctx *, int,
1856e63cc1fSRoy Marples     struct ps_msghdr *, const void *, size_t);
186d4fb1e02SRoy Marples ssize_t ps_sendmsg(struct dhcpcd_ctx *, int, uint16_t, unsigned long,
1876e63cc1fSRoy Marples     const struct msghdr *);
188d4fb1e02SRoy Marples ssize_t ps_sendcmd(struct dhcpcd_ctx *, int, uint16_t, unsigned long,
1896e63cc1fSRoy Marples     const void *data, size_t len);
190d4fb1e02SRoy Marples ssize_t ps_recvmsg(struct dhcpcd_ctx *, int, uint16_t, int);
1916e63cc1fSRoy Marples ssize_t ps_recvpsmsg(struct dhcpcd_ctx *, int,
1926e63cc1fSRoy Marples     ssize_t (*callback)(void *, struct ps_msghdr *, struct msghdr *), void *);
1936e63cc1fSRoy Marples 
1946e63cc1fSRoy Marples /* Internal privsep functions. */
1957f8103cdSRoy Marples int ps_setbuf_fdpair(int []);
196a0d9933aSRoy Marples 
1977f8103cdSRoy Marples #ifdef PRIVSEP_RIGHTS
1987f8103cdSRoy Marples int ps_rights_limit_ioctl(int);
1997f8103cdSRoy Marples int ps_rights_limit_fd_fctnl(int);
2007f8103cdSRoy Marples int ps_rights_limit_fd_rdonly(int);
201a0d9933aSRoy Marples int ps_rights_limit_fd_sockopt(int);
2027f8103cdSRoy Marples int ps_rights_limit_fd(int);
2037f8103cdSRoy Marples int ps_rights_limit_fdpair(int []);
2047f8103cdSRoy Marples #endif
205a0d9933aSRoy Marples 
206a0d9933aSRoy Marples #ifdef HAVE_SECCOMP
207a0d9933aSRoy Marples int ps_seccomp_enter(void);
208a0d9933aSRoy Marples #endif
209a0d9933aSRoy Marples 
2106e63cc1fSRoy Marples pid_t ps_dostart(struct dhcpcd_ctx * ctx,
2116e63cc1fSRoy Marples     pid_t *priv_pid, int *priv_fd,
2126e63cc1fSRoy Marples     void (*recv_msg)(void *), void (*recv_unpriv_msg),
2136e63cc1fSRoy Marples     void *recv_ctx, int (*callback)(void *), void (*)(int, void *),
2146e63cc1fSRoy Marples     unsigned int);
2156e63cc1fSRoy Marples int ps_dostop(struct dhcpcd_ctx *ctx, pid_t *pid, int *fd);
2166e63cc1fSRoy Marples 
2176e63cc1fSRoy Marples struct ps_process *ps_findprocess(struct dhcpcd_ctx *, struct ps_id *);
2186e63cc1fSRoy Marples struct ps_process *ps_newprocess(struct dhcpcd_ctx *, struct ps_id *);
2196e63cc1fSRoy Marples void ps_freeprocess(struct ps_process *);
2206e63cc1fSRoy Marples void ps_freeprocesses(struct dhcpcd_ctx *, struct ps_process *);
2216e63cc1fSRoy Marples #endif
222