💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Vgmi › files › d09d5c04e379ebed65fbd53e3a2fd… captured on 2023-12-28 at 15:45:05. Gemini links have been rewritten to link to archived content

View Raw

More Information

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

Go Back

0 /*

1 * ISC License

2 * Copyright (c) 2023 RMF <rawmonk@firemail.cc>

3 */

4 #if defined (__linux__) && !defined (DISABLE_SANDBOX)

5 #include <linux/seccomp.h>

6 #define _DEFAULT_SOURCE

7 #include <sys/syscall.h>

8 #include <sys/resource.h>

9 #include <sys/prctl.h>

10 #include <stdio.h>

11 #include <stdint.h>

12 #include <unistd.h>

13 #include <errno.h>

14 #include <fcntl.h>

15 #include "macro.h"

16 #include "sandbox.h"

17 #include "storage.h"

18 #include "error.h"

19 #include "config.h"

20

21 #ifdef ENABLE_SECCOMP_FILTER

22 #include <linux/filter.h>

23 #include <stddef.h>

24

25 #define SC_ALLOW(nr) \

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

27 BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)

28

29 struct sock_filter filter[] = {

30 BPF_STMT(BPF_LD | BPF_W | BPF_ABS,

31 (offsetof(struct seccomp_data, arch))),

32 BPF_STMT(BPF_LD | BPF_W | BPF_ABS,

33 (offsetof(struct seccomp_data, nr))),

34 SC_ALLOW(readv),

35 SC_ALLOW(writev),

36 #ifdef __NR_open

37 SC_ALLOW(open),

38 #endif

39 SC_ALLOW(dup),

40 #ifdef __NR_dup2

41 SC_ALLOW(dup2),

42 #endif

43 SC_ALLOW(pipe2),

44 SC_ALLOW(recvmsg),

45 SC_ALLOW(getsockname),

46 SC_ALLOW(fstat),

47 #ifdef __NR_stat

48 SC_ALLOW(stat),

49 #endif

50 #ifdef __NR_pipe

51 SC_ALLOW(pipe),

52 #endif

53 SC_ALLOW(setsockopt),

54 SC_ALLOW(read),

55 SC_ALLOW(write),

56 SC_ALLOW(openat),

57 SC_ALLOW(close),

58 SC_ALLOW(exit),

59 SC_ALLOW(ioctl),

60 SC_ALLOW(exit_group),

61 SC_ALLOW(futex),

62 SC_ALLOW(sysinfo),

63 SC_ALLOW(brk),

64 SC_ALLOW(newfstatat),

65 SC_ALLOW(getpid),

66 SC_ALLOW(getrandom),

67 SC_ALLOW(mmap),

68 SC_ALLOW(fcntl),

69 SC_ALLOW(lseek),

70 SC_ALLOW(rt_sigaction),

71 SC_ALLOW(rt_sigprocmask),

72 SC_ALLOW(rt_sigreturn),

73 SC_ALLOW(mprotect),

74 SC_ALLOW(pread64),

75 SC_ALLOW(uname),

76 SC_ALLOW(ppoll),

77 SC_ALLOW(bind),

78 SC_ALLOW(sendto),

79 SC_ALLOW(recvfrom),

80 SC_ALLOW(socket),

81 SC_ALLOW(socketpair),

82 SC_ALLOW(connect),

83 SC_ALLOW(getsockopt),

84 #ifdef __NR_poll

85 SC_ALLOW(poll),

86 #endif

87 SC_ALLOW(clone),

88 #ifdef __NR_clone3

89 SC_ALLOW(clone3),

90 #endif

91 SC_ALLOW(clock_nanosleep),

92 SC_ALLOW(nanosleep),

93 SC_ALLOW(rseq),

94 SC_ALLOW(set_robust_list),

95 SC_ALLOW(munmap),

96 SC_ALLOW(madvise),

97 SC_ALLOW(mremap),

98 #ifdef __NR_select

99 SC_ALLOW(select),

100 #endif

101 SC_ALLOW(membarrier),

102 SC_ALLOW(sendmmsg),

103 #ifdef __NR_pselect6

104 SC_ALLOW(pselect6),

105 #endif

106 SC_ALLOW(getdents),

107 SC_ALLOW(getdents64),

108 SC_ALLOW(unlink),

109 SC_ALLOW(unlinkat),

110 BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),

111 };

112

113 int enable_seccomp() {

114 struct sock_fprog prog;

115 prog.len = (unsigned short)(sizeof(filter) / sizeof (filter[0]));

116 prog.filter = filter;

117 return prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0);

