summaryrefslogtreecommitdiffstats
path: root/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0050-Smack-secmark-support-for-netfilter.patch
diff options
context:
space:
mode:
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.patch448
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
+