dmaengine: imx-sdma: Let the core do the device node validation
[linux/fpc-iii.git] / security / selinux / netlabel.c
blob6fd9954e1c085f7d9f1553cbf0fba417b3205354
1 /*
2 * SELinux NetLabel Support
4 * This file provides the necessary glue to tie NetLabel into the SELinux
5 * subsystem.
7 * Author: Paul Moore <paul@paul-moore.com>
9 */
12 * (c) Copyright Hewlett-Packard Development Company, L.P., 2007, 2008
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
22 * the GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program. If not, see <http://www.gnu.org/licenses/>.
29 #include <linux/spinlock.h>
30 #include <linux/rcupdate.h>
31 #include <linux/gfp.h>
32 #include <linux/ip.h>
33 #include <linux/ipv6.h>
34 #include <net/sock.h>
35 #include <net/netlabel.h>
36 #include <net/ip.h>
37 #include <net/ipv6.h>
39 #include "objsec.h"
40 #include "security.h"
41 #include "netlabel.h"
43 /**
44 * selinux_netlbl_sidlookup_cached - Cache a SID lookup
45 * @skb: the packet
46 * @secattr: the NetLabel security attributes
47 * @sid: the SID
49 * Description:
50 * Query the SELinux security server to lookup the correct SID for the given
51 * security attributes. If the query is successful, cache the result to speed
52 * up future lookups. Returns zero on success, negative values on failure.
55 static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,
56 u16 family,
57 struct netlbl_lsm_secattr *secattr,
58 u32 *sid)
60 int rc;
62 rc = security_netlbl_secattr_to_sid(&selinux_state, secattr, sid);
63 if (rc == 0 &&
64 (secattr->flags & NETLBL_SECATTR_CACHEABLE) &&
65 (secattr->flags & NETLBL_SECATTR_CACHE))
66 netlbl_cache_add(skb, family, secattr);
68 return rc;
71 /**
72 * selinux_netlbl_sock_genattr - Generate the NetLabel socket secattr
73 * @sk: the socket
75 * Description:
76 * Generate the NetLabel security attributes for a socket, making full use of
77 * the socket's attribute cache. Returns a pointer to the security attributes
78 * on success, NULL on failure.
81 static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk)
83 int rc;
84 struct sk_security_struct *sksec = sk->sk_security;
85 struct netlbl_lsm_secattr *secattr;
87 if (sksec->nlbl_secattr != NULL)
88 return sksec->nlbl_secattr;
90 secattr = netlbl_secattr_alloc(GFP_ATOMIC);
91 if (secattr == NULL)
92 return NULL;
93 rc = security_netlbl_sid_to_secattr(&selinux_state, sksec->sid,
94 secattr);
95 if (rc != 0) {
96 netlbl_secattr_free(secattr);
97 return NULL;
99 sksec->nlbl_secattr = secattr;
101 return secattr;
105 * selinux_netlbl_sock_getattr - Get the cached NetLabel secattr
106 * @sk: the socket
107 * @sid: the SID
109 * Query the socket's cached secattr and if the SID matches the cached value
110 * return the cache, otherwise return NULL.
113 static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr(
114 const struct sock *sk,
115 u32 sid)
117 struct sk_security_struct *sksec = sk->sk_security;
118 struct netlbl_lsm_secattr *secattr = sksec->nlbl_secattr;
120 if (secattr == NULL)
121 return NULL;
123 if ((secattr->flags & NETLBL_SECATTR_SECID) &&
124 (secattr->attr.secid == sid))
125 return secattr;
127 return NULL;
131 * selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache
133 * Description:
134 * Invalidate the NetLabel security attribute mapping cache.
137 void selinux_netlbl_cache_invalidate(void)
139 netlbl_cache_invalidate();
143 * selinux_netlbl_err - Handle a NetLabel packet error
144 * @skb: the packet
145 * @error: the error code
146 * @gateway: true if host is acting as a gateway, false otherwise
148 * Description:
149 * When a packet is dropped due to a call to avc_has_perm() pass the error
150 * code to the NetLabel subsystem so any protocol specific processing can be
151 * done. This is safe to call even if you are unsure if NetLabel labeling is
152 * present on the packet, NetLabel is smart enough to only act when it should.
155 void selinux_netlbl_err(struct sk_buff *skb, u16 family, int error, int gateway)
157 netlbl_skbuff_err(skb, family, error, gateway);
161 * selinux_netlbl_sk_security_free - Free the NetLabel fields
162 * @sksec: the sk_security_struct
164 * Description:
165 * Free all of the memory in the NetLabel fields of a sk_security_struct.
168 void selinux_netlbl_sk_security_free(struct sk_security_struct *sksec)
170 if (sksec->nlbl_secattr != NULL)
171 netlbl_secattr_free(sksec->nlbl_secattr);
175 * selinux_netlbl_sk_security_reset - Reset the NetLabel fields
176 * @sksec: the sk_security_struct
177 * @family: the socket family
179 * Description:
180 * Called when the NetLabel state of a sk_security_struct needs to be reset.
181 * The caller is responsible for all the NetLabel sk_security_struct locking.
184 void selinux_netlbl_sk_security_reset(struct sk_security_struct *sksec)
186 sksec->nlbl_state = NLBL_UNSET;
190 * selinux_netlbl_skbuff_getsid - Get the sid of a packet using NetLabel
191 * @skb: the packet
192 * @family: protocol family
193 * @type: NetLabel labeling protocol type
194 * @sid: the SID
196 * Description:
197 * Call the NetLabel mechanism to get the security attributes of the given
198 * packet and use those attributes to determine the correct context/SID to
199 * assign to the packet. Returns zero on success, negative values on failure.
202 int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
203 u16 family,
204 u32 *type,
205 u32 *sid)
207 int rc;
208 struct netlbl_lsm_secattr secattr;
210 if (!netlbl_enabled()) {
211 *sid = SECSID_NULL;
212 return 0;
215 netlbl_secattr_init(&secattr);
216 rc = netlbl_skbuff_getattr(skb, family, &secattr);
217 if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE)
218 rc = selinux_netlbl_sidlookup_cached(skb, family,
219 &secattr, sid);
220 else
221 *sid = SECSID_NULL;
222 *type = secattr.type;
223 netlbl_secattr_destroy(&secattr);
225 return rc;
229 * selinux_netlbl_skbuff_setsid - Set the NetLabel on a packet given a sid
230 * @skb: the packet
231 * @family: protocol family
232 * @sid: the SID
234 * Description
235 * Call the NetLabel mechanism to set the label of a packet using @sid.
236 * Returns zero on success, negative values on failure.
239 int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
240 u16 family,
241 u32 sid)
243 int rc;
244 struct netlbl_lsm_secattr secattr_storage;
245 struct netlbl_lsm_secattr *secattr = NULL;
246 struct sock *sk;
248 /* if this is a locally generated packet check to see if it is already
249 * being labeled by it's parent socket, if it is just exit */
250 sk = skb_to_full_sk(skb);
251 if (sk != NULL) {
252 struct sk_security_struct *sksec = sk->sk_security;
254 if (sksec->nlbl_state != NLBL_REQSKB)
255 return 0;
256 secattr = selinux_netlbl_sock_getattr(sk, sid);
258 if (secattr == NULL) {
259 secattr = &secattr_storage;
260 netlbl_secattr_init(secattr);
261 rc = security_netlbl_sid_to_secattr(&selinux_state, sid,
262 secattr);
263 if (rc != 0)
264 goto skbuff_setsid_return;
267 rc = netlbl_skbuff_setattr(skb, family, secattr);
269 skbuff_setsid_return:
270 if (secattr == &secattr_storage)
271 netlbl_secattr_destroy(secattr);
272 return rc;
276 * selinux_netlbl_sctp_assoc_request - Label an incoming sctp association.
277 * @ep: incoming association endpoint.
278 * @skb: the packet.
280 * Description:
281 * A new incoming connection is represented by @ep, ......
282 * Returns zero on success, negative values on failure.
285 int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep,
286 struct sk_buff *skb)
288 int rc;
289 struct netlbl_lsm_secattr secattr;
290 struct sk_security_struct *sksec = ep->base.sk->sk_security;
291 struct sockaddr_in addr4;
292 struct sockaddr_in6 addr6;
294 if (ep->base.sk->sk_family != PF_INET &&
295 ep->base.sk->sk_family != PF_INET6)
296 return 0;
298 netlbl_secattr_init(&secattr);
299 rc = security_netlbl_sid_to_secattr(&selinux_state,
300 ep->secid, &secattr);
301 if (rc != 0)
302 goto assoc_request_return;
304 /* Move skb hdr address info to a struct sockaddr and then call
305 * netlbl_conn_setattr().
307 if (ip_hdr(skb)->version == 4) {
308 addr4.sin_family = AF_INET;
309 addr4.sin_addr.s_addr = ip_hdr(skb)->saddr;
310 rc = netlbl_conn_setattr(ep->base.sk, (void *)&addr4, &secattr);
311 } else if (IS_ENABLED(CONFIG_IPV6) && ip_hdr(skb)->version == 6) {
312 addr6.sin6_family = AF_INET6;
313 addr6.sin6_addr = ipv6_hdr(skb)->saddr;
314 rc = netlbl_conn_setattr(ep->base.sk, (void *)&addr6, &secattr);
315 } else {
316 rc = -EAFNOSUPPORT;
319 if (rc == 0)
320 sksec->nlbl_state = NLBL_LABELED;
322 assoc_request_return:
323 netlbl_secattr_destroy(&secattr);
324 return rc;
328 * selinux_netlbl_inet_conn_request - Label an incoming stream connection
329 * @req: incoming connection request socket
331 * Description:
332 * A new incoming connection request is represented by @req, we need to label
333 * the new request_sock here and the stack will ensure the on-the-wire label
334 * will get preserved when a full sock is created once the connection handshake
335 * is complete. Returns zero on success, negative values on failure.
338 int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family)
340 int rc;
341 struct netlbl_lsm_secattr secattr;
343 if (family != PF_INET && family != PF_INET6)
344 return 0;
346 netlbl_secattr_init(&secattr);
347 rc = security_netlbl_sid_to_secattr(&selinux_state, req->secid,
348 &secattr);
349 if (rc != 0)
350 goto inet_conn_request_return;
351 rc = netlbl_req_setattr(req, &secattr);
352 inet_conn_request_return:
353 netlbl_secattr_destroy(&secattr);
354 return rc;
358 * selinux_netlbl_inet_csk_clone - Initialize the newly created sock
359 * @sk: the new sock
361 * Description:
362 * A new connection has been established using @sk, we've already labeled the
363 * socket via the request_sock struct in selinux_netlbl_inet_conn_request() but
364 * we need to set the NetLabel state here since we now have a sock structure.
367 void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family)
369 struct sk_security_struct *sksec = sk->sk_security;
371 if (family == PF_INET)
372 sksec->nlbl_state = NLBL_LABELED;
373 else
374 sksec->nlbl_state = NLBL_UNSET;
378 * selinux_netlbl_sctp_sk_clone - Copy state to the newly created sock
379 * @sk: current sock
380 * @newsk: the new sock
382 * Description:
383 * Called whenever a new socket is created by accept(2) or sctp_peeloff(3).
385 void selinux_netlbl_sctp_sk_clone(struct sock *sk, struct sock *newsk)
387 struct sk_security_struct *sksec = sk->sk_security;
388 struct sk_security_struct *newsksec = newsk->sk_security;
390 newsksec->nlbl_state = sksec->nlbl_state;
394 * selinux_netlbl_socket_post_create - Label a socket using NetLabel
395 * @sock: the socket to label
396 * @family: protocol family
398 * Description:
399 * Attempt to label a socket using the NetLabel mechanism using the given
400 * SID. Returns zero values on success, negative values on failure.
403 int selinux_netlbl_socket_post_create(struct sock *sk, u16 family)
405 int rc;
406 struct sk_security_struct *sksec = sk->sk_security;
407 struct netlbl_lsm_secattr *secattr;
409 if (family != PF_INET && family != PF_INET6)
410 return 0;
412 secattr = selinux_netlbl_sock_genattr(sk);
413 if (secattr == NULL)
414 return -ENOMEM;
415 rc = netlbl_sock_setattr(sk, family, secattr);
416 switch (rc) {
417 case 0:
418 sksec->nlbl_state = NLBL_LABELED;
419 break;
420 case -EDESTADDRREQ:
421 sksec->nlbl_state = NLBL_REQSKB;
422 rc = 0;
423 break;
426 return rc;
430 * selinux_netlbl_sock_rcv_skb - Do an inbound access check using NetLabel
431 * @sksec: the sock's sk_security_struct
432 * @skb: the packet
433 * @family: protocol family
434 * @ad: the audit data
436 * Description:
437 * Fetch the NetLabel security attributes from @skb and perform an access check
438 * against the receiving socket. Returns zero on success, negative values on
439 * error.
442 int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
443 struct sk_buff *skb,
444 u16 family,
445 struct common_audit_data *ad)
447 int rc;
448 u32 nlbl_sid;
449 u32 perm;
450 struct netlbl_lsm_secattr secattr;
452 if (!netlbl_enabled())
453 return 0;
455 netlbl_secattr_init(&secattr);
456 rc = netlbl_skbuff_getattr(skb, family, &secattr);
457 if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE)
458 rc = selinux_netlbl_sidlookup_cached(skb, family,
459 &secattr, &nlbl_sid);
460 else
461 nlbl_sid = SECINITSID_UNLABELED;
462 netlbl_secattr_destroy(&secattr);
463 if (rc != 0)
464 return rc;
466 switch (sksec->sclass) {
467 case SECCLASS_UDP_SOCKET:
468 perm = UDP_SOCKET__RECVFROM;
469 break;
470 case SECCLASS_TCP_SOCKET:
471 perm = TCP_SOCKET__RECVFROM;
472 break;
473 default:
474 perm = RAWIP_SOCKET__RECVFROM;
477 rc = avc_has_perm(&selinux_state,
478 sksec->sid, nlbl_sid, sksec->sclass, perm, ad);
479 if (rc == 0)
480 return 0;
482 if (nlbl_sid != SECINITSID_UNLABELED)
483 netlbl_skbuff_err(skb, family, rc, 0);
484 return rc;
488 * selinux_netlbl_option - Is this a NetLabel option
489 * @level: the socket level or protocol
490 * @optname: the socket option name
492 * Description:
493 * Returns true if @level and @optname refer to a NetLabel option.
494 * Helper for selinux_netlbl_socket_setsockopt().
496 static inline int selinux_netlbl_option(int level, int optname)
498 return (level == IPPROTO_IP && optname == IP_OPTIONS) ||
499 (level == IPPROTO_IPV6 && optname == IPV6_HOPOPTS);
503 * selinux_netlbl_socket_setsockopt - Do not allow users to remove a NetLabel
504 * @sock: the socket
505 * @level: the socket level or protocol
506 * @optname: the socket option name
508 * Description:
509 * Check the setsockopt() call and if the user is trying to replace the IP
510 * options on a socket and a NetLabel is in place for the socket deny the
511 * access; otherwise allow the access. Returns zero when the access is
512 * allowed, -EACCES when denied, and other negative values on error.
515 int selinux_netlbl_socket_setsockopt(struct socket *sock,
516 int level,
517 int optname)
519 int rc = 0;
520 struct sock *sk = sock->sk;
521 struct sk_security_struct *sksec = sk->sk_security;
522 struct netlbl_lsm_secattr secattr;
524 if (selinux_netlbl_option(level, optname) &&
525 (sksec->nlbl_state == NLBL_LABELED ||
526 sksec->nlbl_state == NLBL_CONNLABELED)) {
527 netlbl_secattr_init(&secattr);
528 lock_sock(sk);
529 /* call the netlabel function directly as we want to see the
530 * on-the-wire label that is assigned via the socket's options
531 * and not the cached netlabel/lsm attributes */
532 rc = netlbl_sock_getattr(sk, &secattr);
533 release_sock(sk);
534 if (rc == 0)
535 rc = -EACCES;
536 else if (rc == -ENOMSG)
537 rc = 0;
538 netlbl_secattr_destroy(&secattr);
541 return rc;
545 * selinux_netlbl_socket_connect_helper - Help label a client-side socket on
546 * connect
547 * @sk: the socket to label
548 * @addr: the destination address
550 * Description:
551 * Attempt to label a connected socket with NetLabel using the given address.
552 * Returns zero values on success, negative values on failure.
555 static int selinux_netlbl_socket_connect_helper(struct sock *sk,
556 struct sockaddr *addr)
558 int rc;
559 struct sk_security_struct *sksec = sk->sk_security;
560 struct netlbl_lsm_secattr *secattr;
562 /* connected sockets are allowed to disconnect when the address family
563 * is set to AF_UNSPEC, if that is what is happening we want to reset
564 * the socket */
565 if (addr->sa_family == AF_UNSPEC) {
566 netlbl_sock_delattr(sk);
567 sksec->nlbl_state = NLBL_REQSKB;
568 rc = 0;
569 return rc;
571 secattr = selinux_netlbl_sock_genattr(sk);
572 if (secattr == NULL) {
573 rc = -ENOMEM;
574 return rc;
576 rc = netlbl_conn_setattr(sk, addr, secattr);
577 if (rc == 0)
578 sksec->nlbl_state = NLBL_CONNLABELED;
580 return rc;
584 * selinux_netlbl_socket_connect_locked - Label a client-side socket on
585 * connect
586 * @sk: the socket to label
587 * @addr: the destination address
589 * Description:
590 * Attempt to label a connected socket that already has the socket locked
591 * with NetLabel using the given address.
592 * Returns zero values on success, negative values on failure.
595 int selinux_netlbl_socket_connect_locked(struct sock *sk,
596 struct sockaddr *addr)
598 struct sk_security_struct *sksec = sk->sk_security;
600 if (sksec->nlbl_state != NLBL_REQSKB &&
601 sksec->nlbl_state != NLBL_CONNLABELED)
602 return 0;
604 return selinux_netlbl_socket_connect_helper(sk, addr);
608 * selinux_netlbl_socket_connect - Label a client-side socket on connect
609 * @sk: the socket to label
610 * @addr: the destination address
612 * Description:
613 * Attempt to label a connected socket with NetLabel using the given address.
614 * Returns zero values on success, negative values on failure.
617 int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr)
619 int rc;
621 lock_sock(sk);
622 rc = selinux_netlbl_socket_connect_locked(sk, addr);
623 release_sock(sk);
625 return rc;