diff options
Diffstat (limited to 'security/smack/smack_lsm.c')
-rw-r--r-- | security/smack/smack_lsm.c | 94 |
1 files changed, 86 insertions, 8 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 1fa72317bbec..81b30e32c526 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -52,8 +52,11 @@ | |||
52 | #define SMK_RECEIVING 1 | 52 | #define SMK_RECEIVING 1 |
53 | #define SMK_SENDING 2 | 53 | #define SMK_SENDING 2 |
54 | 54 | ||
55 | #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) | ||
55 | LIST_HEAD(smk_ipv6_port_list); | 56 | LIST_HEAD(smk_ipv6_port_list); |
57 | #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ | ||
56 | static struct kmem_cache *smack_inode_cache; | 58 | static struct kmem_cache *smack_inode_cache; |
59 | int smack_enabled; | ||
57 | 60 | ||
58 | #ifdef CONFIG_SECURITY_SMACK_BRINGUP | 61 | #ifdef CONFIG_SECURITY_SMACK_BRINGUP |
59 | static void smk_bu_mode(int mode, char *s) | 62 | static void smk_bu_mode(int mode, char *s) |
@@ -2213,6 +2216,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) | |||
2213 | return smack_netlabel(sk, sk_lbl); | 2216 | return smack_netlabel(sk, sk_lbl); |
2214 | } | 2217 | } |
2215 | 2218 | ||
2219 | #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) | ||
2216 | /** | 2220 | /** |
2217 | * smk_ipv6_port_label - Smack port access table management | 2221 | * smk_ipv6_port_label - Smack port access table management |
2218 | * @sock: socket | 2222 | * @sock: socket |
@@ -2362,6 +2366,7 @@ auditout: | |||
2362 | rc = smk_bu_note("IPv6 port check", skp, object, MAY_WRITE, rc); | 2366 | rc = smk_bu_note("IPv6 port check", skp, object, MAY_WRITE, rc); |
2363 | return rc; | 2367 | return rc; |
2364 | } | 2368 | } |
2369 | #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ | ||
2365 | 2370 | ||
2366 | /** | 2371 | /** |
2367 | * smack_inode_setsecurity - set smack xattrs | 2372 | * smack_inode_setsecurity - set smack xattrs |
@@ -2422,8 +2427,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, | |||
2422 | } else | 2427 | } else |
2423 | return -EOPNOTSUPP; | 2428 | return -EOPNOTSUPP; |
2424 | 2429 | ||
2430 | #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) | ||
2425 | if (sock->sk->sk_family == PF_INET6) | 2431 | if (sock->sk->sk_family == PF_INET6) |
2426 | smk_ipv6_port_label(sock, NULL); | 2432 | smk_ipv6_port_label(sock, NULL); |
2433 | #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ | ||
2427 | 2434 | ||
2428 | return 0; | 2435 | return 0; |
2429 | } | 2436 | } |
@@ -2451,6 +2458,7 @@ static int smack_socket_post_create(struct socket *sock, int family, | |||
2451 | return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); | 2458 | return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); |
2452 | } | 2459 | } |
2453 | 2460 | ||
2461 | #ifndef CONFIG_SECURITY_SMACK_NETFILTER | ||
2454 | /** | 2462 | /** |
2455 | * smack_socket_bind - record port binding information. | 2463 | * smack_socket_bind - record port binding information. |
2456 | * @sock: the socket | 2464 | * @sock: the socket |
@@ -2464,11 +2472,14 @@ static int smack_socket_post_create(struct socket *sock, int family, | |||
2464 | static int smack_socket_bind(struct socket *sock, struct sockaddr *address, | 2472 | static int smack_socket_bind(struct socket *sock, struct sockaddr *address, |
2465 | int addrlen) | 2473 | int addrlen) |
2466 | { | 2474 | { |
2475 | #if IS_ENABLED(CONFIG_IPV6) | ||
2467 | if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) | 2476 | if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) |
2468 | smk_ipv6_port_label(sock, address); | 2477 | smk_ipv6_port_label(sock, address); |
2478 | #endif | ||
2469 | 2479 | ||
2470 | return 0; | 2480 | return 0; |
2471 | } | 2481 | } |
2482 | #endif /* !CONFIG_SECURITY_SMACK_NETFILTER */ | ||
2472 | 2483 | ||
2473 | /** | 2484 | /** |
2474 | * smack_socket_connect - connect access check | 2485 | * smack_socket_connect - connect access check |
@@ -2497,8 +2508,10 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, | |||
2497 | case PF_INET6: | 2508 | case PF_INET6: |
2498 | if (addrlen < sizeof(struct sockaddr_in6)) | 2509 | if (addrlen < sizeof(struct sockaddr_in6)) |
2499 | return -EINVAL; | 2510 | return -EINVAL; |
2511 | #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) | ||
2500 | rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap, | 2512 | rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap, |
2501 | SMK_CONNECTING); | 2513 | SMK_CONNECTING); |
2514 | #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ | ||
2502 | break; | 2515 | break; |
2503 | } | 2516 | } |
2504 | return rc; | 2517 | return rc; |
@@ -3381,7 +3394,9 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, | |||
3381 | int size) | 3394 | int size) |
3382 | { | 3395 | { |
3383 | struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; | 3396 | struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; |
3397 | #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) | ||
3384 | struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name; | 3398 | struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name; |
3399 | #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ | ||
3385 | int rc = 0; | 3400 | int rc = 0; |
3386 | 3401 | ||
3387 | /* | 3402 | /* |
@@ -3395,7 +3410,9 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, | |||
3395 | rc = smack_netlabel_send(sock->sk, sip); | 3410 | rc = smack_netlabel_send(sock->sk, sip); |
3396 | break; | 3411 | break; |
3397 | case AF_INET6: | 3412 | case AF_INET6: |
3413 | #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) | ||
3398 | rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING); | 3414 | rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING); |
3415 | #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ | ||
3399 | break; | 3416 | break; |
3400 | } | 3417 | } |
3401 | return rc; | 3418 | return rc; |
@@ -3486,6 +3503,7 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, | |||
3486 | return smack_net_ambient; | 3503 | return smack_net_ambient; |
3487 | } | 3504 | } |
3488 | 3505 | ||
3506 | #if IS_ENABLED(CONFIG_IPV6) | ||
3489 | static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) | 3507 | static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) |
3490 | { | 3508 | { |
3491 | u8 nexthdr; | 3509 | u8 nexthdr; |
@@ -3532,6 +3550,7 @@ static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) | |||
3532 | } | 3550 | } |
3533 | return proto; | 3551 | return proto; |
3534 | } | 3552 | } |
3553 | #endif /* CONFIG_IPV6 */ | ||
3535 | 3554 | ||
3536 | /** | 3555 | /** |
3537 | * smack_socket_sock_rcv_skb - Smack packet delivery access check | 3556 | * smack_socket_sock_rcv_skb - Smack packet delivery access check |
@@ -3544,15 +3563,30 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
3544 | { | 3563 | { |
3545 | struct netlbl_lsm_secattr secattr; | 3564 | struct netlbl_lsm_secattr secattr; |
3546 | struct socket_smack *ssp = sk->sk_security; | 3565 | struct socket_smack *ssp = sk->sk_security; |
3547 | struct smack_known *skp; | 3566 | struct smack_known *skp = NULL; |
3548 | struct sockaddr_in6 sadd; | ||
3549 | int rc = 0; | 3567 | int rc = 0; |
3550 | struct smk_audit_info ad; | 3568 | struct smk_audit_info ad; |
3551 | #ifdef CONFIG_AUDIT | 3569 | #ifdef CONFIG_AUDIT |
3552 | struct lsm_network_audit net; | 3570 | struct lsm_network_audit net; |
3553 | #endif | 3571 | #endif |
3572 | #if IS_ENABLED(CONFIG_IPV6) | ||
3573 | struct sockaddr_in6 sadd; | ||
3574 | int proto; | ||
3575 | #endif /* CONFIG_IPV6 */ | ||
3576 | |||
3554 | switch (sk->sk_family) { | 3577 | switch (sk->sk_family) { |
3555 | case PF_INET: | 3578 | case PF_INET: |
3579 | #ifdef CONFIG_SECURITY_SMACK_NETFILTER | ||
3580 | /* | ||
3581 | * If there is a secmark use it rather than the CIPSO label. | ||
3582 | * If there is no secmark fall back to CIPSO. | ||
3583 | * The secmark is assumed to reflect policy better. | ||
3584 | */ | ||
3585 | if (skb && skb->secmark != 0) { | ||
3586 | skp = smack_from_secid(skb->secmark); | ||
3587 | goto access_check; | ||
3588 | } | ||
3589 | #endif /* CONFIG_SECURITY_SMACK_NETFILTER */ | ||
3556 | /* | 3590 | /* |
3557 | * Translate what netlabel gave us. | 3591 | * Translate what netlabel gave us. |
3558 | */ | 3592 | */ |
@@ -3566,6 +3600,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
3566 | 3600 | ||
3567 | netlbl_secattr_destroy(&secattr); | 3601 | netlbl_secattr_destroy(&secattr); |
3568 | 3602 | ||
3603 | #ifdef CONFIG_SECURITY_SMACK_NETFILTER | ||
3604 | access_check: | ||
3605 | #endif | ||
3569 | #ifdef CONFIG_AUDIT | 3606 | #ifdef CONFIG_AUDIT |
3570 | smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); | 3607 | smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); |
3571 | ad.a.u.net->family = sk->sk_family; | 3608 | ad.a.u.net->family = sk->sk_family; |
@@ -3584,14 +3621,32 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
3584 | if (rc != 0) | 3621 | if (rc != 0) |
3585 | netlbl_skbuff_err(skb, rc, 0); | 3622 | netlbl_skbuff_err(skb, rc, 0); |
3586 | break; | 3623 | break; |
3624 | #if IS_ENABLED(CONFIG_IPV6) | ||
3587 | case PF_INET6: | 3625 | case PF_INET6: |
3588 | rc = smk_skb_to_addr_ipv6(skb, &sadd); | 3626 | proto = smk_skb_to_addr_ipv6(skb, &sadd); |
3589 | if (rc == IPPROTO_UDP || rc == IPPROTO_TCP) | 3627 | if (proto != IPPROTO_UDP && proto != IPPROTO_TCP) |
3590 | rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING); | 3628 | break; |
3629 | #ifdef CONFIG_SECURITY_SMACK_NETFILTER | ||
3630 | if (skb && skb->secmark != 0) | ||
3631 | skp = smack_from_secid(skb->secmark); | ||
3591 | else | 3632 | else |
3592 | rc = 0; | 3633 | skp = smack_net_ambient; |
3634 | #ifdef CONFIG_AUDIT | ||
3635 | smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); | ||
3636 | ad.a.u.net->family = sk->sk_family; | ||
3637 | ad.a.u.net->netif = skb->skb_iif; | ||
3638 | ipv6_skb_to_auditdata(skb, &ad.a, NULL); | ||
3639 | #endif /* CONFIG_AUDIT */ | ||
3640 | rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); | ||
3641 | rc = smk_bu_note("IPv6 delivery", skp, ssp->smk_in, | ||
3642 | MAY_WRITE, rc); | ||
3643 | #else /* CONFIG_SECURITY_SMACK_NETFILTER */ | ||
3644 | rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING); | ||
3645 | #endif /* CONFIG_SECURITY_SMACK_NETFILTER */ | ||
3593 | break; | 3646 | break; |
3647 | #endif /* CONFIG_IPV6 */ | ||
3594 | } | 3648 | } |
3649 | |||
3595 | return rc; | 3650 | return rc; |
3596 | } | 3651 | } |
3597 | 3652 | ||
@@ -3653,16 +3708,25 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, | |||
3653 | if (skb != NULL) { | 3708 | if (skb != NULL) { |
3654 | if (skb->protocol == htons(ETH_P_IP)) | 3709 | if (skb->protocol == htons(ETH_P_IP)) |
3655 | family = PF_INET; | 3710 | family = PF_INET; |
3711 | #if IS_ENABLED(CONFIG_IPV6) | ||
3656 | else if (skb->protocol == htons(ETH_P_IPV6)) | 3712 | else if (skb->protocol == htons(ETH_P_IPV6)) |
3657 | family = PF_INET6; | 3713 | family = PF_INET6; |
3714 | #endif /* CONFIG_IPV6 */ | ||
3658 | } | 3715 | } |
3659 | if (family == PF_UNSPEC && sock != NULL) | 3716 | if (family == PF_UNSPEC && sock != NULL) |
3660 | family = sock->sk->sk_family; | 3717 | family = sock->sk->sk_family; |
3661 | 3718 | ||
3662 | if (family == PF_UNIX) { | 3719 | switch (family) { |
3720 | case PF_UNIX: | ||
3663 | ssp = sock->sk->sk_security; | 3721 | ssp = sock->sk->sk_security; |
3664 | s = ssp->smk_out->smk_secid; | 3722 | s = ssp->smk_out->smk_secid; |
3665 | } else if (family == PF_INET || family == PF_INET6) { | 3723 | break; |
3724 | case PF_INET: | ||
3725 | #ifdef CONFIG_SECURITY_SMACK_NETFILTER | ||
3726 | s = skb->secmark; | ||
3727 | if (s != 0) | ||
3728 | break; | ||
3729 | #endif | ||
3666 | /* | 3730 | /* |
3667 | * Translate what netlabel gave us. | 3731 | * Translate what netlabel gave us. |
3668 | */ | 3732 | */ |
@@ -3675,6 +3739,14 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, | |||
3675 | s = skp->smk_secid; | 3739 | s = skp->smk_secid; |
3676 | } | 3740 | } |
3677 | netlbl_secattr_destroy(&secattr); | 3741 | netlbl_secattr_destroy(&secattr); |
3742 | break; | ||
3743 | #if IS_ENABLED(CONFIG_IPV6) | ||
3744 | case PF_INET6: | ||
3745 | #ifdef CONFIG_SECURITY_SMACK_NETFILTER | ||
3746 | s = skb->secmark; | ||
3747 | #endif /* CONFIG_SECURITY_SMACK_NETFILTER */ | ||
3748 | break; | ||
3749 | #endif /* CONFIG_IPV6 */ | ||
3678 | } | 3750 | } |
3679 | *secid = s; | 3751 | *secid = s; |
3680 | if (s == 0) | 3752 | if (s == 0) |
@@ -3730,6 +3802,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, | |||
3730 | struct lsm_network_audit net; | 3802 | struct lsm_network_audit net; |
3731 | #endif | 3803 | #endif |
3732 | 3804 | ||
3805 | #if IS_ENABLED(CONFIG_IPV6) | ||
3733 | if (family == PF_INET6) { | 3806 | if (family == PF_INET6) { |
3734 | /* | 3807 | /* |
3735 | * Handle mapped IPv4 packets arriving | 3808 | * Handle mapped IPv4 packets arriving |
@@ -3741,6 +3814,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, | |||
3741 | else | 3814 | else |
3742 | return 0; | 3815 | return 0; |
3743 | } | 3816 | } |
3817 | #endif /* CONFIG_IPV6 */ | ||
3744 | 3818 | ||
3745 | netlbl_secattr_init(&secattr); | 3819 | netlbl_secattr_init(&secattr); |
3746 | rc = netlbl_skbuff_getattr(skb, family, &secattr); | 3820 | rc = netlbl_skbuff_getattr(skb, family, &secattr); |
@@ -4199,7 +4273,9 @@ struct security_operations smack_ops = { | |||
4199 | .unix_may_send = smack_unix_may_send, | 4273 | .unix_may_send = smack_unix_may_send, |
4200 | 4274 | ||
4201 | .socket_post_create = smack_socket_post_create, | 4275 | .socket_post_create = smack_socket_post_create, |
4276 | #ifndef CONFIG_SECURITY_SMACK_NETFILTER | ||
4202 | .socket_bind = smack_socket_bind, | 4277 | .socket_bind = smack_socket_bind, |
4278 | #endif /* CONFIG_SECURITY_SMACK_NETFILTER */ | ||
4203 | .socket_connect = smack_socket_connect, | 4279 | .socket_connect = smack_socket_connect, |
4204 | .socket_sendmsg = smack_socket_sendmsg, | 4280 | .socket_sendmsg = smack_socket_sendmsg, |
4205 | .socket_sock_rcv_skb = smack_socket_sock_rcv_skb, | 4281 | .socket_sock_rcv_skb = smack_socket_sock_rcv_skb, |
@@ -4280,6 +4356,8 @@ static __init int smack_init(void) | |||
4280 | if (!security_module_enable(&smack_ops)) | 4356 | if (!security_module_enable(&smack_ops)) |
4281 | return 0; | 4357 | return 0; |
4282 | 4358 | ||
4359 | smack_enabled = 1; | ||
4360 | |||
4283 | smack_inode_cache = KMEM_CACHE(inode_smack, 0); | 4361 | smack_inode_cache = KMEM_CACHE(inode_smack, 0); |
4284 | if (!smack_inode_cache) | 4362 | if (!smack_inode_cache) |
4285 | return -ENOMEM; | 4363 | return -ENOMEM; |