secid reconciliation-v03: Invoke LSM hook for outbound traffic
Subsystems (5)
PATCH 4/7 secid reconciliation-v03: Invoke LSM hook for outbound traffic
Invoke the skb_flow_out LSM hook for outbound traffic for secid reconciliation and flow control.
--- net/netfilter/xt_CONNSECMARK.c | 70 +++++++++++++++++++++++-------- net/netfilter/xt_SECMARK.c | 33 +++++++++++++- 2 files changed, 85 insertions(+), 18 deletions(-)
net/netfilter/xt_CONNSECMARK.c +54 -16
@@ -17,6 +17,8 @@*/ #include <linux/module.h> #include <linux/skbuff.h> +#include <linux/security.h> +#include <linux/netfilter_ipv6.h> #include <linux/netfilter/x_tables.h> #include <linux/netfilter/xt_CONNSECMARK.h> #include <net/netfilter/nf_conntrack_compat.h>
@@ -33,34 +35,70 @@ MODULE_ALIAS("ip6t_CONNSECMARK");* 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, +const struct xt_target *target) {if (skb->secmark) {u32 *connsecmark;enum ip_conntrack_info ctinfo; connsecmark =nf_ct_get_secmark (skb, &ctinfo); -if (connsecmark && !*connsecmark) -if (*connsecmark != skb->secmark) +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,const struct xt_target *target) { -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) { + +printk (KERN_ERR "IN HOOK (%d) (%u) (%u)\n" , hooknum, skb->secmark, *psecmark); +/* Set secmark on inbound and filter it on outbound */ +if ((target->family ==AF_INET && + (hooknum ==NF_IP_POST_ROUTING || + hooknum ==NF_IP_LOCAL_OUT || + hooknum ==NF_IP_FORWARD )) || + (target->family ==AF_INET6 && + (hooknum ==NF_IP6_POST_ROUTING || + hooknum ==NF_IP6_LOCAL_OUT || + hooknum ==NF_IP6_FORWARD ))) { +/* outbound */ +int err; + + err =security_skb_flow_out (skb, *psecmark); +printk (KERN_ERR "ERR (%d) (%u)\n" , err, skb->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 (skb->secmark != *psecmark) +{ +printk (KERN_ERR "RESTORING FROM (%u) TO (%u) (%u)\n" , skb->secmark, *psecmark,0xffffffff ); + skb->secmark = *psecmark; +} } + +out: +return XT_CONTINUE ; } static unsigned int target(struct sk_buff **pskb, const struct net_device *in,
@@ -73,11 +111,11 @@ static unsigned int target(struct sk_bufswitch (info->mode) {case CONNSECMARK_SAVE : -secmark_save (skb); +secmark_save (skb, hooknum, target);break ;case CONNSECMARK_RESTORE : -secmark_restore (skb); +return secmark_restore (skb, hooknum, in, target);break ;default :
net/netfilter/xt_SECMARK.c +31 -2
@@ -15,8 +15,10 @@#include <linux/module.h> #include <linux/skbuff.h> #include <linux/selinux.h> +#include <linux/security.h> #include <linux/netfilter/x_tables.h> #include <linux/netfilter/xt_SECMARK.h> +#include <linux/netfilter_ipv6.h> MODULE_LICENSE ("GPL" );MODULE_AUTHOR ("James Morris <[email protected]>" );
@@ -47,9 +49,36 @@ static unsigned int target(struct sk_bufBUG (); } -if ((*pskb)->secmark != secmark) - (*pskb)->secmark = secmark; +if (secmark) { + +/* Set secmark on inbound and filter it on outbound */ +if ((target->family ==AF_INET && + (hooknum ==NF_IP_POST_ROUTING || + hooknum ==NF_IP_LOCAL_OUT || + hooknum ==NF_IP_FORWARD )) || + (target->family ==AF_INET6 && + (hooknum ==NF_IP6_POST_ROUTING || + hooknum ==NF_IP6_LOCAL_OUT || + hooknum ==NF_IP6_FORWARD ))) { +/* outbound */ +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 no LSM hook for outbound */ +if ((*pskb)->secmark != secmark) + (*pskb)->secmark = secmark; + } +out:return XT_CONTINUE ; }
--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.
net/netfilter/xt_CONNSECMARK.c MODULE_ALIAS("ip6t_CONNSECMARK"); · line 49
Quoted 4 lines · Venkat Yekkirala
net/netfilter/xt_CONNSECMARK.c +3
-0+if (connsecmark) +if (*connsecmark != skb->secmark) { *connsecmark = skb->secmark; + }
Please remove the braces if re-submitting.
Quoted 1 line
+printk(KERN_ERR "IN HOOK (%d) (%u) (%u)\n", hooknum,
skb->secmark, *psecmark);\
Please remove debugging (here and elsewhere).
net/netfilter/xt_CONNSECMARK.c MODULE_ALIAS("ip6t_CONNSECMARK"); · line 76
Quoted 9 lines
net/netfilter/xt_CONNSECMARK.c +9
-0+/* Set secmark on inbound and filter it on outbound */ +if ((target->family ==AF_INET && + (hooknum ==NF_IP_POST_ROUTING || + hooknum ==NF_IP_LOCAL_OUT || + hooknum ==NF_IP_FORWARD )) || + (target->family ==AF_INET6 && + (hooknum ==NF_IP6_POST_ROUTING || + hooknum ==NF_IP6_LOCAL_OUT || + hooknum ==NF_IP6_FORWARD ))) {
I think this should be a separate helper function, so the logic can be changed/evaluated in isolation (preferred, but not a blocker).
net/netfilter/xt_CONNSECMARK.c static unsigned int target(struct sk_buf · line 114
Quoted 1 line
net/netfilter/xt_CONNSECMARK.c +1
-0+secmark_save (skb, hooknum, target);
It seems that the target parameter is not needed.
net/netfilter/xt_CONNSECMARK.c static unsigned int target(struct sk_buf · line 118
Quoted 1 line
net/netfilter/xt_CONNSECMARK.c +1
-0+return secmark_restore (skb, hooknum, in, target);
Please pass a family parameter instead of target.
Signature · 2 lines
James Morris <[email protected]>
net/netfilter/xt_CONNSECMARK.c MODULE_ALIAS("ip6t_CONNSECMARK"); · line 89
Quoted 6 lines · Venkat Yekkirala
net/netfilter/xt_CONNSECMARK.c +6
-0+ } +else /* inbound */ +/* loopback traffic should already be labeled +and any filtering on outbound should suffice */ +if (in == &loopback_dev) + goto out;
Minor nit that akpm will point out, the else belongs on the same line as the brace. Also, the comment style is:
/* * Comment... * etc. */
- James
Signature · 2 lines
James Morris <[email protected]>