aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/smack/smack_lsm.c106
1 files changed, 63 insertions, 43 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 489a85afa477..04a98c361a65 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -1667,10 +1667,13 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
1667 ssp->smk_in = sp; 1667 ssp->smk_in = sp;
1668 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { 1668 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
1669 ssp->smk_out = sp; 1669 ssp->smk_out = sp;
1670 rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); 1670 if (sock->sk->sk_family != PF_UNIX) {
1671 if (rc != 0) 1671 rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
1672 printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n", 1672 if (rc != 0)
1673 __func__, -rc); 1673 printk(KERN_WARNING
1674 "Smack: \"%s\" netlbl error %d.\n",
1675 __func__, -rc);
1676 }
1674 } else 1677 } else
1675 return -EOPNOTSUPP; 1678 return -EOPNOTSUPP;
1676 1679
@@ -2267,9 +2270,10 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2267 break; 2270 break;
2268 case SOCKFS_MAGIC: 2271 case SOCKFS_MAGIC:
2269 /* 2272 /*
2270 * Casey says sockets get the smack of the task. 2273 * Socket access is controlled by the socket
2274 * structures associated with the task involved.
2271 */ 2275 */
2272 final = csp; 2276 final = smack_known_star.smk_known;
2273 break; 2277 break;
2274 case PROC_SUPER_MAGIC: 2278 case PROC_SUPER_MAGIC:
2275 /* 2279 /*
@@ -2296,7 +2300,16 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2296 /* 2300 /*
2297 * This isn't an understood special case. 2301 * This isn't an understood special case.
2298 * Get the value from the xattr. 2302 * Get the value from the xattr.
2299 * 2303 */
2304
2305 /*
2306 * UNIX domain sockets use lower level socket data.
2307 */
2308 if (S_ISSOCK(inode->i_mode)) {
2309 final = smack_known_star.smk_known;
2310 break;
2311 }
2312 /*
2300 * No xattr support means, alas, no SMACK label. 2313 * No xattr support means, alas, no SMACK label.
2301 * Use the aforeapplied default. 2314 * Use the aforeapplied default.
2302 * It would be curious if the label of the task 2315 * It would be curious if the label of the task
@@ -2418,14 +2431,18 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2418static int smack_unix_stream_connect(struct socket *sock, 2431static int smack_unix_stream_connect(struct socket *sock,
2419 struct socket *other, struct sock *newsk) 2432 struct socket *other, struct sock *newsk)
2420{ 2433{
2421 struct inode *sp = SOCK_INODE(sock); 2434 struct socket_smack *ssp = sock->sk->sk_security;
2422 struct inode *op = SOCK_INODE(other); 2435 struct socket_smack *osp = other->sk->sk_security;
2423 struct smk_audit_info ad; 2436 struct smk_audit_info ad;
2437 int rc = 0;
2424 2438
2425 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); 2439 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
2426 smk_ad_setfield_u_net_sk(&ad, other->sk); 2440 smk_ad_setfield_u_net_sk(&ad, other->sk);
2427 return smk_access(smk_of_inode(sp), smk_of_inode(op), 2441
2428 MAY_READWRITE, &ad); 2442 if (!capable(CAP_MAC_OVERRIDE))
2443 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
2444
2445 return rc;
2429} 2446}
2430 2447
2431/** 2448/**
@@ -2438,13 +2455,18 @@ static int smack_unix_stream_connect(struct socket *sock,
2438 */ 2455 */
2439static int smack_unix_may_send(struct socket *sock, struct socket *other) 2456static int smack_unix_may_send(struct socket *sock, struct socket *other)
2440{ 2457{
2441 struct inode *sp = SOCK_INODE(sock); 2458 struct socket_smack *ssp = sock->sk->sk_security;
2442 struct inode *op = SOCK_INODE(other); 2459 struct socket_smack *osp = other->sk->sk_security;
2443 struct smk_audit_info ad; 2460 struct smk_audit_info ad;
2461 int rc = 0;
2444 2462
2445 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); 2463 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
2446 smk_ad_setfield_u_net_sk(&ad, other->sk); 2464 smk_ad_setfield_u_net_sk(&ad, other->sk);
2447 return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_WRITE, &ad); 2465
2466 if (!capable(CAP_MAC_OVERRIDE))
2467 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
2468
2469 return rc;
2448} 2470}
2449 2471
2450/** 2472/**
@@ -2629,7 +2651,7 @@ static int smack_socket_getpeersec_stream(struct socket *sock,
2629 2651
2630/** 2652/**
2631 * smack_socket_getpeersec_dgram - pull in packet label 2653 * smack_socket_getpeersec_dgram - pull in packet label
2632 * @sock: the socket 2654 * @sock: the peer socket
2633 * @skb: packet data 2655 * @skb: packet data
2634 * @secid: pointer to where to put the secid of the packet 2656 * @secid: pointer to where to put the secid of the packet
2635 * 2657 *
@@ -2640,41 +2662,39 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
2640 2662
2641{ 2663{
2642 struct netlbl_lsm_secattr secattr; 2664 struct netlbl_lsm_secattr secattr;
2643 struct sock *sk; 2665 struct socket_smack *sp;
2644 char smack[SMK_LABELLEN]; 2666 char smack[SMK_LABELLEN];
2645 int family = PF_INET; 2667 int family = PF_UNSPEC;
2646 u32 s; 2668 u32 s = 0; /* 0 is the invalid secid */
2647 int rc; 2669 int rc;
2648 2670
2649 /* 2671 if (skb != NULL) {
2650 * Only works for families with packets. 2672 if (skb->protocol == htons(ETH_P_IP))
2651 */ 2673 family = PF_INET;
2652 if (sock != NULL) { 2674 else if (skb->protocol == htons(ETH_P_IPV6))
2653 sk = sock->sk; 2675 family = PF_INET6;
2654 if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
2655 return 0;
2656 family = sk->sk_family;
2657 } 2676 }
2658 /* 2677 if (family == PF_UNSPEC && sock != NULL)
2659 * Translate what netlabel gave us. 2678 family = sock->sk->sk_family;
2660 */
2661 netlbl_secattr_init(&secattr);
2662 rc = netlbl_skbuff_getattr(skb, family, &secattr);
2663 if (rc == 0)
2664 smack_from_secattr(&secattr, smack);
2665 netlbl_secattr_destroy(&secattr);
2666
2667 /*
2668 * Give up if we couldn't get anything
2669 */
2670 if (rc != 0)
2671 return rc;
2672 2679
2673 s = smack_to_secid(smack); 2680 if (family == PF_UNIX) {
2681 sp = sock->sk->sk_security;
2682 s = smack_to_secid(sp->smk_out);
2683 } else if (family == PF_INET || family == PF_INET6) {
2684 /*
2685 * Translate what netlabel gave us.
2686 */
2687 netlbl_secattr_init(&secattr);
2688 rc = netlbl_skbuff_getattr(skb, family, &secattr);
2689 if (rc == 0) {
2690 smack_from_secattr(&secattr, smack);
2691 s = smack_to_secid(smack);
2692 }
2693 netlbl_secattr_destroy(&secattr);
2694 }
2695 *secid = s;
2674 if (s == 0) 2696 if (s == 0)
2675 return -EINVAL; 2697 return -EINVAL;
2676
2677 *secid = s;
2678 return 0; 2698 return 0;
2679} 2699}
2680 2700