xref: /freebsd/contrib/xz/src/common/my_landlock.h (revision 128836d304d93f2d00eb14069c27089ab46c38d4)
1*128836d3SXin LI // SPDX-License-Identifier: 0BSD
2*128836d3SXin LI 
3*128836d3SXin LI ///////////////////////////////////////////////////////////////////////////////
4*128836d3SXin LI //
5*128836d3SXin LI /// \file       my_landlock.h
6*128836d3SXin LI /// \brief      Linux Landlock sandbox helper functions
7*128836d3SXin LI //
8*128836d3SXin LI //  Author:     Lasse Collin
9*128836d3SXin LI //
10*128836d3SXin LI ///////////////////////////////////////////////////////////////////////////////
11*128836d3SXin LI 
12*128836d3SXin LI #ifndef MY_LANDLOCK_H
13*128836d3SXin LI #define MY_LANDLOCK_H
14*128836d3SXin LI 
15*128836d3SXin LI #include "sysdefs.h"
16*128836d3SXin LI 
17*128836d3SXin LI #include <linux/landlock.h>
18*128836d3SXin LI #include <sys/syscall.h>
19*128836d3SXin LI #include <sys/prctl.h>
20*128836d3SXin LI 
21*128836d3SXin LI 
22*128836d3SXin LI /// \brief      Initialize Landlock ruleset attributes to forbid everything
23*128836d3SXin LI ///
24*128836d3SXin LI /// The supported Landlock ABI is checked at runtime and only the supported
25*128836d3SXin LI /// actions are forbidden in the attributes. Thus, if the attributes are
26*128836d3SXin LI /// used with my_landlock_create_ruleset(), it shouldn't fail.
27*128836d3SXin LI ///
28*128836d3SXin LI /// \return     On success, the Landlock ABI version is returned (a positive
29*128836d3SXin LI ///             integer). If Landlock isn't supported, -1 is returned.
30*128836d3SXin LI static int
my_landlock_ruleset_attr_forbid_all(struct landlock_ruleset_attr * attr)31*128836d3SXin LI my_landlock_ruleset_attr_forbid_all(struct landlock_ruleset_attr *attr)
32*128836d3SXin LI {
33*128836d3SXin LI 	memzero(attr, sizeof(*attr));
34*128836d3SXin LI 
35*128836d3SXin LI 	const int abi_version = syscall(SYS_landlock_create_ruleset,
36*128836d3SXin LI 			(void *)NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
37*128836d3SXin LI 	if (abi_version <= 0)
38*128836d3SXin LI 		return -1;
39*128836d3SXin LI 
40*128836d3SXin LI 	// ABI 1 except the few at the end
41*128836d3SXin LI 	attr->handled_access_fs
42*128836d3SXin LI 			= LANDLOCK_ACCESS_FS_EXECUTE
43*128836d3SXin LI 			| LANDLOCK_ACCESS_FS_WRITE_FILE
44*128836d3SXin LI 			| LANDLOCK_ACCESS_FS_READ_FILE
45*128836d3SXin LI 			| LANDLOCK_ACCESS_FS_READ_DIR
46*128836d3SXin LI 			| LANDLOCK_ACCESS_FS_REMOVE_DIR
47*128836d3SXin LI 			| LANDLOCK_ACCESS_FS_REMOVE_FILE
48*128836d3SXin LI 			| LANDLOCK_ACCESS_FS_MAKE_CHAR
49*128836d3SXin LI 			| LANDLOCK_ACCESS_FS_MAKE_DIR
50*128836d3SXin LI 			| LANDLOCK_ACCESS_FS_MAKE_REG
51*128836d3SXin LI 			| LANDLOCK_ACCESS_FS_MAKE_SOCK
52*128836d3SXin LI 			| LANDLOCK_ACCESS_FS_MAKE_FIFO
53*128836d3SXin LI 			| LANDLOCK_ACCESS_FS_MAKE_BLOCK
54*128836d3SXin LI 			| LANDLOCK_ACCESS_FS_MAKE_SYM
55*128836d3SXin LI #ifdef LANDLOCK_ACCESS_FS_REFER
56*128836d3SXin LI 			| LANDLOCK_ACCESS_FS_REFER // ABI 2
57*128836d3SXin LI #endif
58*128836d3SXin LI #ifdef LANDLOCK_ACCESS_FS_TRUNCATE
59*128836d3SXin LI 			| LANDLOCK_ACCESS_FS_TRUNCATE // ABI 3
60*128836d3SXin LI #endif
61*128836d3SXin LI #ifdef LANDLOCK_ACCESS_FS_IOCTL_DEV
62*128836d3SXin LI 			| LANDLOCK_ACCESS_FS_IOCTL_DEV // ABI 5
63*128836d3SXin LI #endif
64*128836d3SXin LI 			;
65*128836d3SXin LI 
66*128836d3SXin LI #ifdef LANDLOCK_ACCESS_NET_BIND_TCP
67*128836d3SXin LI 	// ABI 4
68*128836d3SXin LI 	attr->handled_access_net
69*128836d3SXin LI 			= LANDLOCK_ACCESS_NET_BIND_TCP
70*128836d3SXin LI 			| LANDLOCK_ACCESS_NET_CONNECT_TCP;
71*128836d3SXin LI #endif
72*128836d3SXin LI 
73*128836d3SXin LI #ifdef LANDLOCK_SCOPE_SIGNAL
74*128836d3SXin LI 	 // ABI 6
75*128836d3SXin LI 	 attr->scoped
76*128836d3SXin LI 			 = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET
77*128836d3SXin LI 			 | LANDLOCK_SCOPE_SIGNAL;
78*128836d3SXin LI #endif
79*128836d3SXin LI 
80*128836d3SXin LI 	// Disable flags that require a new ABI version.
81*128836d3SXin LI 	switch (abi_version) {
82*128836d3SXin LI 	case 1:
83*128836d3SXin LI #ifdef LANDLOCK_ACCESS_FS_REFER
84*128836d3SXin LI 		attr->handled_access_fs &= ~LANDLOCK_ACCESS_FS_REFER;
85*128836d3SXin LI #endif
86*128836d3SXin LI 		FALLTHROUGH;
87*128836d3SXin LI 
88*128836d3SXin LI 	case 2:
89*128836d3SXin LI #ifdef LANDLOCK_ACCESS_FS_TRUNCATE
90*128836d3SXin LI 		attr->handled_access_fs &= ~LANDLOCK_ACCESS_FS_TRUNCATE;
91*128836d3SXin LI #endif
92*128836d3SXin LI 		FALLTHROUGH;
93*128836d3SXin LI 
94*128836d3SXin LI 	case 3:
95*128836d3SXin LI #ifdef LANDLOCK_ACCESS_NET_BIND_TCP
96*128836d3SXin LI 		attr->handled_access_net = 0;
97*128836d3SXin LI #endif
98*128836d3SXin LI 		FALLTHROUGH;
99*128836d3SXin LI 
100*128836d3SXin LI 	case 4:
101*128836d3SXin LI #ifdef LANDLOCK_ACCESS_FS_IOCTL_DEV
102*128836d3SXin LI 		attr->handled_access_fs &= ~LANDLOCK_ACCESS_FS_IOCTL_DEV;
103*128836d3SXin LI #endif
104*128836d3SXin LI 		FALLTHROUGH;
105*128836d3SXin LI 
106*128836d3SXin LI 	case 5:
107*128836d3SXin LI #ifdef LANDLOCK_SCOPE_SIGNAL
108*128836d3SXin LI 		attr->scoped = 0;
109*128836d3SXin LI #endif
110*128836d3SXin LI 		FALLTHROUGH;
111*128836d3SXin LI 
112*128836d3SXin LI 	default:
113*128836d3SXin LI 		// We only know about the features of the ABIs 1-6.
114*128836d3SXin LI 		break;
115*128836d3SXin LI 	}
116*128836d3SXin LI 
117*128836d3SXin LI 	return abi_version;
118*128836d3SXin LI }
119*128836d3SXin LI 
120*128836d3SXin LI 
121*128836d3SXin LI /// \brief      Wrapper for the landlock_create_ruleset(2) syscall
122*128836d3SXin LI ///
123*128836d3SXin LI /// Syscall wrappers provide argument type checking.
124*128836d3SXin LI ///
125*128836d3SXin LI /// \note       Remember to call `prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)` too!
126*128836d3SXin LI static inline int
my_landlock_create_ruleset(const struct landlock_ruleset_attr * attr,size_t size,uint32_t flags)127*128836d3SXin LI my_landlock_create_ruleset(const struct landlock_ruleset_attr *attr,
128*128836d3SXin LI 		size_t size, uint32_t flags)
129*128836d3SXin LI {
130*128836d3SXin LI 	return syscall(SYS_landlock_create_ruleset, attr, size, flags);
131*128836d3SXin LI }
132*128836d3SXin LI 
133*128836d3SXin LI 
134*128836d3SXin LI /// \brief      Wrapper for the landlock_restrict_self(2) syscall
135*128836d3SXin LI static inline int
my_landlock_restrict_self(int ruleset_fd,uint32_t flags)136*128836d3SXin LI my_landlock_restrict_self(int ruleset_fd, uint32_t flags)
137*128836d3SXin LI {
138*128836d3SXin LI 	return syscall(SYS_landlock_restrict_self, ruleset_fd, flags);
139*128836d3SXin LI }
140*128836d3SXin LI 
141*128836d3SXin LI #endif
142