Go Back

0 /* See LICENSE file for copyright and license details. */

1

2 #ifdef __linux__

3 #include <sys/syscall.h>

4 #include <unistd.h>

5 #include <stdio.h>

6 #include <fcntl.h>

7 #include <string.h>

8 #include <errno.h>

9 #include <stddef.h>

10 #include <stdint.h>

11 #include <sys/prctl.h>

12 #include <linux/seccomp.h>

13 #include <linux/filter.h>

14 #include <linux/unistd.h>

15 #include "util.h"

16 #include "conf.h"

17

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

19

20 #if ENABLE_LANDLOCK || \

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

22 #include <linux/landlock.h>

23 #define ENABLE_LANDLOCK

24 #endif

25

26 #define SC_ALLOW_(nr) \

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

28 BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)

29 #define SC_ALLOW(nr) \

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

31 BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)

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

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

34 BPF_STMT(BPF_LD + BPF_W + BPF_ABS, \

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

36 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, \

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

38 BPF_STMT(BPF_LD + BPF_W + BPF_ABS, \

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

40 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, \

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

42 BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW), \

43 BPF_STMT(BPF_LD + BPF_W + BPF_ABS, \

44 offsetof(struct seccomp_data, nr))

45

46 struct sock_filter filter[] = {

47 BPF_STMT(BPF_LD | BPF_W | BPF_ABS,

48 (offsetof(struct seccomp_data, arch))),

49 BPF_STMT(BPF_LD | BPF_W | BPF_ABS,

50 (offsetof(struct seccomp_data, nr))),

51 SC_ALLOW(fstat),

52 SC_ALLOW(stat),

53 SC_ALLOW(setsockopt),

54 SC_ALLOW(accept),

55 SC_ALLOW(listen),

56 SC_ALLOW(bind),

57 SC_ALLOW(mkdir),

58 SC_ALLOW(read),

59 SC_ALLOW(write),

60 SC_ALLOW(readv),

61 SC_ALLOW(writev),

62 SC_ALLOW(creat),

63 SC_ALLOW(open),

64 SC_ALLOW(openat),

65 SC_ALLOW(ioctl),

66 SC_ALLOW(close),

67 SC_ALLOW(exit),

68 SC_ALLOW(exit_group),

69 SC_ALLOW(futex),

70 SC_ALLOW(newfstatat),

71 SC_ALLOW(fcntl),

72 SC_ALLOW(lseek),

73 SC_ALLOW(pread64),

74 SC_ALLOW(sendto),

75 SC_ALLOW(recvfrom),

76 SC_ALLOW(socket),

77 SC_ALLOW(getsockopt),

78 SC_ALLOW(poll),

79 SC_ALLOW(mmap),

80 SC_ALLOW(munmap),

81 SC_ALLOW(rt_sigaction),

82 SC_ALLOW(getpid),

83 SC_ALLOW(getrandom),

84 SC_ALLOW(brk),

85 SC_ALLOW(socketpair),

86 SC_ALLOW(mprotect),

87 SC_ALLOW(clone),

88 SC_ALLOW(clone3),

89 SC_ALLOW(set_robust_list),

90 SC_ALLOW(exit_group),

91 SC_ALLOW(connect),

92 SC_ALLOW(sched_getaffinity),

93 SC_ALLOW(rt_sigprocmask),

94 SC_ALLOW(rseq),

95 SC_ALLOW(uname),

96 SC_ALLOW(dup),

97 SC_ALLOW(writev),

98 SC_ALLOW(madvise),

99 BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),

100 };

101

102 #ifdef ENABLE_LANDLOCK

103

104 #include <fcntl.h>

105

106 static int landlock_create_ruleset(const struct landlock_ruleset_attr *attr,

107 size_t size, uint32_t flags) {

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

109 }

110

111 static int landlock_add_rule(int ruleset_fd, enum landlock_rule_type type,

112 const void *attr, uint32_t flags) {

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

114 }

115

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

117 return syscall(__NR_landlock_restrict_self, ruleset_fd, flags);

118 }

119

120 int landlock_unveil(int landlock_fd, int fd, int perms) {

121 int ret, err;

122 struct landlock_path_beneath_attr attr = {0};

123 attr.allowed_access = perms;

124 attr.parent_fd = fd;

125

126 ret = landlock_add_rule(landlock_fd,

127 LANDLOCK_RULE_PATH_BENEATH, &attr, 0);

128 err = errno;

129 close(attr.parent_fd);

130 errno = err;

131 return ret;

132 }

133

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

135 int fd = open(path, 0);

136 if (fd < 0) return -1;

137 return landlock_unveil(landlock_fd, fd, perms);

138 }

139

140 int landlock_init() {

141 struct landlock_ruleset_attr attr = {0};

142 attr.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE |

143 LANDLOCK_ACCESS_FS_WRITE_FILE;

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

145 }

146

147 int landlock_apply(int fd) {

148 int ret = landlock_restrict_self(fd, 0);

149 int err = errno;

150 close(fd);

151 errno = err;

152 return ret;

153 }

154 #endif

155

156 int sandbox() {

157

158 struct sock_fprog prog = {0};

159 #ifdef ENABLE_LANDLOCK

160 int llfd, fail;

161 #endif

162

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

164 printf("PR_SET_NO_NEW_PRIVS failed\n");

165 return -1;

166 }

167 #ifdef ENABLE_LANDLOCK

168 llfd = landlock_init();

169 if (llfd < 0) {

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

171 strerror(errno));

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

173 goto skip_landlock;

174 }

175 fail = 0;

176 fail |= landlock_unveil_path(llfd, conf.clients,

177 LANDLOCK_ACCESS_FS_READ_FILE |

178 LANDLOCK_ACCESS_FS_WRITE_FILE);

179 fail |= landlock_unveil_path(llfd, "/etc/resolv.conf",

180 LANDLOCK_ACCESS_FS_READ_FILE);

181 fail |= landlock_unveil_path(llfd, "/etc/hosts",

182 LANDLOCK_ACCESS_FS_READ_FILE);

183 if (fail) {

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

185 return -1;

186 }

187 if (landlock_apply(llfd)) {

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

189 strerror(errno));

190 return -1;

191 }

192 skip_landlock:;

193 #endif

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

195 prog.filter = filter;

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

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

198 return -1;

199 }

200 return 0;

201 }

202

203 #else

204 typedef int hide_warning;

205 #endif

206