118 }

119 #endif

120

121 #ifdef HAS_LANDLOCK

122 #include <linux/landlock.h>

123

124 static int landlock_create_ruleset(

125 const struct landlock_ruleset_attr *attr,

126 size_t size, uint32_t flags) {

127 return syscall(SYS_landlock_create_ruleset, attr, size, flags);

128 }

129

130 static int landlock_add_rule(int ruleset_fd,

131 enum landlock_rule_type type,

132 const void *attr, uint32_t flags) {

133 return syscall(SYS_landlock_add_rule, ruleset_fd, type, attr, flags);

134 }

135

136 static int landlock_restrict_self(int ruleset_fd, __u32 flags) {

137 return syscall(SYS_landlock_restrict_self, ruleset_fd, flags);

138 }

139

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

141 {

142 int ret, err;

143 struct landlock_path_beneath_attr attr = {0};

144 attr.allowed_access = perms;

145 attr.parent_fd = fd;

146

147 ret = landlock_add_rule(landlock_fd, LANDLOCK_RULE_PATH_BENEATH,

148 &attr, 0);

149 err = errno;

150 close(attr.parent_fd);

151 errno = err;

152 return ret;

153 }

154

155 int landlock_unveil_path(int landlock_fd, const char* path, int perms) {

156 int fd = open(path, 0);

157 if (fd < 0) return -1;

158 return landlock_unveil(landlock_fd, fd, perms);

159 }

160

161 int landlock_init() {

162 struct landlock_ruleset_attr attr = {0};

163 attr.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE |

164 LANDLOCK_ACCESS_FS_READ_DIR |

165 LANDLOCK_ACCESS_FS_WRITE_FILE |

166 LANDLOCK_ACCESS_FS_MAKE_REG;

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

168 }

169

170 int landlock_apply(int fd)

171 {

172 int ret = landlock_restrict_self(fd, 0);

173 int err = errno;

174 close(fd);

175 errno = err;

176 return ret;

177 }

178 #endif

179

180 int sandbox_init() {

181

182 char path[2048], download_path[2048];

183 #ifdef HAS_LANDLOCK

184 int fd;

185 #endif

186 int ret;

187 struct rlimit limit;

188

189 if (!config.enableSandbox) return 0;

190

191 /* prevents from creating large file */

192 limit.rlim_max = limit.rlim_cur = config.maximumBodyLength;

193 if (setrlimit(RLIMIT_FSIZE, &limit))

194 return ERROR_SANDBOX_FAILURE;

195

196 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0))

197 return ERROR_SANDBOX_FAILURE;

198

199 if ((ret = storage_path(V(path)))) return ret;

200 if ((ret = storage_download_path(V(download_path)))) return ret;

201

202 #ifdef HAS_LANDLOCK

203 /* restrict filesystem access */

204 fd = landlock_init();

205 if (fd < 0) return ERROR_SANDBOX_FAILURE;

206 ret = landlock_unveil_path(fd, path,

207 LANDLOCK_ACCESS_FS_READ_FILE |

208 LANDLOCK_ACCESS_FS_WRITE_FILE |

209 LANDLOCK_ACCESS_FS_MAKE_REG);

210 ret |= landlock_unveil_path(fd, download_path,

211 LANDLOCK_ACCESS_FS_WRITE_FILE |

212 LANDLOCK_ACCESS_FS_MAKE_REG);

213 ret |= landlock_unveil_path(fd, "/etc/hosts",

214 LANDLOCK_ACCESS_FS_READ_FILE);

215 ret |= landlock_unveil_path(fd, "/etc/resolv.conf",

216 LANDLOCK_ACCESS_FS_READ_FILE);

217

218 if (ret) return ERROR_SANDBOX_FAILURE;

219

220 if (landlock_apply(fd)) return ERROR_SANDBOX_FAILURE;

221 #endif

222

223 #ifdef ENABLE_SECCOMP_FILTER

224 if (enable_seccomp()) return ERROR_SANDBOX_FAILURE;

225 #endif

226

227 return 0;

228 }

229

230 int sandbox_isolate() {

231 if (!config.enableSandbox) return 0;

232 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT))

233 return ERROR_SANDBOX_FAILURE;

234 return 0;

235 }

236

237 int sandbox_set_name(const char *name) {

238 if (prctl(PR_SET_NAME, name))

239 return ERROR_SANDBOX_FAILURE;

240 return 0;

241 }

242 #else

243 typedef int hide_warning;

244 #endif

245