netlabel.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * SELinux NetLabel Support
  4. *
  5. * This file provides the necessary glue to tie NetLabel into the SELinux
  6. * subsystem.
  7. *
  8. * Author: Paul Moore <[email protected]>
  9. */
  10. /*
  11. * (c) Copyright Hewlett-Packard Development Company, L.P., 2007, 2008
  12. */
  13. #include <linux/spinlock.h>
  14. #include <linux/rcupdate.h>
  15. #include <linux/gfp.h>
  16. #include <linux/ip.h>
  17. #include <linux/ipv6.h>
  18. #include <net/sock.h>
  19. #include <net/netlabel.h>
  20. #include <net/ip.h>
  21. #include <net/ipv6.h>
  22. #include "objsec.h"
  23. #include "security.h"
  24. #include "netlabel.h"
  25. /**
  26. * selinux_netlbl_sidlookup_cached - Cache a SID lookup
  27. * @skb: the packet
  28. * @family: the packet's address family
  29. * @secattr: the NetLabel security attributes
  30. * @sid: the SID
  31. *
  32. * Description:
  33. * Query the SELinux security server to lookup the correct SID for the given
  34. * security attributes. If the query is successful, cache the result to speed
  35. * up future lookups. Returns zero on success, negative values on failure.
  36. *
  37. */
  38. static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,
  39. u16 family,
  40. struct netlbl_lsm_secattr *secattr,
  41. u32 *sid)
  42. {
  43. int rc;
  44. rc = security_netlbl_secattr_to_sid(&selinux_state, secattr, sid);
  45. if (rc == 0 &&
  46. (secattr->flags & NETLBL_SECATTR_CACHEABLE) &&
  47. (secattr->flags & NETLBL_SECATTR_CACHE))
  48. netlbl_cache_add(skb, family, secattr);
  49. return rc;
  50. }
  51. /**
  52. * selinux_netlbl_sock_genattr - Generate the NetLabel socket secattr
  53. * @sk: the socket
  54. *
  55. * Description:
  56. * Generate the NetLabel security attributes for a socket, making full use of
  57. * the socket's attribute cache. Returns a pointer to the security attributes
  58. * on success, NULL on failure.
  59. *
  60. */
  61. static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk)
  62. {
  63. int rc;
  64. struct sk_security_struct *sksec = sk->sk_security;
  65. struct netlbl_lsm_secattr *secattr;
  66. if (sksec->nlbl_secattr != NULL)
  67. return sksec->nlbl_secattr;
  68. secattr = netlbl_secattr_alloc(GFP_ATOMIC);
  69. if (secattr == NULL)
  70. return NULL;
  71. rc = security_netlbl_sid_to_secattr(&selinux_state, sksec->sid,
  72. secattr);
  73. if (rc != 0) {
  74. netlbl_secattr_free(secattr);
  75. return NULL;
  76. }
  77. sksec->nlbl_secattr = secattr;
  78. return secattr;
  79. }
  80. /**
  81. * selinux_netlbl_sock_getattr - Get the cached NetLabel secattr
  82. * @sk: the socket
  83. * @sid: the SID
  84. *
  85. * Query the socket's cached secattr and if the SID matches the cached value
  86. * return the cache, otherwise return NULL.
  87. *
  88. */
  89. static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr(
  90. const struct sock *sk,
  91. u32 sid)
  92. {
  93. struct sk_security_struct *sksec = sk->sk_security;
  94. struct netlbl_lsm_secattr *secattr = sksec->nlbl_secattr;
  95. if (secattr == NULL)
  96. return NULL;
  97. if ((secattr->flags & NETLBL_SECATTR_SECID) &&
  98. (secattr->attr.secid == sid))
  99. return secattr;
  100. return NULL;
  101. }
  102. /**
  103. * selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache
  104. *
  105. * Description:
  106. * Invalidate the NetLabel security attribute mapping cache.
  107. *
  108. */
  109. void selinux_netlbl_cache_invalidate(void)
  110. {
  111. netlbl_cache_invalidate();
  112. }
  113. /**
  114. * selinux_netlbl_err - Handle a NetLabel packet error
  115. * @skb: the packet
  116. * @family: the packet's address family
  117. * @error: the error code
  118. * @gateway: true if host is acting as a gateway, false otherwise
  119. *
  120. * Description:
  121. * When a packet is dropped due to a call to avc_has_perm() pass the error
  122. * code to the NetLabel subsystem so any protocol specific processing can be
  123. * done. This is safe to call even if you are unsure if NetLabel labeling is
  124. * present on the packet, NetLabel is smart enough to only act when it should.
  125. *
  126. */
  127. void selinux_netlbl_err(struct sk_buff *skb, u16 family, int error, int gateway)
  128. {
  129. netlbl_skbuff_err(skb, family, error, gateway);
  130. }
  131. /**
  132. * selinux_netlbl_sk_security_free - Free the NetLabel fields
  133. * @sksec: the sk_security_struct
  134. *
  135. * Description:
  136. * Free all of the memory in the NetLabel fields of a sk_security_struct.
  137. *
  138. */
  139. void selinux_netlbl_sk_security_free(struct sk_security_struct *sksec)
  140. {
  141. if (sksec->nlbl_secattr != NULL)
  142. netlbl_secattr_free(sksec->nlbl_secattr);
  143. }
  144. /**
  145. * selinux_netlbl_sk_security_reset - Reset the NetLabel fields
  146. * @sksec: the sk_security_struct
  147. *
  148. * Description:
  149. * Called when the NetLabel state of a sk_security_struct needs to be reset.
  150. * The caller is responsible for all the NetLabel sk_security_struct locking.
  151. *
  152. */
  153. void selinux_netlbl_sk_security_reset(struct sk_security_struct *sksec)
  154. {
  155. sksec->nlbl_state = NLBL_UNSET;
  156. }
  157. /**
  158. * selinux_netlbl_skbuff_getsid - Get the sid of a packet using NetLabel
  159. * @skb: the packet
  160. * @family: protocol family
  161. * @type: NetLabel labeling protocol type
  162. * @sid: the SID
  163. *
  164. * Description:
  165. * Call the NetLabel mechanism to get the security attributes of the given
  166. * packet and use those attributes to determine the correct context/SID to
  167. * assign to the packet. Returns zero on success, negative values on failure.
  168. *
  169. */
  170. int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
  171. u16 family,
  172. u32 *type,
  173. u32 *sid)
  174. {
  175. int rc;
  176. struct netlbl_lsm_secattr secattr;
  177. if (!netlbl_enabled()) {
  178. *sid = SECSID_NULL;
  179. return 0;
  180. }
  181. netlbl_secattr_init(&secattr);
  182. rc = netlbl_skbuff_getattr(skb, family, &secattr);
  183. if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE)
  184. rc = selinux_netlbl_sidlookup_cached(skb, family,
  185. &secattr, sid);
  186. else
  187. *sid = SECSID_NULL;
  188. *type = secattr.type;
  189. netlbl_secattr_destroy(&secattr);
  190. return rc;
  191. }
  192. /**
  193. * selinux_netlbl_skbuff_setsid - Set the NetLabel on a packet given a sid
  194. * @skb: the packet
  195. * @family: protocol family
  196. * @sid: the SID
  197. *
  198. * Description
  199. * Call the NetLabel mechanism to set the label of a packet using @sid.
  200. * Returns zero on success, negative values on failure.
  201. *
  202. */
  203. int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
  204. u16 family,
  205. u32 sid)
  206. {
  207. int rc;
  208. struct netlbl_lsm_secattr secattr_storage;
  209. struct netlbl_lsm_secattr *secattr = NULL;
  210. struct sock *sk;
  211. /* if this is a locally generated packet check to see if it is already
  212. * being labeled by it's parent socket, if it is just exit */
  213. sk = skb_to_full_sk(skb);
  214. if (sk != NULL) {
  215. struct sk_security_struct *sksec = sk->sk_security;
  216. if (sksec->nlbl_state != NLBL_REQSKB)
  217. return 0;
  218. secattr = selinux_netlbl_sock_getattr(sk, sid);
  219. }
  220. if (secattr == NULL) {
  221. secattr = &secattr_storage;
  222. netlbl_secattr_init(secattr);
  223. rc = security_netlbl_sid_to_secattr(&selinux_state, sid,
  224. secattr);
  225. if (rc != 0)
  226. goto skbuff_setsid_return;
  227. }
  228. rc = netlbl_skbuff_setattr(skb, family, secattr);
  229. skbuff_setsid_return:
  230. if (secattr == &secattr_storage)
  231. netlbl_secattr_destroy(secattr);
  232. return rc;
  233. }
  234. /**
  235. * selinux_netlbl_sctp_assoc_request - Label an incoming sctp association.
  236. * @asoc: incoming association.
  237. * @skb: the packet.
  238. *
  239. * Description:
  240. * A new incoming connection is represented by @asoc, ......
  241. * Returns zero on success, negative values on failure.
  242. *
  243. */
  244. int selinux_netlbl_sctp_assoc_request(struct sctp_association *asoc,
  245. struct sk_buff *skb)
  246. {
  247. int rc;
  248. struct netlbl_lsm_secattr secattr;
  249. struct sk_security_struct *sksec = asoc->base.sk->sk_security;
  250. struct sockaddr_in addr4;
  251. struct sockaddr_in6 addr6;
  252. if (asoc->base.sk->sk_family != PF_INET &&
  253. asoc->base.sk->sk_family != PF_INET6)
  254. return 0;
  255. netlbl_secattr_init(&secattr);
  256. rc = security_netlbl_sid_to_secattr(&selinux_state,
  257. asoc->secid, &secattr);
  258. if (rc != 0)
  259. goto assoc_request_return;
  260. /* Move skb hdr address info to a struct sockaddr and then call
  261. * netlbl_conn_setattr().
  262. */
  263. if (ip_hdr(skb)->version == 4) {
  264. addr4.sin_family = AF_INET;
  265. addr4.sin_addr.s_addr = ip_hdr(skb)->saddr;
  266. rc = netlbl_conn_setattr(asoc->base.sk, (void *)&addr4, &secattr);
  267. } else if (IS_ENABLED(CONFIG_IPV6) && ip_hdr(skb)->version == 6) {
  268. addr6.sin6_family = AF_INET6;
  269. addr6.sin6_addr = ipv6_hdr(skb)->saddr;
  270. rc = netlbl_conn_setattr(asoc->base.sk, (void *)&addr6, &secattr);
  271. } else {
  272. rc = -EAFNOSUPPORT;
  273. }
  274. if (rc == 0)
  275. sksec->nlbl_state = NLBL_LABELED;
  276. assoc_request_return:
  277. netlbl_secattr_destroy(&secattr);
  278. return rc;
  279. }
  280. /**
  281. * selinux_netlbl_inet_conn_request - Label an incoming stream connection
  282. * @req: incoming connection request socket
  283. * @family: the request socket's address family
  284. *
  285. * Description:
  286. * A new incoming connection request is represented by @req, we need to label
  287. * the new request_sock here and the stack will ensure the on-the-wire label
  288. * will get preserved when a full sock is created once the connection handshake
  289. * is complete. Returns zero on success, negative values on failure.
  290. *
  291. */
  292. int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family)
  293. {
  294. int rc;
  295. struct netlbl_lsm_secattr secattr;
  296. if (family != PF_INET && family != PF_INET6)
  297. return 0;
  298. netlbl_secattr_init(&secattr);
  299. rc = security_netlbl_sid_to_secattr(&selinux_state, req->secid,
  300. &secattr);
  301. if (rc != 0)
  302. goto inet_conn_request_return;
  303. rc = netlbl_req_setattr(req, &secattr);
  304. inet_conn_request_return:
  305. netlbl_secattr_destroy(&secattr);
  306. return rc;
  307. }
  308. /**
  309. * selinux_netlbl_inet_csk_clone - Initialize the newly created sock
  310. * @sk: the new sock
  311. * @family: the sock's address family
  312. *
  313. * Description:
  314. * A new connection has been established using @sk, we've already labeled the
  315. * socket via the request_sock struct in selinux_netlbl_inet_conn_request() but
  316. * we need to set the NetLabel state here since we now have a sock structure.
  317. *
  318. */
  319. void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family)
  320. {
  321. struct sk_security_struct *sksec = sk->sk_security;
  322. if (family == PF_INET)
  323. sksec->nlbl_state = NLBL_LABELED;
  324. else
  325. sksec->nlbl_state = NLBL_UNSET;
  326. }
  327. /**
  328. * selinux_netlbl_sctp_sk_clone - Copy state to the newly created sock
  329. * @sk: current sock
  330. * @newsk: the new sock
  331. *
  332. * Description:
  333. * Called whenever a new socket is created by accept(2) or sctp_peeloff(3).
  334. */
  335. void selinux_netlbl_sctp_sk_clone(struct sock *sk, struct sock *newsk)
  336. {
  337. struct sk_security_struct *sksec = sk->sk_security;
  338. struct sk_security_struct *newsksec = newsk->sk_security;
  339. newsksec->nlbl_state = sksec->nlbl_state;
  340. }
  341. /**
  342. * selinux_netlbl_socket_post_create - Label a socket using NetLabel
  343. * @sk: the sock to label
  344. * @family: protocol family
  345. *
  346. * Description:
  347. * Attempt to label a socket using the NetLabel mechanism using the given
  348. * SID. Returns zero values on success, negative values on failure.
  349. *
  350. */
  351. int selinux_netlbl_socket_post_create(struct sock *sk, u16 family)
  352. {
  353. int rc;
  354. struct sk_security_struct *sksec = sk->sk_security;
  355. struct netlbl_lsm_secattr *secattr;
  356. if (family != PF_INET && family != PF_INET6)
  357. return 0;
  358. secattr = selinux_netlbl_sock_genattr(sk);
  359. if (secattr == NULL)
  360. return -ENOMEM;
  361. rc = netlbl_sock_setattr(sk, family, secattr);
  362. switch (rc) {
  363. case 0:
  364. sksec->nlbl_state = NLBL_LABELED;
  365. break;
  366. case -EDESTADDRREQ:
  367. sksec->nlbl_state = NLBL_REQSKB;
  368. rc = 0;
  369. break;
  370. }
  371. return rc;
  372. }
  373. /**
  374. * selinux_netlbl_sock_rcv_skb - Do an inbound access check using NetLabel
  375. * @sksec: the sock's sk_security_struct
  376. * @skb: the packet
  377. * @family: protocol family
  378. * @ad: the audit data
  379. *
  380. * Description:
  381. * Fetch the NetLabel security attributes from @skb and perform an access check
  382. * against the receiving socket. Returns zero on success, negative values on
  383. * error.
  384. *
  385. */
  386. int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
  387. struct sk_buff *skb,
  388. u16 family,
  389. struct common_audit_data *ad)
  390. {
  391. int rc;
  392. u32 nlbl_sid;
  393. u32 perm;
  394. struct netlbl_lsm_secattr secattr;
  395. if (!netlbl_enabled())
  396. return 0;
  397. netlbl_secattr_init(&secattr);
  398. rc = netlbl_skbuff_getattr(skb, family, &secattr);
  399. if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE)
  400. rc = selinux_netlbl_sidlookup_cached(skb, family,
  401. &secattr, &nlbl_sid);
  402. else
  403. nlbl_sid = SECINITSID_UNLABELED;
  404. netlbl_secattr_destroy(&secattr);
  405. if (rc != 0)
  406. return rc;
  407. switch (sksec->sclass) {
  408. case SECCLASS_UDP_SOCKET:
  409. perm = UDP_SOCKET__RECVFROM;
  410. break;
  411. case SECCLASS_TCP_SOCKET:
  412. perm = TCP_SOCKET__RECVFROM;
  413. break;
  414. default:
  415. perm = RAWIP_SOCKET__RECVFROM;
  416. }
  417. rc = avc_has_perm(&selinux_state,
  418. sksec->sid, nlbl_sid, sksec->sclass, perm, ad);
  419. if (rc == 0)
  420. return 0;
  421. if (nlbl_sid != SECINITSID_UNLABELED)
  422. netlbl_skbuff_err(skb, family, rc, 0);
  423. return rc;
  424. }
  425. /**
  426. * selinux_netlbl_option - Is this a NetLabel option
  427. * @level: the socket level or protocol
  428. * @optname: the socket option name
  429. *
  430. * Description:
  431. * Returns true if @level and @optname refer to a NetLabel option.
  432. * Helper for selinux_netlbl_socket_setsockopt().
  433. */
  434. static inline int selinux_netlbl_option(int level, int optname)
  435. {
  436. return (level == IPPROTO_IP && optname == IP_OPTIONS) ||
  437. (level == IPPROTO_IPV6 && optname == IPV6_HOPOPTS);
  438. }
  439. /**
  440. * selinux_netlbl_socket_setsockopt - Do not allow users to remove a NetLabel
  441. * @sock: the socket
  442. * @level: the socket level or protocol
  443. * @optname: the socket option name
  444. *
  445. * Description:
  446. * Check the setsockopt() call and if the user is trying to replace the IP
  447. * options on a socket and a NetLabel is in place for the socket deny the
  448. * access; otherwise allow the access. Returns zero when the access is
  449. * allowed, -EACCES when denied, and other negative values on error.
  450. *
  451. */
  452. int selinux_netlbl_socket_setsockopt(struct socket *sock,
  453. int level,
  454. int optname)
  455. {
  456. int rc = 0;
  457. struct sock *sk = sock->sk;
  458. struct sk_security_struct *sksec = sk->sk_security;
  459. struct netlbl_lsm_secattr secattr;
  460. if (selinux_netlbl_option(level, optname) &&
  461. (sksec->nlbl_state == NLBL_LABELED ||
  462. sksec->nlbl_state == NLBL_CONNLABELED)) {
  463. netlbl_secattr_init(&secattr);
  464. lock_sock(sk);
  465. /* call the netlabel function directly as we want to see the
  466. * on-the-wire label that is assigned via the socket's options
  467. * and not the cached netlabel/lsm attributes */
  468. rc = netlbl_sock_getattr(sk, &secattr);
  469. release_sock(sk);
  470. if (rc == 0)
  471. rc = -EACCES;
  472. else if (rc == -ENOMSG)
  473. rc = 0;
  474. netlbl_secattr_destroy(&secattr);
  475. }
  476. return rc;
  477. }
  478. /**
  479. * selinux_netlbl_socket_connect_helper - Help label a client-side socket on
  480. * connect
  481. * @sk: the socket to label
  482. * @addr: the destination address
  483. *
  484. * Description:
  485. * Attempt to label a connected socket with NetLabel using the given address.
  486. * Returns zero values on success, negative values on failure.
  487. *
  488. */
  489. static int selinux_netlbl_socket_connect_helper(struct sock *sk,
  490. struct sockaddr *addr)
  491. {
  492. int rc;
  493. struct sk_security_struct *sksec = sk->sk_security;
  494. struct netlbl_lsm_secattr *secattr;
  495. /* connected sockets are allowed to disconnect when the address family
  496. * is set to AF_UNSPEC, if that is what is happening we want to reset
  497. * the socket */
  498. if (addr->sa_family == AF_UNSPEC) {
  499. netlbl_sock_delattr(sk);
  500. sksec->nlbl_state = NLBL_REQSKB;
  501. rc = 0;
  502. return rc;
  503. }
  504. secattr = selinux_netlbl_sock_genattr(sk);
  505. if (secattr == NULL) {
  506. rc = -ENOMEM;
  507. return rc;
  508. }
  509. rc = netlbl_conn_setattr(sk, addr, secattr);
  510. if (rc == 0)
  511. sksec->nlbl_state = NLBL_CONNLABELED;
  512. return rc;
  513. }
  514. /**
  515. * selinux_netlbl_socket_connect_locked - Label a client-side socket on
  516. * connect
  517. * @sk: the socket to label
  518. * @addr: the destination address
  519. *
  520. * Description:
  521. * Attempt to label a connected socket that already has the socket locked
  522. * with NetLabel using the given address.
  523. * Returns zero values on success, negative values on failure.
  524. *
  525. */
  526. int selinux_netlbl_socket_connect_locked(struct sock *sk,
  527. struct sockaddr *addr)
  528. {
  529. struct sk_security_struct *sksec = sk->sk_security;
  530. if (sksec->nlbl_state != NLBL_REQSKB &&
  531. sksec->nlbl_state != NLBL_CONNLABELED)
  532. return 0;
  533. return selinux_netlbl_socket_connect_helper(sk, addr);
  534. }
  535. /**
  536. * selinux_netlbl_socket_connect - Label a client-side socket on connect
  537. * @sk: the socket to label
  538. * @addr: the destination address
  539. *
  540. * Description:
  541. * Attempt to label a connected socket with NetLabel using the given address.
  542. * Returns zero values on success, negative values on failure.
  543. *
  544. */
  545. int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr)
  546. {
  547. int rc;
  548. lock_sock(sk);
  549. rc = selinux_netlbl_socket_connect_locked(sk, addr);
  550. release_sock(sk);
  551. return rc;
  552. }