common.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Landlock test helpers
  4. *
  5. * Copyright © 2017-2020 Mickaël Salaün <mic@digikod.net>
  6. * Copyright © 2019-2020 ANSSI
  7. * Copyright © 2021 Microsoft Corporation
  8. */
  9. #include <arpa/inet.h>
  10. #include <errno.h>
  11. #include <linux/landlock.h>
  12. #include <linux/securebits.h>
  13. #include <sys/capability.h>
  14. #include <sys/socket.h>
  15. #include <sys/syscall.h>
  16. #include <sys/types.h>
  17. #include <sys/un.h>
  18. #include <sys/wait.h>
  19. #include <unistd.h>
  20. #include "../kselftest_harness.h"
  21. #define TMP_DIR "tmp"
  22. #ifndef __maybe_unused
  23. #define __maybe_unused __attribute__((__unused__))
  24. #endif
  25. /* TEST_F_FORK() should not be used for new tests. */
  26. #define TEST_F_FORK(fixture_name, test_name) TEST_F(fixture_name, test_name)
  27. #ifndef landlock_create_ruleset
  28. static inline int
  29. landlock_create_ruleset(const struct landlock_ruleset_attr *const attr,
  30. const size_t size, const __u32 flags)
  31. {
  32. return syscall(__NR_landlock_create_ruleset, attr, size, flags);
  33. }
  34. #endif
  35. #ifndef landlock_add_rule
  36. static inline int landlock_add_rule(const int ruleset_fd,
  37. const enum landlock_rule_type rule_type,
  38. const void *const rule_attr,
  39. const __u32 flags)
  40. {
  41. return syscall(__NR_landlock_add_rule, ruleset_fd, rule_type, rule_attr,
  42. flags);
  43. }
  44. #endif
  45. #ifndef landlock_restrict_self
  46. static inline int landlock_restrict_self(const int ruleset_fd,
  47. const __u32 flags)
  48. {
  49. return syscall(__NR_landlock_restrict_self, ruleset_fd, flags);
  50. }
  51. #endif
  52. static void _init_caps(struct __test_metadata *const _metadata, bool drop_all)
  53. {
  54. cap_t cap_p;
  55. /* Only these three capabilities are useful for the tests. */
  56. const cap_value_t caps[] = {
  57. /* clang-format off */
  58. CAP_DAC_OVERRIDE,
  59. CAP_MKNOD,
  60. CAP_NET_ADMIN,
  61. CAP_NET_BIND_SERVICE,
  62. CAP_SETUID,
  63. CAP_SYS_ADMIN,
  64. CAP_SYS_CHROOT,
  65. /* clang-format on */
  66. };
  67. const unsigned int noroot = SECBIT_NOROOT | SECBIT_NOROOT_LOCKED;
  68. if ((cap_get_secbits() & noroot) != noroot)
  69. EXPECT_EQ(0, cap_set_secbits(noroot));
  70. cap_p = cap_get_proc();
  71. EXPECT_NE(NULL, cap_p);
  72. EXPECT_NE(-1, cap_clear(cap_p));
  73. if (!drop_all) {
  74. EXPECT_NE(-1, cap_set_flag(cap_p, CAP_PERMITTED,
  75. ARRAY_SIZE(caps), caps, CAP_SET));
  76. }
  77. /* Automatically resets ambient capabilities. */
  78. EXPECT_NE(-1, cap_set_proc(cap_p))
  79. {
  80. TH_LOG("Failed to set capabilities: %s", strerror(errno));
  81. }
  82. EXPECT_NE(-1, cap_free(cap_p));
  83. /* Quickly checks that ambient capabilities are cleared. */
  84. EXPECT_NE(-1, cap_get_ambient(caps[0]));
  85. }
  86. /* We cannot put such helpers in a library because of kselftest_harness.h . */
  87. static void __maybe_unused disable_caps(struct __test_metadata *const _metadata)
  88. {
  89. _init_caps(_metadata, false);
  90. }
  91. static void __maybe_unused drop_caps(struct __test_metadata *const _metadata)
  92. {
  93. _init_caps(_metadata, true);
  94. }
  95. static void _change_cap(struct __test_metadata *const _metadata,
  96. const cap_flag_t flag, const cap_value_t cap,
  97. const cap_flag_value_t value)
  98. {
  99. cap_t cap_p;
  100. cap_p = cap_get_proc();
  101. EXPECT_NE(NULL, cap_p);
  102. EXPECT_NE(-1, cap_set_flag(cap_p, flag, 1, &cap, value));
  103. EXPECT_NE(-1, cap_set_proc(cap_p))
  104. {
  105. TH_LOG("Failed to set capability %d: %s", cap, strerror(errno));
  106. }
  107. EXPECT_NE(-1, cap_free(cap_p));
  108. }
  109. static void __maybe_unused set_cap(struct __test_metadata *const _metadata,
  110. const cap_value_t cap)
  111. {
  112. _change_cap(_metadata, CAP_EFFECTIVE, cap, CAP_SET);
  113. }
  114. static void __maybe_unused clear_cap(struct __test_metadata *const _metadata,
  115. const cap_value_t cap)
  116. {
  117. _change_cap(_metadata, CAP_EFFECTIVE, cap, CAP_CLEAR);
  118. }
  119. static void __maybe_unused
  120. set_ambient_cap(struct __test_metadata *const _metadata, const cap_value_t cap)
  121. {
  122. _change_cap(_metadata, CAP_INHERITABLE, cap, CAP_SET);
  123. EXPECT_NE(-1, cap_set_ambient(cap, CAP_SET))
  124. {
  125. TH_LOG("Failed to set ambient capability %d: %s", cap,
  126. strerror(errno));
  127. }
  128. }
  129. static void __maybe_unused clear_ambient_cap(
  130. struct __test_metadata *const _metadata, const cap_value_t cap)
  131. {
  132. EXPECT_EQ(1, cap_get_ambient(cap));
  133. _change_cap(_metadata, CAP_INHERITABLE, cap, CAP_CLEAR);
  134. EXPECT_EQ(0, cap_get_ambient(cap));
  135. }
  136. /* Receives an FD from a UNIX socket. Returns the received FD, or -errno. */
  137. static int __maybe_unused recv_fd(int usock)
  138. {
  139. int fd_rx;
  140. union {
  141. /* Aligned ancillary data buffer. */
  142. char buf[CMSG_SPACE(sizeof(fd_rx))];
  143. struct cmsghdr _align;
  144. } cmsg_rx = {};
  145. char data = '\0';
  146. struct iovec io = {
  147. .iov_base = &data,
  148. .iov_len = sizeof(data),
  149. };
  150. struct msghdr msg = {
  151. .msg_iov = &io,
  152. .msg_iovlen = 1,
  153. .msg_control = &cmsg_rx.buf,
  154. .msg_controllen = sizeof(cmsg_rx.buf),
  155. };
  156. struct cmsghdr *cmsg;
  157. int res;
  158. res = recvmsg(usock, &msg, MSG_CMSG_CLOEXEC);
  159. if (res < 0)
  160. return -errno;
  161. cmsg = CMSG_FIRSTHDR(&msg);
  162. if (cmsg->cmsg_len != CMSG_LEN(sizeof(fd_rx)))
  163. return -EIO;
  164. memcpy(&fd_rx, CMSG_DATA(cmsg), sizeof(fd_rx));
  165. return fd_rx;
  166. }
  167. /* Sends an FD on a UNIX socket. Returns 0 on success or -errno. */
  168. static int __maybe_unused send_fd(int usock, int fd_tx)
  169. {
  170. union {
  171. /* Aligned ancillary data buffer. */
  172. char buf[CMSG_SPACE(sizeof(fd_tx))];
  173. struct cmsghdr _align;
  174. } cmsg_tx = {};
  175. char data_tx = '.';
  176. struct iovec io = {
  177. .iov_base = &data_tx,
  178. .iov_len = sizeof(data_tx),
  179. };
  180. struct msghdr msg = {
  181. .msg_iov = &io,
  182. .msg_iovlen = 1,
  183. .msg_control = &cmsg_tx.buf,
  184. .msg_controllen = sizeof(cmsg_tx.buf),
  185. };
  186. struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
  187. cmsg->cmsg_len = CMSG_LEN(sizeof(fd_tx));
  188. cmsg->cmsg_level = SOL_SOCKET;
  189. cmsg->cmsg_type = SCM_RIGHTS;
  190. memcpy(CMSG_DATA(cmsg), &fd_tx, sizeof(fd_tx));
  191. if (sendmsg(usock, &msg, 0) < 0)
  192. return -errno;
  193. return 0;
  194. }
  195. static void __maybe_unused
  196. enforce_ruleset(struct __test_metadata *const _metadata, const int ruleset_fd)
  197. {
  198. ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
  199. ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0))
  200. {
  201. TH_LOG("Failed to enforce ruleset: %s", strerror(errno));
  202. }
  203. }
  204. struct protocol_variant {
  205. int domain;
  206. int type;
  207. int protocol;
  208. };
  209. struct service_fixture {
  210. struct protocol_variant protocol;
  211. /* port is also stored in ipv4_addr.sin_port or ipv6_addr.sin6_port */
  212. unsigned short port;
  213. union {
  214. struct sockaddr_in ipv4_addr;
  215. struct sockaddr_in6 ipv6_addr;
  216. struct {
  217. struct sockaddr_un unix_addr;
  218. socklen_t unix_addr_len;
  219. };
  220. };
  221. };
  222. static pid_t __maybe_unused sys_gettid(void)
  223. {
  224. return syscall(__NR_gettid);
  225. }
  226. static void __maybe_unused set_unix_address(struct service_fixture *const srv,
  227. const unsigned short index)
  228. {
  229. srv->unix_addr.sun_family = AF_UNIX;
  230. sprintf(srv->unix_addr.sun_path,
  231. "_selftests-landlock-abstract-unix-tid%d-index%d", sys_gettid(),
  232. index);
  233. srv->unix_addr_len = SUN_LEN(&srv->unix_addr);
  234. srv->unix_addr.sun_path[0] = '\0';
  235. }