💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Upload › files › be4e446fa44a2281a88e0935eb7… captured on 2023-03-20 at 18:34:00. Gemini links have been rewritten to link to archived content

View Raw

More Information

➡️ Next capture (2023-09-08)

-=-=-=-=-=-=-

0 /* See LICENSE for license details. */

1 #include "sandbox.h"

2 #include <strings.h>

3 #include <unistd.h>

4 #include <stdio.h>

5

6 #ifndef NO_SANDBOX

7

8 #ifdef __illumos__

9 #include <priv.h>

10 #include <errno.h>

11

12 #define SANDBOXED

13 int

14 init_privs(const char **privs) {

15

16 int i = 0;

17

18 priv_set_t *pset;

19 if ((pset = priv_allocset()) == NULL) {

20 printf("priv_allocset: %s\n", strerror(errno));

21 return -1;

22 }

23 priv_emptyset(pset);

24 while (privs[i]) {

25 if (priv_addset(pset, privs[i]) != 0) {

26 printf("priv_addset: %s\n", strerror(errno));

27 return -1;

28 }

29 i++;

30 }

31 if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 ||

32 setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 ||

33 setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0) {

34 printf("setppriv: %s\n", strerror(errno));

35 return -1;

36 }

37 priv_freeset(pset);

38 return 0;

39 }

40

41 int

42 sandbox_start(const char* path)

43 {

44 if (!path) return -1;

45 const char* privs[] = {PRIV_NET_ACCESS, PRIV_FILE_WRITE, NULL};

46 if (init_privs(privs)) return -1;

47 return 0;

48 }

49 #endif

50

51 #ifdef __OpenBSD__

52 #define SANDBOXED

53 int

54 sandbox_start(const char* path)

55 {

56 unveil(path, "rwc");

57 unveil(NULL, NULL);

58 pledge("stdio inet rpath wpath cpath", NULL);

59 return 0;

60 }

61 #endif

62

63 #ifdef __linux__

64 #define SANDBOXED

65 #include <sys/syscall.h>

66 #include <unistd.h>

67 #include <stdio.h>

68 #include <fcntl.h>

69 #include <string.h>

70 #include <errno.h>

71 #include <stddef.h>

72 #include <stdint.h>

73 #include <sys/prctl.h>

74 #include <linux/seccomp.h>

75 #include <linux/filter.h>

76 #include <linux/unistd.h>

77 long syscall(long number, ...); /* fix warning */

78

79 #if ENABLE_LANDLOCK || \

80 (!defined(DISABLE_LANDLOCK) && __has_include(<linux/landlock.h>))

81 #include <linux/landlock.h>

82 #define ENABLE_LANDLOCK

83 #endif

84

85 #define SC_ALLOW_(nr) \

86 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, nr, 0, 1), \

87 BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)

88 #define SC_ALLOW(nr) \

89 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_##nr, 0, 1), \

90 BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)

91 #define SC_ALLOW_ARG(_nr, _arg, _val) \

92 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, (_nr), 0, 6), \

93 BPF_STMT(BPF_LD + BPF_W + BPF_ABS, \

94 offsetof(struct seccomp_data, args[(_arg)]) + SC_ARG_LO), \

95 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, \

96 ((_val) & 0xffffffff), 0, 3), \

97 BPF_STMT(BPF_LD + BPF_W + BPF_ABS, \

98 offsetof(struct seccomp_data, args[(_arg)]) + SC_ARG_HI), \

99 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, \

100 (((uint32_t)((uint64_t)(_val) >> 32)) & 0xffffffff), 0, 1), \

101 BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW), \

102 BPF_STMT(BPF_LD + BPF_W + BPF_ABS, \

103 offsetof(struct seccomp_data, nr))

104

