net.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Landlock - Network management and hooks
  4. *
  5. * Copyright © 2022-2023 Huawei Tech. Co., Ltd.
  6. * Copyright © 2022-2025 Microsoft Corporation
  7. */
  8. #include <linux/in.h>
  9. #include <linux/lsm_audit.h>
  10. #include <linux/net.h>
  11. #include <linux/socket.h>
  12. #include <net/ipv6.h>
  13. #include "audit.h"
  14. #include "common.h"
  15. #include "cred.h"
  16. #include "limits.h"
  17. #include "net.h"
  18. #include "ruleset.h"
  19. int landlock_append_net_rule(struct landlock_ruleset *const ruleset,
  20. const u16 port, access_mask_t access_rights)
  21. {
  22. int err;
  23. const struct landlock_id id = {
  24. .key.data = (__force uintptr_t)htons(port),
  25. .type = LANDLOCK_KEY_NET_PORT,
  26. };
  27. BUILD_BUG_ON(sizeof(port) > sizeof(id.key.data));
  28. /* Transforms relative access rights to absolute ones. */
  29. access_rights |= LANDLOCK_MASK_ACCESS_NET &
  30. ~landlock_get_net_access_mask(ruleset, 0);
  31. mutex_lock(&ruleset->lock);
  32. err = landlock_insert_rule(ruleset, id, access_rights);
  33. mutex_unlock(&ruleset->lock);
  34. return err;
  35. }
  36. static int current_check_access_socket(struct socket *const sock,
  37. struct sockaddr *const address,
  38. const int addrlen,
  39. access_mask_t access_request)
  40. {
  41. __be16 port;
  42. struct layer_access_masks layer_masks = {};
  43. const struct landlock_rule *rule;
  44. struct landlock_id id = {
  45. .type = LANDLOCK_KEY_NET_PORT,
  46. };
  47. const struct access_masks masks = {
  48. .net = access_request,
  49. };
  50. const struct landlock_cred_security *const subject =
  51. landlock_get_applicable_subject(current_cred(), masks, NULL);
  52. struct lsm_network_audit audit_net = {};
  53. if (!subject)
  54. return 0;
  55. /* Checks for minimal header length to safely read sa_family. */
  56. if (addrlen < offsetofend(typeof(*address), sa_family))
  57. return -EINVAL;
  58. switch (address->sa_family) {
  59. case AF_UNSPEC:
  60. if (access_request == LANDLOCK_ACCESS_NET_CONNECT_TCP) {
  61. /*
  62. * Connecting to an address with AF_UNSPEC dissolves
  63. * the TCP association, which have the same effect as
  64. * closing the connection while retaining the socket
  65. * object (i.e., the file descriptor). As for dropping
  66. * privileges, closing connections is always allowed.
  67. *
  68. * For a TCP access control system, this request is
  69. * legitimate. Let the network stack handle potential
  70. * inconsistencies and return -EINVAL if needed.
  71. */
  72. return 0;
  73. } else if (access_request == LANDLOCK_ACCESS_NET_BIND_TCP) {
  74. /*
  75. * Binding to an AF_UNSPEC address is treated
  76. * differently by IPv4 and IPv6 sockets. The socket's
  77. * family may change under our feet due to
  78. * setsockopt(IPV6_ADDRFORM), but that's ok: we either
  79. * reject entirely or require
  80. * %LANDLOCK_ACCESS_NET_BIND_TCP for the given port, so
  81. * it cannot be used to bypass the policy.
  82. *
  83. * IPv4 sockets map AF_UNSPEC to AF_INET for
  84. * retrocompatibility for bind accesses, only if the
  85. * address is INADDR_ANY (cf. __inet_bind). IPv6
  86. * sockets always reject it.
  87. *
  88. * Checking the address is required to not wrongfully
  89. * return -EACCES instead of -EAFNOSUPPORT or -EINVAL.
  90. * We could return 0 and let the network stack handle
  91. * these checks, but it is safer to return a proper
  92. * error and test consistency thanks to kselftest.
  93. */
  94. if (sock->sk->__sk_common.skc_family == AF_INET) {
  95. const struct sockaddr_in *const sockaddr =
  96. (struct sockaddr_in *)address;
  97. if (addrlen < sizeof(struct sockaddr_in))
  98. return -EINVAL;
  99. if (sockaddr->sin_addr.s_addr !=
  100. htonl(INADDR_ANY))
  101. return -EAFNOSUPPORT;
  102. } else {
  103. if (addrlen < SIN6_LEN_RFC2133)
  104. return -EINVAL;
  105. else
  106. return -EAFNOSUPPORT;
  107. }
  108. } else {
  109. WARN_ON_ONCE(1);
  110. }
  111. /* Only for bind(AF_UNSPEC+INADDR_ANY) on IPv4 socket. */
  112. fallthrough;
  113. case AF_INET: {
  114. const struct sockaddr_in *addr4;
  115. if (addrlen < sizeof(struct sockaddr_in))
  116. return -EINVAL;
  117. addr4 = (struct sockaddr_in *)address;
  118. port = addr4->sin_port;
  119. if (access_request == LANDLOCK_ACCESS_NET_CONNECT_TCP) {
  120. audit_net.dport = port;
  121. audit_net.v4info.daddr = addr4->sin_addr.s_addr;
  122. } else if (access_request == LANDLOCK_ACCESS_NET_BIND_TCP) {
  123. audit_net.sport = port;
  124. audit_net.v4info.saddr = addr4->sin_addr.s_addr;
  125. } else {
  126. WARN_ON_ONCE(1);
  127. }
  128. break;
  129. }
  130. #if IS_ENABLED(CONFIG_IPV6)
  131. case AF_INET6: {
  132. const struct sockaddr_in6 *addr6;
  133. if (addrlen < SIN6_LEN_RFC2133)
  134. return -EINVAL;
  135. addr6 = (struct sockaddr_in6 *)address;
  136. port = addr6->sin6_port;
  137. if (access_request == LANDLOCK_ACCESS_NET_CONNECT_TCP) {
  138. audit_net.dport = port;
  139. audit_net.v6info.daddr = addr6->sin6_addr;
  140. } else if (access_request == LANDLOCK_ACCESS_NET_BIND_TCP) {
  141. audit_net.sport = port;
  142. audit_net.v6info.saddr = addr6->sin6_addr;
  143. } else {
  144. WARN_ON_ONCE(1);
  145. }
  146. break;
  147. }
  148. #endif /* IS_ENABLED(CONFIG_IPV6) */
  149. default:
  150. return 0;
  151. }
  152. /*
  153. * Checks sa_family consistency to not wrongfully return
  154. * -EACCES instead of -EINVAL. Valid sa_family changes are
  155. * only (from AF_INET or AF_INET6) to AF_UNSPEC.
  156. *
  157. * We could return 0 and let the network stack handle this
  158. * check, but it is safer to return a proper error and test
  159. * consistency thanks to kselftest.
  160. */
  161. if (address->sa_family != sock->sk->__sk_common.skc_family &&
  162. address->sa_family != AF_UNSPEC)
  163. return -EINVAL;
  164. id.key.data = (__force uintptr_t)port;
  165. BUILD_BUG_ON(sizeof(port) > sizeof(id.key.data));
  166. rule = landlock_find_rule(subject->domain, id);
  167. access_request = landlock_init_layer_masks(subject->domain,
  168. access_request, &layer_masks,
  169. LANDLOCK_KEY_NET_PORT);
  170. if (!access_request)
  171. return 0;
  172. if (landlock_unmask_layers(rule, &layer_masks))
  173. return 0;
  174. audit_net.family = address->sa_family;
  175. landlock_log_denial(subject,
  176. &(struct landlock_request){
  177. .type = LANDLOCK_REQUEST_NET_ACCESS,
  178. .audit.type = LSM_AUDIT_DATA_NET,
  179. .audit.u.net = &audit_net,
  180. .access = access_request,
  181. .layer_masks = &layer_masks,
  182. });
  183. return -EACCES;
  184. }
  185. static int hook_socket_bind(struct socket *const sock,
  186. struct sockaddr *const address, const int addrlen)
  187. {
  188. access_mask_t access_request;
  189. if (sk_is_tcp(sock->sk))
  190. access_request = LANDLOCK_ACCESS_NET_BIND_TCP;
  191. else
  192. return 0;
  193. return current_check_access_socket(sock, address, addrlen,
  194. access_request);
  195. }
  196. static int hook_socket_connect(struct socket *const sock,
  197. struct sockaddr *const address,
  198. const int addrlen)
  199. {
  200. access_mask_t access_request;
  201. if (sk_is_tcp(sock->sk))
  202. access_request = LANDLOCK_ACCESS_NET_CONNECT_TCP;
  203. else
  204. return 0;
  205. return current_check_access_socket(sock, address, addrlen,
  206. access_request);
  207. }
  208. static struct security_hook_list landlock_hooks[] __ro_after_init = {
  209. LSM_HOOK_INIT(socket_bind, hook_socket_bind),
  210. LSM_HOOK_INIT(socket_connect, hook_socket_connect),
  211. };
  212. __init void landlock_add_net_hooks(void)
  213. {
  214. security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks),
  215. &landlock_lsmid);
  216. }