aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPaul Moore <paul.moore@hp.com>2008-10-10 10:16:33 -0400
committerPaul Moore <paul.moore@hp.com>2008-10-10 10:16:33 -0400
commit014ab19a69c325f52d7bae54ceeda73d6307ae0c (patch)
tree8a69c490accb7d5454bdfeb8c078d846729aeb60 /net
parent948bf85c1bc9a84754786a9d5dd99b7ecc46451e (diff)
selinux: Set socket NetLabel based on connection endpoint
Previous work enabled the use of address based NetLabel selectors, which while highly useful, brought the potential for additional per-packet overhead when used. This patch attempts to solve that by applying NetLabel socket labels when sockets are connect()'d. This should alleviate the per-packet NetLabel labeling for all connected sockets (yes, it even works for connected DGRAM sockets). Signed-off-by: Paul Moore <paul.moore@hp.com> Reviewed-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/cipso_ipv4.c74
-rw-r--r--net/netlabel/netlabel_kapi.c78
2 files changed, 151 insertions, 1 deletions
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index e13d6dbb66ab..23768b9d6b64 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -1810,6 +1810,80 @@ socket_setattr_failure:
1810} 1810}
1811 1811
1812/** 1812/**
1813 * cipso_v4_sock_delattr - Delete the CIPSO option from a socket
1814 * @sk: the socket
1815 *
1816 * Description:
1817 * Removes the CIPSO option from a socket, if present.
1818 *
1819 */
1820void cipso_v4_sock_delattr(struct sock *sk)
1821{
1822 u8 hdr_delta;
1823 struct ip_options *opt;
1824 struct inet_sock *sk_inet;
1825
1826 sk_inet = inet_sk(sk);
1827 opt = sk_inet->opt;
1828 if (opt == NULL || opt->cipso == 0)
1829 return;
1830
1831 if (opt->srr || opt->rr || opt->ts || opt->router_alert) {
1832 u8 cipso_len;
1833 u8 cipso_off;
1834 unsigned char *cipso_ptr;
1835 int iter;
1836 int optlen_new;
1837
1838 cipso_off = opt->cipso - sizeof(struct iphdr);
1839 cipso_ptr = &opt->__data[cipso_off];
1840 cipso_len = cipso_ptr[1];
1841
1842 if (opt->srr > opt->cipso)
1843 opt->srr -= cipso_len;
1844 if (opt->rr > opt->cipso)
1845 opt->rr -= cipso_len;
1846 if (opt->ts > opt->cipso)
1847 opt->ts -= cipso_len;
1848 if (opt->router_alert > opt->cipso)
1849 opt->router_alert -= cipso_len;
1850 opt->cipso = 0;
1851
1852 memmove(cipso_ptr, cipso_ptr + cipso_len,
1853 opt->optlen - cipso_off - cipso_len);
1854
1855 /* determining the new total option length is tricky because of
1856 * the padding necessary, the only thing i can think to do at
1857 * this point is walk the options one-by-one, skipping the
1858 * padding at the end to determine the actual option size and
1859 * from there we can determine the new total option length */
1860 iter = 0;
1861 optlen_new = 0;
1862 while (iter < opt->optlen)
1863 if (opt->__data[iter] != IPOPT_NOP) {
1864 iter += opt->__data[iter + 1];
1865 optlen_new = iter;
1866 } else
1867 iter++;
1868 hdr_delta = opt->optlen;
1869 opt->optlen = (optlen_new + 3) & ~3;
1870 hdr_delta -= opt->optlen;
1871 } else {
1872 /* only the cipso option was present on the socket so we can
1873 * remove the entire option struct */
1874 sk_inet->opt = NULL;
1875 hdr_delta = opt->optlen;
1876 kfree(opt);
1877 }
1878
1879 if (sk_inet->is_icsk && hdr_delta > 0) {
1880 struct inet_connection_sock *sk_conn = inet_csk(sk);
1881 sk_conn->icsk_ext_hdr_len -= hdr_delta;
1882 sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie);
1883 }
1884}
1885
1886/**
1813 * cipso_v4_getattr - Helper function for the cipso_v4_*_getattr functions 1887 * cipso_v4_getattr - Helper function for the cipso_v4_*_getattr functions
1814 * @cipso: the CIPSO v4 option 1888 * @cipso: the CIPSO v4 option
1815 * @secattr: the security attributes 1889 * @secattr: the security attributes
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index cc8047d1f505..78fc557689b2 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12/* 12/*
13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
14 * 14 *
15 * This program is free software; you can redistribute it and/or modify 15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by 16 * it under the terms of the GNU General Public License as published by
@@ -456,6 +456,20 @@ socket_setattr_return:
456} 456}
457 457
458/** 458/**
459 * netlbl_sock_delattr - Delete all the NetLabel labels on a socket
460 * @sk: the socket
461 *
462 * Description:
463 * Remove all the NetLabel labeling from @sk. The caller is responsible for
464 * ensuring that @sk is locked.
465 *
466 */
467void netlbl_sock_delattr(struct sock *sk)
468{
469 cipso_v4_sock_delattr(sk);
470}
471
472/**
459 * netlbl_sock_getattr - Determine the security attributes of a sock 473 * netlbl_sock_getattr - Determine the security attributes of a sock
460 * @sk: the sock 474 * @sk: the sock
461 * @secattr: the security attributes 475 * @secattr: the security attributes
@@ -473,6 +487,68 @@ int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
473} 487}
474 488
475/** 489/**
490 * netlbl_conn_setattr - Label a connected socket using the correct protocol
491 * @sk: the socket to label
492 * @addr: the destination address
493 * @secattr: the security attributes
494 *
495 * Description:
496 * Attach the correct label to the given connected socket using the security
497 * attributes specified in @secattr. The caller is responsible for ensuring
498 * that @sk is locked. Returns zero on success, negative values on failure.
499 *
500 */
501int netlbl_conn_setattr(struct sock *sk,
502 struct sockaddr *addr,
503 const struct netlbl_lsm_secattr *secattr)
504{
505 int ret_val;
506 struct sockaddr_in *addr4;
507 struct netlbl_domaddr4_map *af4_entry;
508
509 rcu_read_lock();
510 switch (addr->sa_family) {
511 case AF_INET:
512 addr4 = (struct sockaddr_in *)addr;
513 af4_entry = netlbl_domhsh_getentry_af4(secattr->domain,
514 addr4->sin_addr.s_addr);
515 if (af4_entry == NULL) {
516 ret_val = -ENOENT;
517 goto conn_setattr_return;
518 }
519 switch (af4_entry->type) {
520 case NETLBL_NLTYPE_CIPSOV4:
521 ret_val = cipso_v4_sock_setattr(sk,
522 af4_entry->type_def.cipsov4,
523 secattr);
524 break;
525 case NETLBL_NLTYPE_UNLABELED:
526 /* just delete the protocols we support for right now
527 * but we could remove other protocols if needed */
528 cipso_v4_sock_delattr(sk);
529 ret_val = 0;
530 break;
531 default:
532 ret_val = -ENOENT;
533 }
534 break;
535#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
536 case AF_INET6:
537 /* since we don't support any IPv6 labeling protocols right
538 * now we can optimize everything away until we do */
539 ret_val = 0;
540 break;
541#endif /* IPv6 */
542 default:
543 ret_val = 0;
544 }
545
546conn_setattr_return:
547 rcu_read_unlock();
548 return ret_val;
549}
550
551/**
476 * netlbl_skbuff_setattr - Label a packet using the correct protocol 552 * netlbl_skbuff_setattr - Label a packet using the correct protocol
477 * @skb: the packet 553 * @skb: the packet
478 * @family: protocol family 554 * @family: protocol family