From mboxrd@z Thu Jan 1 00:00:00 1970 Message-Id: <20061009195848.642381000@hp.com> References: <20061009194223.402695000@hp.com> Date: Mon, 09 Oct 2006 15:42:27 -0400 From: paul.moore@hp.com To: netdev@vger.kernel.org, selinux@tycho.nsa.gov Cc: vyekkirala@TrustedCS.com, jmorris@namei.org, sds@tycho.nsa.gov Subject: [PATCH 04/11] secid reconciliation: Invoke LSM hook for outbound traffic Sender: owner-selinux@tycho.nsa.gov List-Id: selinux@tycho.nsa.gov From: Venkat Yekkirala Invoke the skb_flow_out LSM hook for outbound traffic for secid reconciliation and flow control. Signed-off-by: Venkat Yekkirala --- net/netfilter/xt_CONNSECMARK.c | 72 ++++++++++++++++++++++++------- net/netfilter/xt_SECMARK.c | 45 ++++++++++++++++++- 2 files changed, 100 insertions(+), 17 deletions(-) diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c index 4673862..cca4a0c 100644 --- a/net/netfilter/xt_CONNSECMARK.c +++ b/net/netfilter/xt_CONNSECMARK.c @@ -17,6 +17,8 @@ */ #include #include +#include +#include #include #include #include @@ -29,38 +31,78 @@ MODULE_DESCRIPTION("ip[6]tables CONNSECM MODULE_ALIAS("ipt_CONNSECMARK"); MODULE_ALIAS("ip6t_CONNSECMARK"); +static inline int outbound(unsigned short family, unsigned int hooknum) +{ + if ((family == AF_INET && + (hooknum == NF_IP_POST_ROUTING || + hooknum == NF_IP_LOCAL_OUT || + hooknum == NF_IP_FORWARD)) || + (family == AF_INET6 && + (hooknum == NF_IP6_POST_ROUTING || + hooknum == NF_IP6_LOCAL_OUT || + hooknum == NF_IP6_FORWARD))) + return 1; + else + return 0; +} + /* * If the packet has a security mark and the connection does not, copy * the security mark from the packet to the connection. */ -static void secmark_save(struct sk_buff *skb) +static void secmark_save(struct sk_buff *skb, unsigned int hooknum) { if (skb->secmark) { u32 *connsecmark; enum ip_conntrack_info ctinfo; connsecmark = nf_ct_get_secmark(skb, &ctinfo); - if (connsecmark && !*connsecmark) + if (connsecmark) if (*connsecmark != skb->secmark) *connsecmark = skb->secmark; } } /* - * If packet has no security mark, and the connection does, restore the - * security mark from the connection to the packet. + * On the inbound, restore the security mark from the connection to the packet. + * On the outbound, filter based on the current secmark. */ -static void secmark_restore(struct sk_buff *skb) +static unsigned int secmark_restore(struct sk_buff *skb, unsigned int hooknum, + const struct net_device *in, unsigned short family) { - if (!skb->secmark) { - u32 *connsecmark; - enum ip_conntrack_info ctinfo; - - connsecmark = nf_ct_get_secmark(skb, &ctinfo); - if (connsecmark && *connsecmark) - if (skb->secmark != *connsecmark) - skb->secmark = *connsecmark; + u32 *psecmark; + enum ip_conntrack_info ctinfo; + + psecmark = nf_ct_get_secmark(skb, &ctinfo); + + if (psecmark && *psecmark) { + + /* Set secmark on inbound and filter it on outbound */ + if (outbound(family, hooknum)) { + int err; + + err = security_skb_flow_out(skb, *psecmark); + if (!err) + return NF_DROP; + } else + /* + * inbound: + * loopback traffic should already be labeled + * and any filtering on outbound should suffice + */ + if (in == &loopback_dev) + goto out; + + /* + * inbound or done with outbound check or no LSM hook + * for outbound + */ + if (skb->secmark != *psecmark) + skb->secmark = *psecmark; } + +out: + return XT_CONTINUE; } static unsigned int target(struct sk_buff **pskb, const struct net_device *in, @@ -73,11 +115,11 @@ static unsigned int target(struct sk_buf switch (info->mode) { case CONNSECMARK_SAVE: - secmark_save(skb); + secmark_save(skb, hooknum); break; case CONNSECMARK_RESTORE: - secmark_restore(skb); + return secmark_restore(skb, hooknum, in, target->family); break; default: diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c index add7521..9ecce66 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c @@ -15,8 +15,10 @@ #include #include #include +#include #include #include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("James Morris "); @@ -28,6 +30,21 @@ #define PFX "SECMARK: " static u8 mode; +static inline int outbound(unsigned short family, unsigned int hooknum) +{ + if ((family == AF_INET && + (hooknum == NF_IP_POST_ROUTING || + hooknum == NF_IP_LOCAL_OUT || + hooknum == NF_IP_FORWARD)) || + (family == AF_INET6 && + (hooknum == NF_IP6_POST_ROUTING || + hooknum == NF_IP6_LOCAL_OUT || + hooknum == NF_IP6_FORWARD))) + return 1; + else + return 0; +} + static unsigned int target(struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, unsigned int hooknum, const struct xt_target *target, @@ -47,9 +64,33 @@ static unsigned int target(struct sk_buf BUG(); } - if ((*pskb)->secmark != secmark) - (*pskb)->secmark = secmark; + if (secmark) { + + /* Set secmark on inbound and filter it on outbound */ + if (outbound(target->family, hooknum)) { + int err; + + err = security_skb_flow_out(*pskb, secmark); + if (!err) + return NF_DROP; + } else + /* + * inbound: + * loopback traffic should already be labeled + * and any filtering on outbound should suffice + */ + if (in == &loopback_dev) + goto out; + + /* + * inbound or done with outbound check or no LSM hook + * for outbound + */ + if ((*pskb)->secmark != secmark) + (*pskb)->secmark = secmark; + } +out: return XT_CONTINUE; } -- paul moore linux security @ hp -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. From mboxrd@z Thu Jan 1 00:00:00 1970 From: paul.moore@hp.com Subject: [PATCH 04/11] secid reconciliation: Invoke LSM hook for outbound traffic Date: Mon, 09 Oct 2006 15:42:27 -0400 Message-ID: <20061009195848.642381000@hp.com> References: <20061009194223.402695000@hp.com> Cc: vyekkirala@TrustedCS.com, jmorris@namei.org, sds@tycho.nsa.gov Return-path: Received: from atlrel9.hp.com ([156.153.255.214]:62391 "EHLO atlrel9.hp.com") by vger.kernel.org with ESMTP id S933017AbWJIT6u (ORCPT ); Mon, 9 Oct 2006 15:58:50 -0400 To: netdev@vger.kernel.org, selinux@tycho.nsa.gov Content-Disposition: inline; filename=secid-4 Sender: netdev-owner@vger.kernel.org List-Id: netdev.vger.kernel.org From: Venkat Yekkirala Invoke the skb_flow_out LSM hook for outbound traffic for secid reconciliation and flow control. Signed-off-by: Venkat Yekkirala --- net/netfilter/xt_CONNSECMARK.c | 72 ++++++++++++++++++++++++------- net/netfilter/xt_SECMARK.c | 45 ++++++++++++++++++- 2 files changed, 100 insertions(+), 17 deletions(-) diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c index 4673862..cca4a0c 100644 --- a/net/netfilter/xt_CONNSECMARK.c +++ b/net/netfilter/xt_CONNSECMARK.c @@ -17,6 +17,8 @@ */ #include #include +#include +#include #include #include #include @@ -29,38 +31,78 @@ MODULE_DESCRIPTION("ip[6]tables CONNSECM MODULE_ALIAS("ipt_CONNSECMARK"); MODULE_ALIAS("ip6t_CONNSECMARK"); +static inline int outbound(unsigned short family, unsigned int hooknum) +{ + if ((family == AF_INET && + (hooknum == NF_IP_POST_ROUTING || + hooknum == NF_IP_LOCAL_OUT || + hooknum == NF_IP_FORWARD)) || + (family == AF_INET6 && + (hooknum == NF_IP6_POST_ROUTING || + hooknum == NF_IP6_LOCAL_OUT || + hooknum == NF_IP6_FORWARD))) + return 1; + else + return 0; +} + /* * If the packet has a security mark and the connection does not, copy * the security mark from the packet to the connection. */ -static void secmark_save(struct sk_buff *skb) +static void secmark_save(struct sk_buff *skb, unsigned int hooknum) { if (skb->secmark) { u32 *connsecmark; enum ip_conntrack_info ctinfo; connsecmark = nf_ct_get_secmark(skb, &ctinfo); - if (connsecmark && !*connsecmark) + if (connsecmark) if (*connsecmark != skb->secmark) *connsecmark = skb->secmark; } } /* - * If packet has no security mark, and the connection does, restore the - * security mark from the connection to the packet. + * On the inbound, restore the security mark from the connection to the packet. + * On the outbound, filter based on the current secmark. */ -static void secmark_restore(struct sk_buff *skb) +static unsigned int secmark_restore(struct sk_buff *skb, unsigned int hooknum, + const struct net_device *in, unsigned short family) { - if (!skb->secmark) { - u32 *connsecmark; - enum ip_conntrack_info ctinfo; - - connsecmark = nf_ct_get_secmark(skb, &ctinfo); - if (connsecmark && *connsecmark) - if (skb->secmark != *connsecmark) - skb->secmark = *connsecmark; + u32 *psecmark; + enum ip_conntrack_info ctinfo; + + psecmark = nf_ct_get_secmark(skb, &ctinfo); + + if (psecmark && *psecmark) { + + /* Set secmark on inbound and filter it on outbound */ + if (outbound(family, hooknum)) { + int err; + + err = security_skb_flow_out(skb, *psecmark); + if (!err) + return NF_DROP; + } else + /* + * inbound: + * loopback traffic should already be labeled + * and any filtering on outbound should suffice + */ + if (in == &loopback_dev) + goto out; + + /* + * inbound or done with outbound check or no LSM hook + * for outbound + */ + if (skb->secmark != *psecmark) + skb->secmark = *psecmark; } + +out: + return XT_CONTINUE; } static unsigned int target(struct sk_buff **pskb, const struct net_device *in, @@ -73,11 +115,11 @@ static unsigned int target(struct sk_buf switch (info->mode) { case CONNSECMARK_SAVE: - secmark_save(skb); + secmark_save(skb, hooknum); break; case CONNSECMARK_RESTORE: - secmark_restore(skb); + return secmark_restore(skb, hooknum, in, target->family); break; default: diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c index add7521..9ecce66 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c @@ -15,8 +15,10 @@ #include #include #include +#include #include #include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("James Morris "); @@ -28,6 +30,21 @@ #define PFX "SECMARK: " static u8 mode; +static inline int outbound(unsigned short family, unsigned int hooknum) +{ + if ((family == AF_INET && + (hooknum == NF_IP_POST_ROUTING || + hooknum == NF_IP_LOCAL_OUT || + hooknum == NF_IP_FORWARD)) || + (family == AF_INET6 && + (hooknum == NF_IP6_POST_ROUTING || + hooknum == NF_IP6_LOCAL_OUT || + hooknum == NF_IP6_FORWARD))) + return 1; + else + return 0; +} + static unsigned int target(struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, unsigned int hooknum, const struct xt_target *target, @@ -47,9 +64,33 @@ static unsigned int target(struct sk_buf BUG(); } - if ((*pskb)->secmark != secmark) - (*pskb)->secmark = secmark; + if (secmark) { + + /* Set secmark on inbound and filter it on outbound */ + if (outbound(target->family, hooknum)) { + int err; + + err = security_skb_flow_out(*pskb, secmark); + if (!err) + return NF_DROP; + } else + /* + * inbound: + * loopback traffic should already be labeled + * and any filtering on outbound should suffice + */ + if (in == &loopback_dev) + goto out; + + /* + * inbound or done with outbound check or no LSM hook + * for outbound + */ + if ((*pskb)->secmark != secmark) + (*pskb)->secmark = secmark; + } +out: return XT_CONTINUE; } -- paul moore linux security @ hp