diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/include/linux/netfilter/xt_SECMARK.h linux-2.6.17-rc3-git7.w/include/linux/netfilter/xt_SECMARK.h --- linux-2.6.17-rc3-git7.p/include/linux/netfilter/xt_SECMARK.h 2006-05-09 19:56:11.000000000 -0400 +++ linux-2.6.17-rc3-git7.w/include/linux/netfilter/xt_SECMARK.h 2006-05-10 18:20:50.000000000 -0400 @@ -7,6 +7,10 @@ * * 'mode' refers to the specific security subsystem which the * packets are being marked for. + * + * The 'track' flag is used to request that the security marking also be + * applied to the associated conntrack, if the conntrack is not labeled + * already. */ #define SECMARK_MODE_SEL 0x01 /* SELinux */ #define SECMARK_SELCTX_MAX 256 @@ -17,7 +21,8 @@ struct xt_secmark_target_selinux_info { }; struct xt_secmark_target_info { - u_int8_t mode; + u_int32_t mode:8, + track:1; union { struct xt_secmark_target_selinux_info sel; } u; diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.17-rc3-git7.w/include/linux/netfilter_ipv4/ip_conntrack.h --- linux-2.6.17-rc3-git7.p/include/linux/netfilter_ipv4/ip_conntrack.h 2006-05-10 17:56:42.000000000 -0400 +++ linux-2.6.17-rc3-git7.w/include/linux/netfilter_ipv4/ip_conntrack.h 2006-05-10 11:59:17.000000000 -0400 @@ -121,6 +121,10 @@ struct ip_conntrack u_int32_t mark; #endif +#ifdef CONFIG_IP_NF_CONNTRACK_SECMARK + u_int32_t secmark; +#endif + /* Traversed often, so hopefully in different cacheline to top */ /* These are my tuples; original and reply */ struct ip_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX]; diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/include/net/netfilter/nf_conntrack_compat.h linux-2.6.17-rc3-git7.w/include/net/netfilter/nf_conntrack_compat.h --- linux-2.6.17-rc3-git7.p/include/net/netfilter/nf_conntrack_compat.h 2006-05-10 17:56:42.000000000 -0400 +++ linux-2.6.17-rc3-git7.w/include/net/netfilter/nf_conntrack_compat.h 2006-05-10 00:39:46.000000000 -0400 @@ -20,6 +20,19 @@ static inline u_int32_t *nf_ct_get_mark( } #endif /* CONFIG_IP_NF_CONNTRACK_MARK */ +#ifdef CONFIG_IP_NF_CONNTRACK_SECMARK +static inline u_int32_t *nf_ct_get_secmark(const struct sk_buff *skb, + u_int32_t *ctinfo) +{ + struct ip_conntrack *ct = ip_conntrack_get(skb, ctinfo); + + if (ct) + return &ct->secmark; + else + return NULL; +} +#endif /* CONFIG_IP_NF_CONNTRACK_SECMARK */ + #ifdef CONFIG_IP_NF_CT_ACCT static inline struct ip_conntrack_counter * nf_ct_get_counters(const struct sk_buff *skb) @@ -70,6 +83,19 @@ static inline u_int32_t *nf_ct_get_mark( } #endif /* CONFIG_NF_CONNTRACK_MARK */ +#ifdef CONFIG_NF_CONNTRACK_SECMARK +static inline u_int32_t *nf_ct_get_secmark(const struct sk_buff *skb, + u_int32_t *ctinfo) +{ + struct nf_conn *ct = nf_ct_get(skb, ctinfo); + + if (ct) + return &ct->secmark; + else + return NULL; +} +#endif /* CONFIG_NF_CONNTRACK_MARK */ + #ifdef CONFIG_NF_CT_ACCT static inline struct ip_conntrack_counter * nf_ct_get_counters(const struct sk_buff *skb) diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/include/net/netfilter/nf_conntrack.h linux-2.6.17-rc3-git7.w/include/net/netfilter/nf_conntrack.h --- linux-2.6.17-rc3-git7.p/include/net/netfilter/nf_conntrack.h 2006-05-03 10:25:01.000000000 -0400 +++ linux-2.6.17-rc3-git7.w/include/net/netfilter/nf_conntrack.h 2006-05-10 11:58:34.000000000 -0400 @@ -114,6 +114,10 @@ struct nf_conn u_int32_t mark; #endif +#ifdef CONFIG_NF_CONNTRACK_SECMARK + u_int32_t secmark; +#endif + /* Storage reserved for other modules: */ union nf_conntrack_proto proto; diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.6.17-rc3-git7.w/net/ipv4/netfilter/ip_conntrack_standalone.c --- linux-2.6.17-rc3-git7.p/net/ipv4/netfilter/ip_conntrack_standalone.c 2006-05-10 17:56:42.000000000 -0400 +++ linux-2.6.17-rc3-git7.w/net/ipv4/netfilter/ip_conntrack_standalone.c 2006-05-10 17:58:03.000000000 -0400 @@ -189,6 +189,11 @@ static int ct_seq_show(struct seq_file * return -ENOSPC; #endif +#ifdef CONFIG_IP_NF_CONNTRACK_SECMARK + if (seq_printf(s, "secmark=%u ", conntrack->secmark)) + return -ENOSPC; +#endif + if (seq_printf(s, "use=%u\n", atomic_read(&conntrack->ct_general.use))) return -ENOSPC; diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/net/ipv4/netfilter/Kconfig linux-2.6.17-rc3-git7.w/net/ipv4/netfilter/Kconfig --- linux-2.6.17-rc3-git7.p/net/ipv4/netfilter/Kconfig 2006-05-10 17:56:42.000000000 -0400 +++ linux-2.6.17-rc3-git7.w/net/ipv4/netfilter/Kconfig 2006-05-10 18:09:02.000000000 -0400 @@ -55,6 +55,16 @@ config IP_NF_CONNTRACK_MARK of packets, but this mark value is kept in the conntrack session instead of the individual packets. +config IP_NF_CONNTRACK_SECMARK + bool 'Connection tracking security mark support' + depends on IP_NF_CONNTRACK + help + This option enables security markings to be applied to + connections; typically copied from packet markings + via the the iptables SECMARK target. + + If unsure, say 'N'. + config IP_NF_CONNTRACK_EVENTS bool "Connection tracking events (EXPERIMENTAL)" depends on EXPERIMENTAL && IP_NF_CONNTRACK diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/net/netfilter/Kconfig linux-2.6.17-rc3-git7.w/net/netfilter/Kconfig --- linux-2.6.17-rc3-git7.p/net/netfilter/Kconfig 2006-05-10 17:56:42.000000000 -0400 +++ linux-2.6.17-rc3-git7.w/net/netfilter/Kconfig 2006-05-10 18:12:32.000000000 -0400 @@ -60,6 +60,16 @@ config NF_CONNTRACK_MARK of packets, but this mark value is kept in the conntrack session instead of the individual packets. +config NF_CONNTRACK_SECMARK + bool 'Connection tracking security mark support' + depends on NF_CONNTRACK + help + This option enables security markings to be applied to + connections; typically copied from packet markings + via the the iptables SECMARK target. + + If unsure, say 'N'. + config NF_CONNTRACK_EVENTS bool "Connection tracking events (EXPERIMENTAL)" depends on EXPERIMENTAL && NF_CONNTRACK diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/net/netfilter/nf_conntrack_core.c linux-2.6.17-rc3-git7.w/net/netfilter/nf_conntrack_core.c --- linux-2.6.17-rc3-git7.p/net/netfilter/nf_conntrack_core.c 2006-05-10 17:56:42.000000000 -0400 +++ linux-2.6.17-rc3-git7.w/net/netfilter/nf_conntrack_core.c 2006-05-10 18:22:10.000000000 -0400 @@ -990,6 +990,9 @@ init_conntrack(const struct nf_conntrack #ifdef CONFIG_NF_CONNTRACK_MARK conntrack->mark = exp->master->mark; #endif +#ifdef CONFIG_NF_CONNTRACK_SECMARK + conntrack->secmark = exp->master->secmark; +#endif nf_conntrack_get(&conntrack->master->ct_general); NF_CT_STAT_INC(expect_new); } else diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/net/netfilter/nf_conntrack_standalone.c linux-2.6.17-rc3-git7.w/net/netfilter/nf_conntrack_standalone.c --- linux-2.6.17-rc3-git7.p/net/netfilter/nf_conntrack_standalone.c 2006-05-10 17:56:42.000000000 -0400 +++ linux-2.6.17-rc3-git7.w/net/netfilter/nf_conntrack_standalone.c 2006-05-10 00:45:57.000000000 -0400 @@ -213,6 +213,11 @@ static int ct_seq_show(struct seq_file * return -ENOSPC; #endif +#if defined(CONFIG_NF_CONNTRACK_SECMARK) + if (seq_printf(s, "secmark=%u ", conntrack->secmark)) + return -ENOSPC; +#endif + if (seq_printf(s, "use=%u\n", atomic_read(&conntrack->ct_general.use))) return -ENOSPC; diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/net/netfilter/xt_SECMARK.c linux-2.6.17-rc3-git7.w/net/netfilter/xt_SECMARK.c --- linux-2.6.17-rc3-git7.p/net/netfilter/xt_SECMARK.c 2006-05-09 19:56:53.000000000 -0400 +++ linux-2.6.17-rc3-git7.w/net/netfilter/xt_SECMARK.c 2006-05-11 01:10:54.000000000 -0400 @@ -17,6 +17,7 @@ #include #include #include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("James Morris "); @@ -28,6 +29,37 @@ MODULE_ALIAS("ip6t_SECMARK"); static u8 mode; +#ifdef CONFIG_IP_NF_CONNTRACK_SECMARK +static inline void secmark_conntrack(struct sk_buff **pskb, u32 secmark, + const struct xt_secmark_target_info *info) +{ + if (info->track) { + u32 *connsecmark; + enum ip_conntrack_info ctinfo; + + /* If connection is unlabeled, copy packet label to it */ + connsecmark = nf_ct_get_secmark(*pskb, &ctinfo); + if (connsecmark && *connsecmark == 0) { + if (*connsecmark != secmark) + *connsecmark = secmark; + } + } +} + +static inline int tracking_enabled(void) +{ + return 1; +} +#else +static inline void secmark_conntrack(struct sk_buff **pskb, const struct xt_secmark_target_info *info) +{ } + +static inline int tracking_enabled(void) +{ + return 0; +} +#endif + 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, @@ -49,7 +81,9 @@ static unsigned int target(struct sk_buf if ((*pskb)->secmark != secmark) (*pskb)->secmark = secmark; - + + secmark_conntrack(pskb, secmark, info); + return XT_CONTINUE; } @@ -58,6 +92,12 @@ static int checkentry_selinux(struct xt_ int err; struct xt_secmark_target_selinux_info *sel = &info->u.sel; + if (info->track && !tracking_enabled()) { + printk(KERN_INFO PFX "--track option invalid unless " + "conntrack and conntrack security marking enabled\n"); + return 0; + } + err = selinux_string_to_sid(sel->selctx, &sel->selsid); if (err) { if (err == -EINVAL) @@ -135,6 +175,9 @@ static int __init xt_secmark_init(void) { int err; + if (tracking_enabled()) + need_conntrack(); + err = xt_register_target(&ipt_secmark_reg); if (err) return err;