105 struct sock_filter filter[] = {

106 BPF_STMT(BPF_LD | BPF_W | BPF_ABS,

107 (offsetof(struct seccomp_data, arch))),

108 BPF_STMT(BPF_LD | BPF_W | BPF_ABS,

109 (offsetof(struct seccomp_data, nr))),

110 SC_ALLOW(fstat),

111 SC_ALLOW(stat),

112 SC_ALLOW(setsockopt),

113 SC_ALLOW(accept),

114 SC_ALLOW(listen),

115 SC_ALLOW(bind),

116 SC_ALLOW(mkdir),

117 SC_ALLOW(read),

118 SC_ALLOW(write),

119 SC_ALLOW(readv),

120 SC_ALLOW(writev),

121 SC_ALLOW(creat),

122 SC_ALLOW(open),

123 SC_ALLOW(openat),

124 SC_ALLOW(ioctl),

125 SC_ALLOW(close),

126 SC_ALLOW(exit),

127 SC_ALLOW(exit_group),

128 SC_ALLOW(futex),

129 SC_ALLOW(newfstatat),

130 SC_ALLOW(fcntl),

131 SC_ALLOW(lseek),

132 SC_ALLOW(mprotect),

133 SC_ALLOW(pread64),

134 SC_ALLOW(sendto),

135 SC_ALLOW(recvfrom),

136 SC_ALLOW(socket),

137 SC_ALLOW(getsockopt),

138 SC_ALLOW(poll),

139 SC_ALLOW(mmap),

140 SC_ALLOW(munmap),

141 BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),

142 };

143

144 #ifdef ENABLE_LANDLOCK

145

146 static int

147 landlock_create_ruleset(const struct landlock_ruleset_attr *attr,

148 size_t size, uint32_t flags)

149 {

150 return syscall(__NR_landlock_create_ruleset, attr, size, flags);

151 }

152

153 static int

154 landlock_add_rule(int ruleset_fd, enum landlock_rule_type type,

155 const void *attr, uint32_t flags)

156 {

157 return syscall(__NR_landlock_add_rule, ruleset_fd, type, attr, flags);

158 }

159

160 static int

161 landlock_restrict_self(int ruleset_fd, __u32 flags)

162 {

163 return syscall(__NR_landlock_restrict_self, ruleset_fd, flags);

164 }

165

166 int

167 landlock_unveil(int landlock_fd, int fd, int perms)

168 {

169 int ret, err;

170 struct landlock_path_beneath_attr attr = {0};

171 attr.allowed_access = perms;

172 attr.parent_fd = fd;

173

174 ret = landlock_add_rule(landlock_fd,

175 LANDLOCK_RULE_PATH_BENEATH, &attr, 0);

176 err = errno;

177 close(attr.parent_fd);

178 errno = err;

179 return ret;

180 }

181

182 #include <fcntl.h>

183 int

184 landlock_unveil_path(int landlock_fd, const char* path, int perms)

185 {

186 int fd = open(path, 0);

187 if (fd < 0) return -1;

188 return landlock_unveil(landlock_fd, fd, perms);

189 }

190

191 int

192 landlock_init()

193 {

194 struct landlock_ruleset_attr attr = {0};

195 attr.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE |

196 LANDLOCK_ACCESS_FS_WRITE_FILE;

197 return landlock_create_ruleset(&attr, sizeof(attr), 0);

198 }

199

200 int

201 landlock_apply(int fd)

202 {

203 int ret = landlock_restrict_self(fd, 0);

204 int err = errno;

205 close(fd);

206 errno = err;

207 return ret;

208 }

209 #endif

210

211 int

212 sandbox_start(const char* path)

213 {

214 struct sock_fprog prog = {0};

215 int llfd, download;

216

217 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {

218 printf("PR_SET_NO_NEW_PRIVS failed\n");

219 return -1;

220 }

221 #ifdef ENABLE_LANDLOCK

222 llfd = landlock_init();

223 if (llfd < 0) {

224 printf("Failed to initialize landlock : %s\n",

225 strerror(errno));

226 printf("The filesystem won't be hidden from the program\n");

227 goto skip_landlock;

228 }

229 download = landlock_unveil_path(llfd, path,

230 LANDLOCK_ACCESS_FS_READ_FILE |

231 LANDLOCK_ACCESS_FS_WRITE_FILE);

232 if (download) {

233 printf("landlock, failed to unveil : %s\n", strerror(errno));

234 return -1;

235 }

236 if (landlock_apply(llfd)) {

237 printf("landlock, failed to restrict process : %s\n",

238 strerror(errno));

239 return -1;

240 }

241 skip_landlock:;

242 #endif

243 prog.len = (unsigned short)(sizeof(filter) / sizeof (filter[0])),

244 prog.filter = filter;

245 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0)) {

246 printf("Failed to enable seccomp\n");

247 return -1;

248 }

249 return 0;

250 }

251 #endif

252 #endif

253

254 #ifndef SANDBOXED

255 int

256 sandbox_start(const char* path)

257 {

258 if (!path) return 0;

259 printf("No sandbox available on your system\n");

260 return 0;

261 }

262 #endif

263