diff options
author | Yannick GICQUEL <yannick.gicquel@iot.bzh> | 2015-10-19 15:57:07 +0200 |
---|---|---|
committer | Gerrit Code Review <gerrit@172.30.200.200> | 2015-11-06 15:23:36 +0000 |
commit | ede19ea0c47fb23f3fc779833d1e57cf76f3371e (patch) | |
tree | 47d6fae2283c54def1871aaf2a73828ac68b1b34 /meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0050-Smack-secmark-support-for-netfilter.patch | |
parent | 1cd8ab18abca96e4ee108f80225058d875b28347 (diff) |
kernel: smack security backport from kernel 4
Here is the backport of all patches relating to smack support
on kernel side. For more details, see file:
meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/README
Please note that patches are applied only if "smack" is in the
ditro features. Here are the 2 lines to add in the local.conf
OVERRIDES .= ":smack"
DISTRO_FEATURES_append = " smack"
Change-Id: I147a3532aec531f977d6ec34c576261835711f1e
Signed-off-by: Yannick GICQUEL <yannick.gicquel@iot.bzh>
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
Diffstat (limited to 'meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0050-Smack-secmark-support-for-netfilter.patch')
-rw-r--r-- | meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0050-Smack-secmark-support-for-netfilter.patch | 448 |
1 files changed, 448 insertions, 0 deletions
diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0050-Smack-secmark-support-for-netfilter.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0050-Smack-secmark-support-for-netfilter.patch new file mode 100644 index 0000000..bbaf99f --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0050-Smack-secmark-support-for-netfilter.patch @@ -0,0 +1,448 @@ +From ca4b65446c72278483c473c189191f50f2b2466e Mon Sep 17 00:00:00 2001 +From: Casey Schaufler <casey@schaufler-ca.com> +Date: Fri, 12 Dec 2014 17:08:40 -0800 +Subject: [PATCH 50/54] Smack: secmark support for netfilter + +Smack uses CIPSO to label internet packets and thus provide +for access control on delivery of packets. The netfilter facility +was not used to allow for Smack to work properly without netfilter +configuration. Smack does not need netfilter, however there are +cases where it would be handy. + +As a side effect, the labeling of local IPv4 packets can be optimized +and the handling of local IPv6 packets is just all out better. + +The best part is that the netfilter tools use "contexts" that +are just strings, and they work just as well for Smack as they +do for SELinux. + +All of the conditional compilation for IPv6 was implemented +by Rafal Krypa <r.krypa@samsung.com> + +Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> +--- + security/smack/Kconfig | 12 +++++ + security/smack/Makefile | 1 + + security/smack/smack.h | 1 + + security/smack/smack_lsm.c | 94 +++++++++++++++++++++++++++++++++++---- + security/smack/smack_netfilter.c | 96 ++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 196 insertions(+), 8 deletions(-) + create mode 100644 security/smack/smack_netfilter.c + +diff --git a/security/smack/Kconfig b/security/smack/Kconfig +index b065f97..271adae 100644 +--- a/security/smack/Kconfig ++++ b/security/smack/Kconfig +@@ -28,3 +28,15 @@ config SECURITY_SMACK_BRINGUP + access rule set once the behavior is well understood. + This is a superior mechanism to the oft abused + "permissive" mode of other systems. ++ If you are unsure how to answer this question, answer N. ++ ++config SECURITY_SMACK_NETFILTER ++ bool "Packet marking using secmarks for netfilter" ++ depends on SECURITY_SMACK ++ depends on NETWORK_SECMARK ++ depends on NETFILTER ++ default n ++ help ++ This enables security marking of network packets using ++ Smack labels. ++ If you are unsure how to answer this question, answer N. +diff --git a/security/smack/Makefile b/security/smack/Makefile +index 67a63aa..616cf93 100644 +--- a/security/smack/Makefile ++++ b/security/smack/Makefile +@@ -5,3 +5,4 @@ + obj-$(CONFIG_SECURITY_SMACK) := smack.o + + smack-y := smack_lsm.o smack_access.o smackfs.o ++smack-$(CONFIG_NETFILTER) += smack_netfilter.o +diff --git a/security/smack/smack.h b/security/smack/smack.h +index b828a37..7629eae 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -248,6 +248,7 @@ struct smack_known *smk_find_entry(const char *); + /* + * Shared data. + */ ++extern int smack_enabled; + extern int smack_cipso_direct; + extern int smack_cipso_mapped; + extern struct smack_known *smack_net_ambient; +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 9aa34d3..ae3e1b6 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -52,8 +52,11 @@ + #define SMK_RECEIVING 1 + #define SMK_SENDING 2 + ++#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) + LIST_HEAD(smk_ipv6_port_list); ++#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ + static struct kmem_cache *smack_inode_cache; ++int smack_enabled; + + #ifdef CONFIG_SECURITY_SMACK_BRINGUP + static void smk_bu_mode(int mode, char *s) +@@ -2214,6 +2217,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) + return smack_netlabel(sk, sk_lbl); + } + ++#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) + /** + * smk_ipv6_port_label - Smack port access table management + * @sock: socket +@@ -2363,6 +2367,7 @@ auditout: + rc = smk_bu_note("IPv6 port check", skp, object, MAY_WRITE, rc); + return rc; + } ++#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ + + /** + * smack_inode_setsecurity - set smack xattrs +@@ -2423,8 +2428,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, + } else + return -EOPNOTSUPP; + ++#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) + if (sock->sk->sk_family == PF_INET6) + smk_ipv6_port_label(sock, NULL); ++#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ + + return 0; + } +@@ -2452,6 +2459,7 @@ static int smack_socket_post_create(struct socket *sock, int family, + return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); + } + ++#ifndef CONFIG_SECURITY_SMACK_NETFILTER + /** + * smack_socket_bind - record port binding information. + * @sock: the socket +@@ -2465,11 +2473,14 @@ static int smack_socket_post_create(struct socket *sock, int family, + static int smack_socket_bind(struct socket *sock, struct sockaddr *address, + int addrlen) + { ++#if IS_ENABLED(CONFIG_IPV6) + if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) + smk_ipv6_port_label(sock, address); ++#endif + + return 0; + } ++#endif /* !CONFIG_SECURITY_SMACK_NETFILTER */ + + /** + * smack_socket_connect - connect access check +@@ -2498,8 +2509,10 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, + case PF_INET6: + if (addrlen < sizeof(struct sockaddr_in6)) + return -EINVAL; ++#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) + rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap, + SMK_CONNECTING); ++#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ + break; + } + return rc; +@@ -3382,7 +3395,9 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, + int size) + { + struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; ++#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) + struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name; ++#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ + int rc = 0; + + /* +@@ -3396,7 +3411,9 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, + rc = smack_netlabel_send(sock->sk, sip); + break; + case AF_INET6: ++#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) + rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING); ++#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ + break; + } + return rc; +@@ -3487,6 +3504,7 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, + return smack_net_ambient; + } + ++#if IS_ENABLED(CONFIG_IPV6) + static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) + { + u8 nexthdr; +@@ -3533,6 +3551,7 @@ static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) + } + return proto; + } ++#endif /* CONFIG_IPV6 */ + + /** + * smack_socket_sock_rcv_skb - Smack packet delivery access check +@@ -3545,15 +3564,30 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) + { + struct netlbl_lsm_secattr secattr; + struct socket_smack *ssp = sk->sk_security; +- struct smack_known *skp; +- struct sockaddr_in6 sadd; ++ struct smack_known *skp = NULL; + int rc = 0; + struct smk_audit_info ad; + #ifdef CONFIG_AUDIT + struct lsm_network_audit net; + #endif ++#if IS_ENABLED(CONFIG_IPV6) ++ struct sockaddr_in6 sadd; ++ int proto; ++#endif /* CONFIG_IPV6 */ ++ + switch (sk->sk_family) { + case PF_INET: ++#ifdef CONFIG_SECURITY_SMACK_NETFILTER ++ /* ++ * If there is a secmark use it rather than the CIPSO label. ++ * If there is no secmark fall back to CIPSO. ++ * The secmark is assumed to reflect policy better. ++ */ ++ if (skb && skb->secmark != 0) { ++ skp = smack_from_secid(skb->secmark); ++ goto access_check; ++ } ++#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ + /* + * Translate what netlabel gave us. + */ +@@ -3567,6 +3601,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) + + netlbl_secattr_destroy(&secattr); + ++#ifdef CONFIG_SECURITY_SMACK_NETFILTER ++access_check: ++#endif + #ifdef CONFIG_AUDIT + smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); + ad.a.u.net->family = sk->sk_family; +@@ -3585,14 +3622,32 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) + if (rc != 0) + netlbl_skbuff_err(skb, rc, 0); + break; ++#if IS_ENABLED(CONFIG_IPV6) + case PF_INET6: +- rc = smk_skb_to_addr_ipv6(skb, &sadd); +- if (rc == IPPROTO_UDP || rc == IPPROTO_TCP) +- rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING); ++ proto = smk_skb_to_addr_ipv6(skb, &sadd); ++ if (proto != IPPROTO_UDP && proto != IPPROTO_TCP) ++ break; ++#ifdef CONFIG_SECURITY_SMACK_NETFILTER ++ if (skb && skb->secmark != 0) ++ skp = smack_from_secid(skb->secmark); + else +- rc = 0; ++ skp = smack_net_ambient; ++#ifdef CONFIG_AUDIT ++ smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); ++ ad.a.u.net->family = sk->sk_family; ++ ad.a.u.net->netif = skb->skb_iif; ++ ipv6_skb_to_auditdata(skb, &ad.a, NULL); ++#endif /* CONFIG_AUDIT */ ++ rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); ++ rc = smk_bu_note("IPv6 delivery", skp, ssp->smk_in, ++ MAY_WRITE, rc); ++#else /* CONFIG_SECURITY_SMACK_NETFILTER */ ++ rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING); ++#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ + break; ++#endif /* CONFIG_IPV6 */ + } ++ + return rc; + } + +@@ -3654,16 +3709,25 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, + if (skb != NULL) { + if (skb->protocol == htons(ETH_P_IP)) + family = PF_INET; ++#if IS_ENABLED(CONFIG_IPV6) + else if (skb->protocol == htons(ETH_P_IPV6)) + family = PF_INET6; ++#endif /* CONFIG_IPV6 */ + } + if (family == PF_UNSPEC && sock != NULL) + family = sock->sk->sk_family; + +- if (family == PF_UNIX) { ++ switch (family) { ++ case PF_UNIX: + ssp = sock->sk->sk_security; + s = ssp->smk_out->smk_secid; +- } else if (family == PF_INET || family == PF_INET6) { ++ break; ++ case PF_INET: ++#ifdef CONFIG_SECURITY_SMACK_NETFILTER ++ s = skb->secmark; ++ if (s != 0) ++ break; ++#endif + /* + * Translate what netlabel gave us. + */ +@@ -3676,6 +3740,14 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, + s = skp->smk_secid; + } + netlbl_secattr_destroy(&secattr); ++ break; ++#if IS_ENABLED(CONFIG_IPV6) ++ case PF_INET6: ++#ifdef CONFIG_SECURITY_SMACK_NETFILTER ++ s = skb->secmark; ++#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ ++ break; ++#endif /* CONFIG_IPV6 */ + } + *secid = s; + if (s == 0) +@@ -3731,6 +3803,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, + struct lsm_network_audit net; + #endif + ++#if IS_ENABLED(CONFIG_IPV6) + if (family == PF_INET6) { + /* + * Handle mapped IPv4 packets arriving +@@ -3742,6 +3815,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, + else + return 0; + } ++#endif /* CONFIG_IPV6 */ + + netlbl_secattr_init(&secattr); + rc = netlbl_skbuff_getattr(skb, family, &secattr); +@@ -4201,7 +4275,9 @@ struct security_operations smack_ops = { + .unix_may_send = smack_unix_may_send, + + .socket_post_create = smack_socket_post_create, ++#ifndef CONFIG_SECURITY_SMACK_NETFILTER + .socket_bind = smack_socket_bind, ++#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ + .socket_connect = smack_socket_connect, + .socket_sendmsg = smack_socket_sendmsg, + .socket_sock_rcv_skb = smack_socket_sock_rcv_skb, +@@ -4282,6 +4358,8 @@ static __init int smack_init(void) + if (!security_module_enable(&smack_ops)) + return 0; + ++ smack_enabled = 1; ++ + smack_inode_cache = KMEM_CACHE(inode_smack, 0); + if (!smack_inode_cache) + return -ENOMEM; +diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c +new file mode 100644 +index 0000000..c952632 +--- /dev/null ++++ b/security/smack/smack_netfilter.c +@@ -0,0 +1,96 @@ ++/* ++ * Simplified MAC Kernel (smack) security module ++ * ++ * This file contains the Smack netfilter implementation ++ * ++ * Author: ++ * Casey Schaufler <casey@schaufler-ca.com> ++ * ++ * Copyright (C) 2014 Casey Schaufler <casey@schaufler-ca.com> ++ * Copyright (C) 2014 Intel Corporation. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2, ++ * as published by the Free Software Foundation. ++ */ ++ ++#include <linux/netfilter_ipv4.h> ++#include <linux/netfilter_ipv6.h> ++#include <linux/netdevice.h> ++#include "smack.h" ++ ++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) ++ ++static unsigned int smack_ipv6_output(const struct nf_hook_ops *ops, ++ struct sk_buff *skb, ++ const struct net_device *in, ++ const struct net_device *out, ++ int (*okfn)(struct sk_buff *)) ++{ ++ struct socket_smack *ssp; ++ struct smack_known *skp; ++ ++ if (skb && skb->sk && skb->sk->sk_security) { ++ ssp = skb->sk->sk_security; ++ skp = ssp->smk_out; ++ skb->secmark = skp->smk_secid; ++ } ++ ++ return NF_ACCEPT; ++} ++#endif /* IPV6 */ ++ ++static unsigned int smack_ipv4_output(const struct nf_hook_ops *ops, ++ struct sk_buff *skb, ++ const struct net_device *in, ++ const struct net_device *out, ++ int (*okfn)(struct sk_buff *)) ++{ ++ struct socket_smack *ssp; ++ struct smack_known *skp; ++ ++ if (skb && skb->sk && skb->sk->sk_security) { ++ ssp = skb->sk->sk_security; ++ skp = ssp->smk_out; ++ skb->secmark = skp->smk_secid; ++ } ++ ++ return NF_ACCEPT; ++} ++ ++static struct nf_hook_ops smack_nf_ops[] = { ++ { ++ .hook = smack_ipv4_output, ++ .owner = THIS_MODULE, ++ .pf = NFPROTO_IPV4, ++ .hooknum = NF_INET_LOCAL_OUT, ++ .priority = NF_IP_PRI_SELINUX_FIRST, ++ }, ++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) ++ { ++ .hook = smack_ipv6_output, ++ .owner = THIS_MODULE, ++ .pf = NFPROTO_IPV6, ++ .hooknum = NF_INET_LOCAL_OUT, ++ .priority = NF_IP6_PRI_SELINUX_FIRST, ++ }, ++#endif /* IPV6 */ ++}; ++ ++static int __init smack_nf_ip_init(void) ++{ ++ int err; ++ ++ if (smack_enabled == 0) ++ return 0; ++ ++ printk(KERN_DEBUG "Smack: Registering netfilter hooks\n"); ++ ++ err = nf_register_hooks(smack_nf_ops, ARRAY_SIZE(smack_nf_ops)); ++ if (err) ++ pr_info("Smack: nf_register_hooks: error %d\n", err); ++ ++ return 0; ++} ++ ++__initcall(smack_nf_ip_init); +-- +2.1.4 + |