netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC] SECMARK 1.0
@ 2006-05-07 15:31 James Morris
  2006-05-07 15:33 ` [RFC] [SECMARK 01/08] Add secmark support to core networking James Morris
                   ` (13 more replies)
  0 siblings, 14 replies; 41+ messages in thread
From: James Morris @ 2006-05-07 15:31 UTC (permalink / raw)
  To: selinux; +Cc: netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

The following patchsets implement a new scheme for adding security 
markings to packets via iptables, as well as changes to SELinux to use 
these markings for security policy enforcement.

Along with these patches, assorted files including policy examples and 
patches for SELinux userland may be found at:
http://people.redhat.com/jmorris/selinux/secmark/

The requirements for secmark arise from the current per-packet network 
controls in SELinux, which are rudimentary, and not as expressive or 
powerful as the controls provided by Netfilter/iptables.

Thus, the idea is to leverage Netfilter/iptables for packet selection and 
labeling, so that SELinux can have more powerful and expressive network 
controls.  This also allows for increased security, as the policy is more 
effective, allowing access to the full range of iptables selectors and 
support mechanisms.

For example, SELinux will now be able to utilize connection tracking, so 
that only packets which are known to be valid for a specific connection 
will be allowed to reach the subject.

Sample iptables rules for labeling packets are at:
http://people.redhat.com/jmorris/selinux/secmark/rules/

And examples of new policy controls may be found here:
http://people.redhat.com/jmorris/selinux/secmark/policy/


The sample policy for ftpd demonstrates how the vsftpd server can be 
confined so that it only receives SYN packets on the ftp control port for 
new connections, as well as any packets related to the ftp control or data 
connections and related ICMP packets.  It is also allowed to send DNS 
requests.

Note that only the per-packet network controls are being replaced -- the 
existing socket-based controls such as name_bind, node_bind and 
name_connect are being retained as they are useful for applications in 
that they return error messages in response to socket calls, and prevent, 
for example, an application from binding to specific local IP addresses.

Also, this local packet marking is orthogonal to the xfrm network labeling 
(which is for mediating access based on the security context of the 
endpoints across a network connection).


Please review these patches and let me know if there are any queries.

I would like to get the kernel components upstream in the 2.6.18 merge 
window.


- James
-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [RFC] [SECMARK 01/08] Add secmark support to core networking
  2006-05-07 15:31 [RFC] SECMARK 1.0 James Morris
@ 2006-05-07 15:33 ` James Morris
  2006-05-07 15:34 ` [RFC][SECMARK 02/08] Export selinux_string_to_sid from SELinux James Morris
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 41+ messages in thread
From: James Morris @ 2006-05-07 15:33 UTC (permalink / raw)
  To: selinux; +Cc: netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

This patch adds a secmark field to the skbuff structure, to allow security 
subsystems to place security markings on network packets.  This is similar 
to the nfmark field, except is intended for implementing security policy, 
rather than than networking policy.

This patch was already acked in principle by Dave Miller.


Signed-off-by: James Morris <jmorris@namei.org>

---

 include/linux/skbuff.h          |   22 ++++++++++++++++++++++
 net/Kconfig                     |    7 +++++++
 net/core/skbuff.c               |    3 ++-
 net/ipv4/ip_output.c            |    1 +
 net/ipv4/netfilter/ipt_REJECT.c |    1 +
 net/ipv6/ip6_output.c           |    1 +
 6 files changed, 34 insertions(+), 1 deletion(-)

diff -purN -X dontdiff linux-2.6.17-rc2-mm1.p/include/linux/skbuff.h linux-2.6.17-rc2-mm1.w/include/linux/skbuff.h
--- linux-2.6.17-rc2-mm1.p/include/linux/skbuff.h	2006-04-27 10:44:26.000000000 -0400
+++ linux-2.6.17-rc2-mm1.w/include/linux/skbuff.h	2006-04-27 23:43:32.000000000 -0400
@@ -209,6 +209,7 @@ enum {
  *	@nf_bridge: Saved data about a bridged frame - see br_netfilter.c
  *	@tc_index: Traffic control index
  *	@tc_verd: traffic control verdict
+ *	@secmark: security marking
  */
 
 struct sk_buff {
@@ -285,6 +286,9 @@ struct sk_buff {
 	__u16			tc_verd;	/* traffic control verdict */
 #endif
 #endif
+#ifdef CONFIG_NETWORK_SECMARK
+	__u32			secmark;
+#endif
 
 
 	/* These elements must be at the end, see alloc_skb() for details.  */
@@ -1396,5 +1400,23 @@ static inline void nf_reset(struct sk_bu
 static inline void nf_reset(struct sk_buff *skb) {}
 #endif /* CONFIG_NETFILTER */
 
+#ifdef CONFIG_NETWORK_SECMARK
+static inline void skb_copy_secmark(struct sk_buff *to, const struct sk_buff *from)
+{
+	to->secmark = from->secmark;
+}
+
+static inline void skb_init_secmark(struct sk_buff *skb)
+{
+	skb->secmark = 0;
+}
+#else
+static inline void skb_copy_secmark(struct sk_buff *to, const struct sk_buff *from)
+{ }
+
+static inline void skb_init_secmark(struct sk_buff *skb)
+{ }
+#endif
+
 #endif	/* __KERNEL__ */
 #endif	/* _LINUX_SKBUFF_H */
diff -purN -X dontdiff linux-2.6.17-rc2-mm1.p/net/core/skbuff.c linux-2.6.17-rc2-mm1.w/net/core/skbuff.c
--- linux-2.6.17-rc2-mm1.p/net/core/skbuff.c	2006-04-27 10:44:26.000000000 -0400
+++ linux-2.6.17-rc2-mm1.w/net/core/skbuff.c	2006-04-27 23:43:32.000000000 -0400
@@ -464,7 +464,7 @@ struct sk_buff *skb_clone(struct sk_buff
 	n->tc_verd = CLR_TC_MUNGED(n->tc_verd);
 	C(input_dev);
 #endif
-
+	skb_copy_secmark(n, skb);
 #endif
 	C(truesize);
 	atomic_set(&n->users, 1);
@@ -526,6 +526,7 @@ static void copy_skb_header(struct sk_bu
 #endif
 	new->tc_index	= old->tc_index;
 #endif
+	skb_copy_secmark(new, old);
 	atomic_set(&new->users, 1);
 	skb_shinfo(new)->tso_size = skb_shinfo(old)->tso_size;
 	skb_shinfo(new)->tso_segs = skb_shinfo(old)->tso_segs;
diff -purN -X dontdiff linux-2.6.17-rc2-mm1.p/net/ipv4/ip_output.c linux-2.6.17-rc2-mm1.w/net/ipv4/ip_output.c
--- linux-2.6.17-rc2-mm1.p/net/ipv4/ip_output.c	2006-04-19 23:31:25.000000000 -0400
+++ linux-2.6.17-rc2-mm1.w/net/ipv4/ip_output.c	2006-04-27 23:43:32.000000000 -0400
@@ -410,6 +410,7 @@ static void ip_copy_metadata(struct sk_b
 	nf_bridge_get(to->nf_bridge);
 #endif
 #endif
+	skb_copy_secmark(to, from);
 }
 
 /*
diff -purN -X dontdiff linux-2.6.17-rc2-mm1.p/net/ipv4/netfilter/ipt_REJECT.c linux-2.6.17-rc2-mm1.w/net/ipv4/netfilter/ipt_REJECT.c
--- linux-2.6.17-rc2-mm1.p/net/ipv4/netfilter/ipt_REJECT.c	2006-04-19 23:31:25.000000000 -0400
+++ linux-2.6.17-rc2-mm1.w/net/ipv4/netfilter/ipt_REJECT.c	2006-04-27 23:43:32.000000000 -0400
@@ -147,6 +147,7 @@ static void send_reset(struct sk_buff *o
 	/* This packet will not be the same as the other: clear nf fields */
 	nf_reset(nskb);
 	nskb->nfmark = 0;
+	skb_init_secmark(nskb);
 
 	tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
 
diff -purN -X dontdiff linux-2.6.17-rc2-mm1.p/net/ipv6/ip6_output.c linux-2.6.17-rc2-mm1.w/net/ipv6/ip6_output.c
--- linux-2.6.17-rc2-mm1.p/net/ipv6/ip6_output.c	2006-04-19 23:31:25.000000000 -0400
+++ linux-2.6.17-rc2-mm1.w/net/ipv6/ip6_output.c	2006-04-27 23:43:32.000000000 -0400
@@ -458,6 +458,7 @@ static void ip6_copy_metadata(struct sk_
 	nf_bridge_get(to->nf_bridge);
 #endif
 #endif
+	skb_copy_secmark(to, from);
 }
 
 int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
diff -purN -X dontdiff linux-2.6.17-rc2-mm1.p/net/Kconfig linux-2.6.17-rc2-mm1.w/net/Kconfig
--- linux-2.6.17-rc2-mm1.p/net/Kconfig	2006-04-19 23:31:25.000000000 -0400
+++ linux-2.6.17-rc2-mm1.w/net/Kconfig	2006-04-27 23:43:32.000000000 -0400
@@ -66,6 +66,13 @@ source "net/ipv6/Kconfig"
 
 endif # if INET
 
+config NETWORK_SECMARK
+	bool "Security Marking"
+	help
+	  This enables security marking of network packets, similar
+	  to nfmark, but designated for security purposes.
+	  If you are unsure how to answer this question, answer N.
+
 menuconfig NETFILTER
 	bool "Network packet filtering (replaces ipchains)"
 	---help---

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [RFC][SECMARK 02/08] Export selinux_string_to_sid from SELinux
  2006-05-07 15:31 [RFC] SECMARK 1.0 James Morris
  2006-05-07 15:33 ` [RFC] [SECMARK 01/08] Add secmark support to core networking James Morris
@ 2006-05-07 15:34 ` James Morris
  2006-05-07 15:35 ` [RFC][SECMARK 03/08] Add xtables SECMARK target James Morris
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 41+ messages in thread
From: James Morris @ 2006-05-07 15:34 UTC (permalink / raw)
  To: selinux; +Cc: netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

This patch exports adds a new function to the in-kernel
SELinux API: selinux_string_to_sid().  It maps a text
security context to an SELiux security ID (SID).


Signed-off-by: James Morris <jmorris@namei.org>

---

 include/linux/selinux.h    |   16 ++++++++++++++++
 security/selinux/exports.c |   11 +++++++++++
 2 files changed, 27 insertions(+)

diff -purN -X dontdiff linux-2.6.17-rc2-mm1.p/include/linux/selinux.h linux-2.6.17-rc2-mm1.w/include/linux/selinux.h
--- linux-2.6.17-rc2-mm1.p/include/linux/selinux.h	2006-04-27 10:44:26.000000000 -0400
+++ linux-2.6.17-rc2-mm1.w/include/linux/selinux.h	2006-04-28 00:53:27.000000000 -0400
@@ -118,6 +118,16 @@ void selinux_get_ipc_sid(const struct ke
  */
 void selinux_get_task_sid(struct task_struct *tsk, u32 *sid);
 
+/**
+ *     selinux_string_to_sid - map a security context string to a security ID
+ *     @str: the security context string to be mapped
+ *     @sid: ID value returned via this.
+ *
+ *     Returns 0 if successful, with the SID stored in sid.  A value
+ *     of zero for sid indicates no SID could be determined (but no error
+ *     occurred).
+ */
+int selinux_string_to_sid(char *str, u32 *sid);
 
 #else
 
@@ -172,6 +182,12 @@ static inline void selinux_get_task_sid(
 	*sid = 0;
 }
 
+static inline int selinux_string_to_sid(const char *str, u32 *sid)
+{
+       *sid = 0;
+       return 0;
+}
+
 #endif	/* CONFIG_SECURITY_SELINUX */
 
 #endif /* _LINUX_SELINUX_H */
diff -purN -X dontdiff linux-2.6.17-rc2-mm1.p/security/selinux/exports.c linux-2.6.17-rc2-mm1.w/security/selinux/exports.c
--- linux-2.6.17-rc2-mm1.p/security/selinux/exports.c	2006-04-27 10:44:26.000000000 -0400
+++ linux-2.6.17-rc2-mm1.w/security/selinux/exports.c	2006-04-28 00:51:25.000000000 -0400
@@ -72,3 +72,14 @@ void selinux_get_task_sid(struct task_st
 	*sid = 0;
 }
 
+int selinux_string_to_sid(char *str, u32 *sid)
+{
+	if (selinux_enabled)
+		return security_context_to_sid(str, strlen(str), sid);
+	else {
+		*sid = 0;
+		return 0;
+	}
+}
+EXPORT_SYMBOL_GPL(selinux_string_to_sid);
+

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [RFC][SECMARK 03/08] Add xtables SECMARK target
  2006-05-07 15:31 [RFC] SECMARK 1.0 James Morris
  2006-05-07 15:33 ` [RFC] [SECMARK 01/08] Add secmark support to core networking James Morris
  2006-05-07 15:34 ` [RFC][SECMARK 02/08] Export selinux_string_to_sid from SELinux James Morris
@ 2006-05-07 15:35 ` James Morris
  2006-05-10  6:03   ` Patrick McHardy
  2006-05-07 15:36 ` [RFC][SECMARK 04/08] Add new flask definitions to SELinux James Morris
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 41+ messages in thread
From: James Morris @ 2006-05-07 15:35 UTC (permalink / raw)
  To: selinux; +Cc: netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

This patch adds a SECMARK target to xtables, allowing
the admin to apply security marks to packets via both
iptables and ip6tables.

The target currently handles SELinux security marking,
but can be extended for other purposes as needed.


Signed-off-by: James Morris <jmorris@namei.org>

---

 include/linux/netfilter/xt_SECMARK.h |   26 ++++++
 net/netfilter/Kconfig                |    9 ++
 net/netfilter/Makefile               |    1 
 net/netfilter/xt_SECMARK.c           |  150 +++++++++++++++++++++++++++++++++++
 4 files changed, 186 insertions(+)

diff -purN -X dontdiff linux-2.6.17-rc2.p/include/linux/netfilter/xt_SECMARK.h linux-2.6.17-rc2.w/include/linux/netfilter/xt_SECMARK.h
--- linux-2.6.17-rc2.p/include/linux/netfilter/xt_SECMARK.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.17-rc2.w/include/linux/netfilter/xt_SECMARK.h	2006-04-25 02:35:45.000000000 -0400
@@ -0,0 +1,26 @@
+#ifndef _XT_SECMARK_H_target
+#define _XT_SECMARK_H_target
+
+/*
+ * This is intended for use by various security subsystems (but not
+ * at the same time).
+ *
+ * 'mode' refers to the specific security subsystem which the 
+ * packets are being marked for.
+ */
+#define SECMARK_MODE_SEL	0x01		/* SELinux */
+#define SECMARK_SELCTX_MAX	256
+
+struct xt_secmark_target_selinux_info {
+	u_int32_t selsid;
+	char selctx[SECMARK_SELCTX_MAX];
+};
+
+struct xt_secmark_target_info {
+	u_int8_t mode;
+	union {
+		struct xt_secmark_target_selinux_info sel;
+	} u;
+};
+
+#endif /*_XT_SECMARK_H_target */
diff -purN -X dontdiff linux-2.6.17-rc2.p/net/netfilter/Kconfig linux-2.6.17-rc2.w/net/netfilter/Kconfig
--- linux-2.6.17-rc2.p/net/netfilter/Kconfig	2006-04-19 23:31:25.000000000 -0400
+++ linux-2.6.17-rc2.w/net/netfilter/Kconfig	2006-04-25 00:22:27.000000000 -0400
@@ -174,6 +174,15 @@ config NETFILTER_XT_TARGET_NOTRACK
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+config NETFILTER_XT_TARGET_SECMARK
+	tristate '"SECMARK" target support'
+	depends on NETFILTER_XTABLES && NETWORK_SECMARK
+	help
+	  The SECMARK target allows security marking of network
+	  packets, for use with security subsystems.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config NETFILTER_XT_MATCH_COMMENT
 	tristate  '"comment" match support'
 	depends on NETFILTER_XTABLES
diff -purN -X dontdiff linux-2.6.17-rc2.p/net/netfilter/Makefile linux-2.6.17-rc2.w/net/netfilter/Makefile
--- linux-2.6.17-rc2.p/net/netfilter/Makefile	2006-04-19 23:31:25.000000000 -0400
+++ linux-2.6.17-rc2.w/net/netfilter/Makefile	2006-04-25 00:22:27.000000000 -0400
@@ -28,6 +28,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMAR
 obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
 
 # matches
 obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o
diff -purN -X dontdiff linux-2.6.17-rc2.p/net/netfilter/xt_SECMARK.c linux-2.6.17-rc2.w/net/netfilter/xt_SECMARK.c
--- linux-2.6.17-rc2.p/net/netfilter/xt_SECMARK.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.17-rc2.w/net/netfilter/xt_SECMARK.c	2006-04-25 02:45:58.000000000 -0400
@@ -0,0 +1,150 @@
+/*
+ * Module for modifying the secmark field of the skb, for use by
+ * security subsystems.
+ *
+ * Based on the nfmark match by:
+ * (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
+ *
+ * (C) 2006 Red Hat, Inc., James Morris <jmorris@redhat.com>
+ *
+ * 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/module.h>
+#include <linux/skbuff.h>
+#include <linux/selinux.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_SECMARK.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("James Morris <jmorris@redhat.com>");
+MODULE_DESCRIPTION("ip[6]tables SECMARK modification module");
+MODULE_ALIAS("ipt_SECMARK");
+MODULE_ALIAS("ip6t_SECMARK");
+
+#define PFX "SECMARK: "
+
+static u8 mode;
+
+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,
+			   const void *targinfo, void *userinfo)
+{
+	u32 secmark = 0;
+	const struct xt_secmark_target_info *info = targinfo;
+
+	BUG_ON(info->mode != mode);
+
+	switch (mode) {
+	case SECMARK_MODE_SEL:
+		secmark = info->u.sel.selsid;
+		break;
+	
+	default:
+		BUG();
+	}
+	
+	if ((*pskb)->secmark != secmark)
+		(*pskb)->secmark = secmark;
+	
+	return XT_CONTINUE;
+}
+
+static int checkentry_selinux(struct xt_secmark_target_info *info)
+{
+	int err;
+	struct xt_secmark_target_selinux_info *sel = &info->u.sel;
+
+	err = selinux_string_to_sid(sel->selctx, &sel->selsid);
+	if (err) {
+		if (err == -EINVAL)
+			printk(KERN_INFO PFX "invalid SELinux context \'%s\'\n",
+			       sel->selctx);
+		return 0;
+	}
+	
+	if (!sel->selsid) {
+		printk(KERN_INFO PFX "unable to map SELinux context \'%s\'\n",
+		       sel->selctx);
+		return 0;
+	}
+
+	return 1;
+}
+
+static int checkentry(const char *tablename, const void *entry,
+		      const struct xt_target *target, void *targinfo,
+		      unsigned int targinfosize, unsigned int hook_mask)
+{
+	struct xt_secmark_target_info *info = targinfo;
+
+	if (mode && mode != info->mode) {
+		printk(KERN_INFO PFX "mode already set to %hhu cannot mix with "
+		       "rules for mode %hhu\n", mode, info->mode);
+		return 0;
+	}
+
+	switch (info->mode) {
+	case SECMARK_MODE_SEL:
+		if (!checkentry_selinux(info))
+			return 0;
+		break;
+	
+	default:
+		printk(KERN_INFO PFX "invalid mode: %hhu\n", info->mode);
+		return 0;
+	}
+	
+	if (!mode)
+		mode = info->mode;
+	return 1;
+}
+
+static struct xt_target ipt_secmark_reg = {
+	.name		= "SECMARK",
+	.target		= target,
+	.targetsize	= sizeof(struct xt_secmark_target_info),
+	.table		= "mangle",
+	.checkentry	= checkentry,
+	.me		= THIS_MODULE,
+	.family		= AF_INET,
+	.revision	= 0,
+};
+
+static struct xt_target ip6t_secmark_reg = {
+	.name		= "SECMARK",
+	.target		= target,
+	.targetsize	= sizeof(struct xt_secmark_target_info),
+	.table		= "mangle",
+	.checkentry	= checkentry,
+	.me		= THIS_MODULE,
+	.family		= AF_INET6,
+	.revision	= 0,
+};
+
+static int __init xt_secmark_init(void)
+{
+	int err;
+
+	err = xt_register_target(&ipt_secmark_reg);
+	if (err)
+		return err;
+
+	err = xt_register_target(&ip6t_secmark_reg);
+	if (err)
+		xt_unregister_target(&ipt_secmark_reg);
+
+	return err;
+}
+
+static void __exit xt_secmark_fini(void)
+{
+	xt_unregister_target(&ip6t_secmark_reg);
+	xt_unregister_target(&ipt_secmark_reg);
+}
+
+module_init(xt_secmark_init);
+module_exit(xt_secmark_fini);

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [RFC][SECMARK 04/08] Add new flask definitions to SELinux
  2006-05-07 15:31 [RFC] SECMARK 1.0 James Morris
                   ` (2 preceding siblings ...)
  2006-05-07 15:35 ` [RFC][SECMARK 03/08] Add xtables SECMARK target James Morris
@ 2006-05-07 15:36 ` James Morris
  2006-05-07 15:37 ` [RFC][SECMARK 05/08] Add new packet controls " James Morris
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 41+ messages in thread
From: James Morris @ 2006-05-07 15:36 UTC (permalink / raw)
  To: selinux; +Cc: netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

This patch adds support for a new object class ('packet'),
and two associated permissions ('send', 'recv').  These
are used to enforce security policy for network packets
labeled with SECMARK.


Signed-off-by: James Morris <jmorris@namei.org>

---

diff -purN -X dontdiff linux-2.6.17-rc2-mm1.p/security/selinux/include/av_permissions.h linux-2.6.17-rc2-mm1.w/security/selinux/include/av_permissions.h
--- linux-2.6.17-rc2-mm1.p/security/selinux/include/av_permissions.h	2006-05-01 16:51:36.000000000 -0400
+++ linux-2.6.17-rc2-mm1.w/security/selinux/include/av_permissions.h	2006-05-01 16:52:14.000000000 -0400
@@ -933,3 +933,6 @@
 #define NETLINK_KOBJECT_UEVENT_SOCKET__SEND_MSG   0x00100000UL
 #define NETLINK_KOBJECT_UEVENT_SOCKET__NAME_BIND  0x00200000UL
 
+#define PACKET__SEND                              0x00000001UL
+#define PACKET__RECV                              0x00000002UL
+
diff -purN -X dontdiff linux-2.6.17-rc2-mm1.p/security/selinux/include/av_perm_to_string.h linux-2.6.17-rc2-mm1.w/security/selinux/include/av_perm_to_string.h
--- linux-2.6.17-rc2-mm1.p/security/selinux/include/av_perm_to_string.h	2006-05-01 16:51:36.000000000 -0400
+++ linux-2.6.17-rc2-mm1.w/security/selinux/include/av_perm_to_string.h	2006-05-01 16:52:14.000000000 -0400
@@ -239,3 +239,5 @@
    S_(SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, "sendto")
    S_(SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, "recvfrom")
    S_(SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, "setcontext")
+   S_(SECCLASS_PACKET, PACKET__SEND, "send")
+   S_(SECCLASS_PACKET, PACKET__RECV, "recv")
diff -purN -X dontdiff linux-2.6.17-rc2-mm1.p/security/selinux/include/class_to_string.h linux-2.6.17-rc2-mm1.w/security/selinux/include/class_to_string.h
--- linux-2.6.17-rc2-mm1.p/security/selinux/include/class_to_string.h	2006-03-20 00:53:29.000000000 -0500
+++ linux-2.6.17-rc2-mm1.w/security/selinux/include/class_to_string.h	2006-05-01 16:52:14.000000000 -0400
@@ -58,3 +58,4 @@
     S_("nscd")
     S_("association")
     S_("netlink_kobject_uevent_socket")
+    S_("packet")
diff -purN -X dontdiff linux-2.6.17-rc2-mm1.p/security/selinux/include/flask.h linux-2.6.17-rc2-mm1.w/security/selinux/include/flask.h
--- linux-2.6.17-rc2-mm1.p/security/selinux/include/flask.h	2006-05-01 16:51:36.000000000 -0400
+++ linux-2.6.17-rc2-mm1.w/security/selinux/include/flask.h	2006-05-01 16:52:14.000000000 -0400
@@ -60,6 +60,7 @@
 #define SECCLASS_NSCD                                    53
 #define SECCLASS_ASSOCIATION                             54
 #define SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET           55
+#define SECCLASS_PACKET                                  56
 
 /*
  * Security identifier indices for initial entities

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [RFC][SECMARK 05/08] Add new packet controls to SELinux
  2006-05-07 15:31 [RFC] SECMARK 1.0 James Morris
                   ` (3 preceding siblings ...)
  2006-05-07 15:36 ` [RFC][SECMARK 04/08] Add new flask definitions to SELinux James Morris
@ 2006-05-07 15:37 ` James Morris
  2006-05-07 15:38 ` [RFC][SECMARK 06/08] Define a relabelto permission in the SELinux packet class James Morris
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 41+ messages in thread
From: James Morris @ 2006-05-07 15:37 UTC (permalink / raw)
  To: selinux; +Cc: netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

This patch adds new per-packet access controls to SELinux, replacing the 
old packet controls.

Packets are labeled with the iptables SECMARK target then security policy 
for the packets is enforced with these controls.

To allow for a smooth transition to the new controls, the old code is 
still present, but not active by default.  To restore previous behavior, 
the old controls may be activated at runtime by writing a '1' to 
/selinux/compat_net.  Switching between the network control models 
requires the security load_policy permission.  The old controls will 
probably eventually be removed.


Signed-off-by: James Morris <jmorris@namei.org>

---

 security/selinux/hooks.c        |  241 +++++++++++++++++++++-------------------
 security/selinux/include/xfrm.h |    2 
 security/selinux/selinuxfs.c    |   52 ++++++++
 security/selinux/xfrm.c         |   12 -
 4 files changed, 188 insertions(+), 119 deletions(-)

diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/security/selinux/hooks.c linux-2.6.17-rc3-git7.w/security/selinux/hooks.c
--- linux-2.6.17-rc3-git7.p/security/selinux/hooks.c	2006-05-03 10:25:11.000000000 -0400
+++ linux-2.6.17-rc3-git7.w/security/selinux/hooks.c	2006-05-07 01:02:35.000000000 -0400
@@ -80,6 +80,7 @@
 
 extern unsigned int policydb_loaded_version;
 extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
+extern int selinux_compat_net;
 
 #ifdef CONFIG_SECURITY_SELINUX_DEVELOP
 int selinux_enforcing = 0;
@@ -3212,47 +3213,16 @@ static int selinux_socket_unix_may_send(
 	return 0;
 }
 
-static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
+static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, struct avc_audit_data *ad,
+				       u32 sock_sid, u16 sock_class, u16 family, char *addrp, int len)
 {
-	u16 family;
-	char *addrp;
-	int len, err = 0;
+	int err = 0;
 	u32 netif_perm, node_perm, node_sid, if_sid, recv_perm = 0;
-	u32 sock_sid = 0;
-	u16 sock_class = 0;
-	struct socket *sock;
-	struct net_device *dev;
-	struct avc_audit_data ad;
 
-	family = sk->sk_family;
-	if (family != PF_INET && family != PF_INET6)
+	if (!skb->dev)
 		goto out;
 
-	/* Handle mapped IPv4 packets arriving via IPv6 sockets */
-	if (family == PF_INET6 && skb->protocol == ntohs(ETH_P_IP))
-		family = PF_INET;
-
- 	read_lock_bh(&sk->sk_callback_lock);
- 	sock = sk->sk_socket;
- 	if (sock) {
- 		struct inode *inode;
- 		inode = SOCK_INODE(sock);
- 		if (inode) {
- 			struct inode_security_struct *isec;
- 			isec = inode->i_security;
- 			sock_sid = isec->sid;
- 			sock_class = isec->sclass;
- 		}
- 	}
- 	read_unlock_bh(&sk->sk_callback_lock);
- 	if (!sock_sid)
-  		goto out;
-
-	dev = skb->dev;
-	if (!dev)
-		goto out;
-
-	err = sel_netif_sids(dev, &if_sid, NULL);
+	err = sel_netif_sids(skb->dev, &if_sid, NULL);
 	if (err)
 		goto out;
 
@@ -3275,44 +3245,88 @@ static int selinux_socket_sock_rcv_skb(s
 		break;
 	}
 
-	AVC_AUDIT_DATA_INIT(&ad, NET);
-	ad.u.net.netif = dev->name;
-	ad.u.net.family = family;
-
-	err = selinux_parse_skb(skb, &ad, &addrp, &len, 1);
-	if (err)
-		goto out;
-
-	err = avc_has_perm(sock_sid, if_sid, SECCLASS_NETIF, netif_perm, &ad);
+	err = avc_has_perm(sock_sid, if_sid, SECCLASS_NETIF, netif_perm, ad);
 	if (err)
 		goto out;
 	
-	/* Fixme: this lookup is inefficient */
 	err = security_node_sid(family, addrp, len, &node_sid);
 	if (err)
 		goto out;
 	
-	err = avc_has_perm(sock_sid, node_sid, SECCLASS_NODE, node_perm, &ad);
+	err = avc_has_perm(sock_sid, node_sid, SECCLASS_NODE, node_perm, ad);
 	if (err)
 		goto out;
 
 	if (recv_perm) {
 		u32 port_sid;
 
-		/* Fixme: make this more efficient */
 		err = security_port_sid(sk->sk_family, sk->sk_type,
-		                        sk->sk_protocol, ntohs(ad.u.net.sport),
+		                        sk->sk_protocol, ntohs(ad->u.net.sport),
 		                        &port_sid);
 		if (err)
 			goto out;
 
 		err = avc_has_perm(sock_sid, port_sid,
-				   sock_class, recv_perm, &ad);
+				   sock_class, recv_perm, ad);
 	}
 
-	if (!err)
-		err = selinux_xfrm_sock_rcv_skb(sock_sid, skb);
+out:
+	return err;
+}
+
+static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
+{
+	u16 family;
+	u16 sock_class = 0;
+	char *addrp;
+	int len, err = 0;
+	u32 sock_sid = 0;
+	struct socket *sock;
+	struct avc_audit_data ad;
+
+	family = sk->sk_family;
+	if (family != PF_INET && family != PF_INET6)
+		goto out;
+
+	/* Handle mapped IPv4 packets arriving via IPv6 sockets */
+	if (family == PF_INET6 && skb->protocol == ntohs(ETH_P_IP))
+		family = PF_INET;
+
+ 	read_lock_bh(&sk->sk_callback_lock);
+ 	sock = sk->sk_socket;
+ 	if (sock) {
+ 		struct inode *inode;
+ 		inode = SOCK_INODE(sock);
+ 		if (inode) {
+ 			struct inode_security_struct *isec;
+ 			isec = inode->i_security;
+ 			sock_sid = isec->sid;
+ 			sock_class = isec->sclass;
+ 		}
+ 	}
+ 	read_unlock_bh(&sk->sk_callback_lock);
+ 	if (!sock_sid)
+  		goto out;
+
+	AVC_AUDIT_DATA_INIT(&ad, NET);
+	ad.u.net.netif = skb->dev ? skb->dev->name : "[unknown]";
+	ad.u.net.family = family;
+
+	err = selinux_parse_skb(skb, &ad, &addrp, &len, 1);
+	if (err)
+		goto out;
+
+	if (selinux_compat_net)
+		err = selinux_sock_rcv_skb_compat(sk, skb, &ad, sock_sid,
+						  sock_class, family,
+						  addrp, len);
+	else
+		err = avc_has_perm(sock_sid, skb->secmark, SECCLASS_PACKET,
+				   PACKET__RECV, &ad);
+	if (err)
+		goto out;
 
+	err = selinux_xfrm_sock_rcv_skb(sock_sid, skb);
 out:	
 	return err;
 }
@@ -3452,42 +3466,18 @@ out:
 
 #ifdef CONFIG_NETFILTER
 
-static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
-                                              struct sk_buff **pskb,
-                                              const struct net_device *in,
-                                              const struct net_device *out,
-                                              int (*okfn)(struct sk_buff *),
-                                              u16 family)
+static int selinux_ip_postroute_last_compat(struct sock *sk, struct net_device *dev,
+					    struct inode_security_struct *isec,
+					    struct avc_audit_data *ad,
+					    u16 family, char *addrp, int len)
 {
-	char *addrp;
-	int len, err = NF_ACCEPT;
+	int err;
 	u32 netif_perm, node_perm, node_sid, if_sid, send_perm = 0;
-	struct sock *sk;
-	struct socket *sock;
-	struct inode *inode;
-	struct sk_buff *skb = *pskb;
-	struct inode_security_struct *isec;
-	struct avc_audit_data ad;
-	struct net_device *dev = (struct net_device *)out;
 	
-	sk = skb->sk;
-	if (!sk)
-		goto out;
-		
-	sock = sk->sk_socket;
-	if (!sock)
-		goto out;
-		
-	inode = SOCK_INODE(sock);
-	if (!inode)
-		goto out;
-
 	err = sel_netif_sids(dev, &if_sid, NULL);
 	if (err)
 		goto out;
 
-	isec = inode->i_security;
-	
 	switch (isec->sclass) {
 	case SECCLASS_UDP_SOCKET:
 		netif_perm = NETIF__UDP_SEND;
@@ -3507,55 +3497,88 @@ static unsigned int selinux_ip_postroute
 		break;
 	}
 
-
-	AVC_AUDIT_DATA_INIT(&ad, NET);
-	ad.u.net.netif = dev->name;
-	ad.u.net.family = family;
-
-	err = selinux_parse_skb(skb, &ad, &addrp,
-				&len, 0) ? NF_DROP : NF_ACCEPT;
-	if (err != NF_ACCEPT)
-		goto out;
-
-	err = avc_has_perm(isec->sid, if_sid, SECCLASS_NETIF,
-	                   netif_perm, &ad) ? NF_DROP : NF_ACCEPT;
-	if (err != NF_ACCEPT)
+	err = avc_has_perm(isec->sid, if_sid, SECCLASS_NETIF, netif_perm, ad);
+	if (err)
 		goto out;
 		
-	/* Fixme: this lookup is inefficient */
-	err = security_node_sid(family, addrp, len,
-				&node_sid) ? NF_DROP : NF_ACCEPT;
-	if (err != NF_ACCEPT)
+	err = security_node_sid(family, addrp, len, &node_sid);
+	if (err)
 		goto out;
 	
-	err = avc_has_perm(isec->sid, node_sid, SECCLASS_NODE,
-	                   node_perm, &ad) ? NF_DROP : NF_ACCEPT;
-	if (err != NF_ACCEPT)
+	err = avc_has_perm(isec->sid, node_sid, SECCLASS_NODE, node_perm, ad);
+	if (err)
 		goto out;
 
 	if (send_perm) {
 		u32 port_sid;
 		
-		/* Fixme: make this more efficient */
 		err = security_port_sid(sk->sk_family,
 		                        sk->sk_type,
 		                        sk->sk_protocol,
-		                        ntohs(ad.u.net.dport),
-		                        &port_sid) ? NF_DROP : NF_ACCEPT;
-		if (err != NF_ACCEPT)
+		                        ntohs(ad->u.net.dport),
+		                        &port_sid);
+		if (err)
 			goto out;
 
 		err = avc_has_perm(isec->sid, port_sid, isec->sclass,
-		                   send_perm, &ad) ? NF_DROP : NF_ACCEPT;
+				   send_perm, ad);
 	}
+out:
+	return err;
+}
+
+static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
+                                              struct sk_buff **pskb,
+                                              const struct net_device *in,
+                                              const struct net_device *out,
+                                              int (*okfn)(struct sk_buff *),
+                                              u16 family)
+{
+	char *addrp;
+	int len, err = 0;
+	struct sock *sk;
+	struct socket *sock;
+	struct inode *inode;
+	struct sk_buff *skb = *pskb;
+	struct inode_security_struct *isec;
+	struct avc_audit_data ad;
+	struct net_device *dev = (struct net_device *)out;
+	
+	sk = skb->sk;
+	if (!sk)
+		goto out;
+		
+	sock = sk->sk_socket;
+	if (!sock)
+		goto out;
+		
+	inode = SOCK_INODE(sock);
+	if (!inode)
+		goto out;
+
+	isec = inode->i_security;
+	
+	AVC_AUDIT_DATA_INIT(&ad, NET);
+	ad.u.net.netif = dev->name;
+	ad.u.net.family = family;
 
-	if (err != NF_ACCEPT)
+	err = selinux_parse_skb(skb, &ad, &addrp, &len, 0);
+	if (err)
 		goto out;
 
-	err = selinux_xfrm_postroute_last(isec->sid, skb);
+	if (selinux_compat_net)
+		err = selinux_ip_postroute_last_compat(sk, dev, isec, &ad,
+						       family, addrp, len);
+	else
+		err = avc_has_perm(isec->sid, skb->secmark, SECCLASS_PACKET, 
+				   PACKET__SEND, &ad);
+	
+	if (err)
+		goto out;
 
+	err = selinux_xfrm_postroute_last(isec->sid, skb);
 out:
-	return err;
+	return err ? NF_DROP : NF_ACCEPT;
 }
 
 static unsigned int selinux_ipv4_postroute_last(unsigned int hooknum,
diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/security/selinux/include/xfrm.h linux-2.6.17-rc3-git7.w/security/selinux/include/xfrm.h
--- linux-2.6.17-rc3-git7.p/security/selinux/include/xfrm.h	2006-05-03 10:25:02.000000000 -0400
+++ linux-2.6.17-rc3-git7.w/security/selinux/include/xfrm.h	2006-05-07 01:02:35.000000000 -0400
@@ -49,7 +49,7 @@ static inline int selinux_xfrm_sock_rcv_
 
 static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb)
 {
-	return NF_ACCEPT;
+	return 0;
 }
 
 static inline int selinux_socket_getpeer_stream(struct sock *sk)
diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/security/selinux/selinuxfs.c linux-2.6.17-rc3-git7.w/security/selinux/selinuxfs.c
--- linux-2.6.17-rc3-git7.p/security/selinux/selinuxfs.c	2006-05-03 10:25:02.000000000 -0400
+++ linux-2.6.17-rc3-git7.w/security/selinux/selinuxfs.c	2006-05-07 01:02:35.000000000 -0400
@@ -37,6 +37,7 @@
 #include "conditional.h"
 
 unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
+int selinux_compat_net;
 
 static int __init checkreqprot_setup(char *str)
 {
@@ -85,6 +86,7 @@ enum sel_inos {
 	SEL_AVC,	/* AVC management directory */
 	SEL_MEMBER,	/* compute polyinstantiation membership decision */
 	SEL_CHECKREQPROT, /* check requested protection, not kernel-applied one */
+	SEL_COMPAT_NET,	/* whether to use old compat network packet controls */
 };
 
 #define TMPBUFLEN	12
@@ -364,6 +366,55 @@ static struct file_operations sel_checkr
 	.write		= sel_write_checkreqprot,
 };
 
+static ssize_t sel_read_compat_net(struct file *filp, char __user *buf,
+				   size_t count, loff_t *ppos)
+{
+	char tmpbuf[TMPBUFLEN];
+	ssize_t length;
+
+	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_compat_net);
+	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
+}
+
+static ssize_t sel_write_compat_net(struct file * file, const char __user * buf,
+				    size_t count, loff_t *ppos)
+{
+	char *page;
+	ssize_t length;
+	int new_value;
+
+	length = task_has_security(current, SECURITY__LOAD_POLICY);
+	if (length)
+		return length;
+
+	if (count >= PAGE_SIZE)
+		return -ENOMEM;
+	if (*ppos != 0) {
+		/* No partial writes. */
+		return -EINVAL;
+	}
+	page = (char*)get_zeroed_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+	length = -EFAULT;
+	if (copy_from_user(page, buf, count))
+		goto out;
+
+	length = -EINVAL;
+	if (sscanf(page, "%d", &new_value) != 1)
+		goto out;
+
+	selinux_compat_net = new_value ? 1 : 0;
+	length = count;
+out:
+	free_page((unsigned long) page);
+	return length;
+}
+static struct file_operations sel_compat_net_ops = {
+	.read		= sel_read_compat_net,
+	.write		= sel_write_compat_net,
+};
+
 /*
  * Remaining nodes use transaction based IO methods like nfsd/nfsctl.c
  */
@@ -1219,6 +1270,7 @@ static int sel_fill_super(struct super_b
 		[SEL_DISABLE] = {"disable", &sel_disable_ops, S_IWUSR},
 		[SEL_MEMBER] = {"member", &transaction_ops, S_IRUGO|S_IWUGO},
 		[SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR},
+		[SEL_COMPAT_NET] = {"compat_net", &sel_compat_net_ops, S_IRUGO|S_IWUSR},
 		/* last one */ {""}
 	};
 	ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/security/selinux/xfrm.c linux-2.6.17-rc3-git7.w/security/selinux/xfrm.c
--- linux-2.6.17-rc3-git7.p/security/selinux/xfrm.c	2006-05-03 10:25:02.000000000 -0400
+++ linux-2.6.17-rc3-git7.w/security/selinux/xfrm.c	2006-05-07 01:02:35.000000000 -0400
@@ -356,18 +356,12 @@ int selinux_xfrm_postroute_last(u32 isec
 			struct xfrm_state *x = dst_test->xfrm;
 
 			if (x && selinux_authorizable_xfrm(x))
-				goto accept;
+				goto out;
 		}
 	}
 
 	rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION,
 			  ASSOCIATION__SENDTO, NULL);
-	if (rc)
-		goto drop;
-
-accept:
-	return NF_ACCEPT;
-
-drop:
-	return NF_DROP;
+out:
+	return rc;
 }

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [RFC][SECMARK 06/08] Define a relabelto permission in the SELinux packet class
  2006-05-07 15:31 [RFC] SECMARK 1.0 James Morris
                   ` (4 preceding siblings ...)
  2006-05-07 15:37 ` [RFC][SECMARK 05/08] Add new packet controls " James Morris
@ 2006-05-07 15:38 ` James Morris
  2006-05-07 15:39 ` [RFC][SECMARK 07/08] Add selinux_relabel_packet_permission() to SELinux API James Morris
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 41+ messages in thread
From: James Morris @ 2006-05-07 15:38 UTC (permalink / raw)
  To: selinux; +Cc: netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

This patch defines a new permission ('relabelto') in the new SELinux 
packet object class, to be used when setting SECMARK rules for labeling 
packets.

Signed-off-by: James Morris <jmorris@namei.org>

---

 security/selinux/include/av_perm_to_string.h |    1 +
 security/selinux/include/av_permissions.h    |    2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/security/selinux/include/av_permissions.h linux-2.6.17-rc3-git7.w/security/selinux/include/av_permissions.h
--- linux-2.6.17-rc3-git7.p/security/selinux/include/av_permissions.h	2006-05-03 11:34:17.000000000 -0400
+++ linux-2.6.17-rc3-git7.w/security/selinux/include/av_permissions.h	2006-05-07 00:14:13.000000000 -0400
@@ -935,4 +935,4 @@
 
 #define PACKET__SEND                              0x00000001UL
 #define PACKET__RECV                              0x00000002UL
-
+#define PACKET__RELABELTO                         0x00000004UL
diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/security/selinux/include/av_perm_to_string.h linux-2.6.17-rc3-git7.w/security/selinux/include/av_perm_to_string.h
--- linux-2.6.17-rc3-git7.p/security/selinux/include/av_perm_to_string.h	2006-05-03 11:34:17.000000000 -0400
+++ linux-2.6.17-rc3-git7.w/security/selinux/include/av_perm_to_string.h	2006-05-07 00:14:34.000000000 -0400
@@ -241,3 +241,4 @@
    S_(SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, "setcontext")
    S_(SECCLASS_PACKET, PACKET__SEND, "send")
    S_(SECCLASS_PACKET, PACKET__RECV, "recv")
+   S_(SECCLASS_PACKET, PACKET__RELABELTO, "relabelto")

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [RFC][SECMARK 07/08] Add selinux_relabel_packet_permission() to SELinux API
  2006-05-07 15:31 [RFC] SECMARK 1.0 James Morris
                   ` (5 preceding siblings ...)
  2006-05-07 15:38 ` [RFC][SECMARK 06/08] Define a relabelto permission in the SELinux packet class James Morris
@ 2006-05-07 15:39 ` James Morris
  2006-05-07 15:40 ` [RFC][SECMARK 08/08] Add selinux_relabel_packet_permission() check to xt_SECMARK James Morris
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 41+ messages in thread
From: James Morris @ 2006-05-07 15:39 UTC (permalink / raw)
  To: selinux; +Cc: netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

This patch adds a new function to the SELinux kernel API, 
selinux_relabel_packet_permission(), which is to be invoked when labeling 
packets via SECMARK.

The security policy must allow the specified label to be set by the 
current task for the permission to be granted.

It is implicit that packets are being labeled from the default unlabeled 
type.


Signed-off-by: James Morris <jmorris@namei.org>

---

 include/linux/selinux.h    |   16 ++++++++++++++++
 security/selinux/exports.c |   11 +++++++++++
 2 files changed, 27 insertions(+)

diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/include/linux/selinux.h linux-2.6.17-rc3-git7.w/include/linux/selinux.h
--- linux-2.6.17-rc3-git7.p/include/linux/selinux.h	2006-05-07 00:10:56.000000000 -0400
+++ linux-2.6.17-rc3-git7.w/include/linux/selinux.h	2006-05-07 00:33:00.000000000 -0400
@@ -129,6 +129,17 @@ void selinux_get_task_sid(struct task_st
  */
 int selinux_string_to_sid(char *str, u32 *sid);
 
+/**
+ *     selinux_relabel_packet_permission - check permission to relabel a packet
+ *     @sid: ID value to be applied to network packet (via SECMARK, most likely)
+ *
+ *     Returns 0 if the current task is allowed to label packets with the
+ *     supplied security ID.  Note that it is implicit that the packet is always
+ *     being relabeled from the default unlabled value, and that the access
+ *     control decision is made in the AVC.
+ */
+int selinux_relabel_packet_permission(u32 sid);
+
 #else
 
 static inline int selinux_audit_rule_init(u32 field, u32 op,
@@ -188,6 +199,11 @@ static inline int selinux_string_to_sid(
        return 0;
 }
 
+static inline int selinux_relabel_packet_permission(u32 sid)
+{
+	return 0;
+}
+
 #endif	/* CONFIG_SECURITY_SELINUX */
 
 #endif /* _LINUX_SELINUX_H */
diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/security/selinux/exports.c linux-2.6.17-rc3-git7.w/security/selinux/exports.c
--- linux-2.6.17-rc3-git7.p/security/selinux/exports.c	2006-05-07 00:10:56.000000000 -0400
+++ linux-2.6.17-rc3-git7.w/security/selinux/exports.c	2006-05-07 00:24:22.000000000 -0400
@@ -83,3 +83,14 @@ int selinux_string_to_sid(char *str, u32
 }
 EXPORT_SYMBOL_GPL(selinux_string_to_sid);
 
+int selinux_relabel_packet_permission(u32 sid)
+{
+	if (selinux_enabled) {
+		struct task_security_struct *tsec = current->security;
+		
+		return avc_has_perm(tsec->sid, sid, SECCLASS_PACKET,
+				    PACKET__RELABELTO, NULL);
+	}
+	return 0;
+}
+EXPORT_SYMBOL_GPL(selinux_relabel_packet_permission);

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [RFC][SECMARK 08/08] Add selinux_relabel_packet_permission() check to xt_SECMARK
  2006-05-07 15:31 [RFC] SECMARK 1.0 James Morris
                   ` (6 preceding siblings ...)
  2006-05-07 15:39 ` [RFC][SECMARK 07/08] Add selinux_relabel_packet_permission() to SELinux API James Morris
@ 2006-05-07 15:40 ` James Morris
  2006-05-08 17:54   ` Karl MacMillan
  2006-05-07 15:42 ` [RFC][SECMARK userland 01/03] Add libselinux support James Morris
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 41+ messages in thread
From: James Morris @ 2006-05-07 15:40 UTC (permalink / raw)
  To: selinux; +Cc: netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

This patch adds the selinux_relabel_packet_permission() check to the 
SECMARK target, so that SELinux policy is consulted to ensure that the 
labeling operation is permitted by the current task.


Signed-off-by: James Morris <jmorris@namei.org>

---

 net/netfilter/xt_SECMARK.c |    6 ++++++
 1 file changed, 6 insertions(+)

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-03 11:34:12.000000000 -0400
+++ linux-2.6.17-rc3-git7.w/net/netfilter/xt_SECMARK.c	2006-05-07 00:35:44.000000000 -0400
@@ -72,6 +72,12 @@ static int checkentry_selinux(struct xt_
 		return 0;
 	}
 
+	err = selinux_relabel_packet_permission(sel->selsid);
+	if (err) {
+		printk(KERN_INFO PFX "unable to obtain relabeling permission\n");
+		return 0;
+	}
+
 	return 1;
 }
 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [RFC][SECMARK userland 01/03] Add libselinux support
  2006-05-07 15:31 [RFC] SECMARK 1.0 James Morris
                   ` (7 preceding siblings ...)
  2006-05-07 15:40 ` [RFC][SECMARK 08/08] Add selinux_relabel_packet_permission() check to xt_SECMARK James Morris
@ 2006-05-07 15:42 ` James Morris
  2006-05-07 15:43 ` [RFC][SECMARK userland 02/03] Add libipt_SECMARK James Morris
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 41+ messages in thread
From: James Morris @ 2006-05-07 15:42 UTC (permalink / raw)
  To: selinux; +Cc: netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

This patch adds the infrastructure for linking iptables against 
libselinux, for use with the SECMARK target.  This is enabled by setting 
DO_SELINUX=1 in the build environment.


Signed-off-by: James Morris <jmorris@namei.org>

---

 Makefile            |   14 +++++++++++++-
 Rules.make          |   11 +++++++++--
 extensions/Makefile |   15 ++++++++++++++-
 3 files changed, 36 insertions(+), 4 deletions(-)

diff -purN -X dontdiff iptables.p/extensions/Makefile iptables.w/extensions/Makefile
--- iptables.p/extensions/Makefile	2006-04-25 20:11:00.000000000 -0400
+++ iptables.w/extensions/Makefile	2006-04-25 20:10:43.000000000 -0400
@@ -8,6 +8,11 @@
 PF_EXT_SLIB:=ah addrtype comment connlimit connmark conntrack dscp ecn esp hashlimit helper icmp iprange length limit mac mark multiport owner physdev pkttype policy realm rpc sctp standard state tcp tcpmss tos ttl udp unclean CLASSIFY CONNMARK DNAT DSCP ECN LOG MARK MASQUERADE MIRROR NETMAP NFQUEUE NOTRACK REDIRECT REJECT SAME SNAT TARPIT TCPMSS TOS TRACE TTL ULOG
 PF6_EXT_SLIB:=connmark eui64 hl icmp6 length limit mac mark multiport owner physdev policy standard state tcp udp CONNMARK HL LOG NFQUEUE MARK TRACE
 
+ifeq ($(DO_SELINUX), 1)
+PF_EXT_SE_SLIB:=
+PF6_EXT_SE_SLIB:=
+endif
+
 # Optionals
 PF_EXT_SLIB_OPTS:=$(foreach T,$(wildcard extensions/.*-test),$(shell KERNEL_DIR=$(KERNEL_DIR) $(T)))
 PF6_EXT_SLIB_OPTS:=$(foreach T,$(wildcard extensions/.*-test6),$(shell KERNEL_DIR=$(KERNEL_DIR) $(T)))
@@ -43,26 +48,34 @@ OPTIONALS+=$(patsubst %,IPv6:%,$(PF6_EXT
 
 ifndef NO_SHARED_LIBS
 SHARED_LIBS+=$(foreach T,$(PF_EXT_SLIB),extensions/libipt_$(T).so)
+SHARED_SE_LIBS+=$(foreach T,$(PF_EXT_SE_SLIB),extensions/libipt_$(T).so)
 EXTRA_INSTALLS+=$(foreach T, $(PF_EXT_SLIB), $(DESTDIR)$(LIBDIR)/iptables/libipt_$(T).so)
+EXTRA_INSTALLS+=$(foreach T, $(PF_EXT_SE_SLIB), $(DESTDIR)$(LIBDIR)/iptables/libipt_$(T).so)
 
 ifeq ($(DO_IPV6), 1)
 SHARED_LIBS+=$(foreach T,$(PF6_EXT_SLIB),extensions/libip6t_$(T).so)
+SHARED_SE_LIBS+=$(foreach T,$(PF6_EXT_SE_SLIB),extensions/libip6t_$(T).so)
 EXTRA_INSTALLS+=$(foreach T, $(PF6_EXT_SLIB), $(DESTDIR)$(LIBDIR)/iptables/libip6t_$(T).so)
+EXTRA_INSTALLS+=$(foreach T, $(PF6_EXT_SE_SLIB), $(DESTDIR)$(LIBDIR)/iptables/libip6t_$(T).so)
 endif
 else 	# NO_SHARED_LIBS
 EXT_OBJS+=$(foreach T,$(PF_EXT_SLIB),extensions/libipt_$(T).o)
+EXT_OBJS+=$(foreach T,$(PF_EXT_SE_SLIB),extensions/libipt_$(T).o)
 EXT_FUNC+=$(foreach T,$(PF_EXT_SLIB),ipt_$(T))
+EXT_FUNC+=$(foreach T,$(PF_EXT_SE_SLIB),ipt_$(T))
 EXT_OBJS+= extensions/initext.o
 ifeq ($(DO_IPV6), 1)
 EXT6_OBJS+=$(foreach T,$(PF6_EXT_SLIB),extensions/libip6t_$(T).o)
+EXT6_OBJS+=$(foreach T,$(PF6_EXT_SE_SLIB),extensions/libip6t_$(T).o)
 EXT6_FUNC+=$(foreach T,$(PF6_EXT_SLIB),ip6t_$(T))
+EXT6_FUNC+=$(foreach T,$(PF6_EXT_SE_SLIB),ip6t_$(T))
 EXT6_OBJS+= extensions/initext6.o
 endif	# DO_IPV6
 endif	# NO_SHARED_LIBS
 
 ifndef TOPLEVEL_INCLUDED
 local:
-	cd .. && $(MAKE) $(SHARED_LIBS)
+	cd .. && $(MAKE) $(SHARED_LIBS) $(SHARED_SE_LIBS)
 endif
 
 ifdef NO_SHARED_LIBS
diff -purN -X dontdiff iptables.p/Makefile iptables.w/Makefile
--- iptables.p/Makefile	2006-04-25 20:11:00.000000000 -0400
+++ iptables.w/Makefile	2006-04-25 01:16:43.000000000 -0400
@@ -31,6 +31,11 @@ ifeq ($(shell [ -f /usr/include/netinet/
 DO_IPV6:=1
 endif
 
+# Enable linking to libselinux via enviornment 'DO_SELINUX=1'
+ifndef DO_SELINUX
+DO_SELINUX=0
+endif
+
 COPT_FLAGS:=-O2
 CFLAGS:=$(COPT_FLAGS) -Wall -Wunused -I$(KERNEL_DIR)/include -Iinclude/ -DIPTABLES_VERSION=\"$(IPTABLES_VERSION)\" #-g -DDEBUG #-pg # -DIPTC_DEBUG
 
@@ -93,17 +98,24 @@ endif
 
 ifndef NO_SHARED_LIBS
 DEPFILES = $(SHARED_LIBS:%.so=%.d)
+DEPFILES += $(SHARED_SE_LIBS:%.so=%.d)
 SH_CFLAGS:=$(CFLAGS) -fPIC
 STATIC_LIBS  =
 STATIC6_LIBS =
 LDFLAGS      = -rdynamic
 LDLIBS       = -ldl -lnsl
+ifeq ($(DO_SELINUX), 1)
+LDLIBS       += -lselinux
+endif
 else
 DEPFILES = $(EXT_OBJS:%.o=%.d)
 STATIC_LIBS  = extensions/libext.a
 STATIC6_LIBS = extensions/libext6.a
 LDFLAGS      = -static
-LDLIBS       =
+LDLIBS	     =
+ifeq ($(DO_SELINUX), 1)
+LDLIBS       += -lselinux
+endif
 endif
 
 .PHONY: default
diff -purN -X dontdiff iptables.p/Rules.make iptables.w/Rules.make
--- iptables.p/Rules.make	2006-04-25 20:11:00.000000000 -0400
+++ iptables.w/Rules.make	2006-04-25 01:16:43.000000000 -0400
@@ -1,12 +1,12 @@
 #! /usr/bin/make
 
-all: $(SHARED_LIBS) $(EXTRAS)
+all: $(SHARED_LIBS) $(SHARED_SE_LIBS) $(EXTRAS)
 
 experimental: $(EXTRAS_EXP)
 
 # Have to handle extensions which no longer exist.
 clean: $(EXTRA_CLEANS)
-	rm -f $(SHARED_LIBS) $(EXTRAS) $(EXTRAS_EXP) $(SHARED_LIBS:%.so=%_sh.o)
+	rm -f $(SHARED_LIBS) $(SHARED_SE_LIBS) $(EXTRAS) $(EXTRAS_EXP) $(SHARED_LIBS:%.so=%_sh.o) $(SHARED_SE_LIBS:%.so=%_sh.o)
 	rm -f extensions/initext.c extensions/initext6.c
 	@find . -name '*.[ao]' -o -name '*.so' | xargs rm -f
 
@@ -33,6 +33,13 @@ $(SHARED_LIBS:%.so=%.d): %.d: %.c
 $(SHARED_LIBS): %.so : %_sh.o
 	$(LD) -shared $(EXT_LDFLAGS) -o $@ $<
 
+$(SHARED_SE_LIBS:%.so=%.d): %.d: %.c
+	@-$(CC) -M -MG $(CFLAGS) $< | \
+		sed -e 's@^.*\.o:@$*.d $*_sh.o:@' > $@
+
+$(SHARED_SE_LIBS): %.so : %_sh.o
+	$(LD) -shared $(EXT_LDFLAGS) -o $@ $< $(LDLIBS)
+
 %_sh.o : %.c
 	$(CC) $(SH_CFLAGS) -o $@ -c $<
 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [RFC][SECMARK userland 02/03] Add libipt_SECMARK
  2006-05-07 15:31 [RFC] SECMARK 1.0 James Morris
                   ` (8 preceding siblings ...)
  2006-05-07 15:42 ` [RFC][SECMARK userland 01/03] Add libselinux support James Morris
@ 2006-05-07 15:43 ` James Morris
  2006-05-07 15:44 ` [RFC][SECMARK userland 03/03] Add libip6t_SECMARK James Morris
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 41+ messages in thread
From: James Morris @ 2006-05-07 15:43 UTC (permalink / raw)
  To: selinux; +Cc: netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

This patch adds the shared library module for the SECMARK target (IPv4).


Signed-off-by: James Morris <jmorris@namei.org>

---

 extensions/Makefile           |    2 
 extensions/libipt_SECMARK.c   |  125 ++++++++++++++++++++++++++++++++++++++++++
 extensions/libipt_SECMARK.man |    7 ++
 3 files changed, 133 insertions(+), 1 deletion(-)

diff -purN -X dontdiff iptables.p/extensions/libipt_SECMARK.c iptables.w/extensions/libipt_SECMARK.c
--- iptables.p/extensions/libipt_SECMARK.c	1969-12-31 19:00:00.000000000 -0500
+++ iptables.w/extensions/libipt_SECMARK.c	2006-04-25 20:12:16.000000000 -0400
@@ -0,0 +1,125 @@
+/*
+ * Shared library add-on to iptables to add SECMARK target support.
+ *
+ * Based on the MARK target.
+ *
+ * Copyright (C) 2006 Red Hat, Inc., James Morris <jmorris@redhat.com>
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <iptables.h>
+#include <linux/netfilter/xt_SECMARK.h>
+
+#define PFX "SECMARK target: "
+
+static void help(void)
+{
+	printf(
+"SECMARK target v%s options:\n"
+"  --selctx value                     Set the SELinux security context\n"
+"\n",
+IPTABLES_VERSION);
+}
+
+static struct option opts[] = {
+	{ "selctx", 1, 0, '1' },
+	{ 0 }
+};
+
+/* Initialize the target. */
+static void init(struct ipt_entry_target *t, unsigned int *nfcache)
+{ }
+
+/*
+ * Function which parses command options; returns true if it
+ * ate an option.
+ */
+static int parse(int c, char **argv, int invert, unsigned int *flags,
+                 const struct ipt_entry *entry, struct ipt_entry_target **target)
+{
+	struct xt_secmark_target_info *info =
+		(struct xt_secmark_target_info*)(*target)->data;
+
+	switch (c) {
+	case '1':
+		if (*flags & SECMARK_MODE_SEL)
+			exit_error(PARAMETER_PROBLEM, PFX
+				   "Can't specify --selctx twice");
+		info->mode = SECMARK_MODE_SEL;
+
+		if (strlen(optarg) > SECMARK_SELCTX_MAX-1)
+			exit_error(PARAMETER_PROBLEM, PFX
+				   "Maximum length %u exceeded by --selctx"
+				   " parameter (%zu)",
+				   SECMARK_SELCTX_MAX-1, strlen(optarg));
+
+		strcpy(info->u.sel.selctx, optarg);
+		*flags |= SECMARK_MODE_SEL;
+		break;
+	default:
+		return 0;
+	}
+
+	return 1;
+}
+
+static void final_check(unsigned int flags)
+{
+	if (!flags)
+		exit_error(PARAMETER_PROBLEM, PFX "parameter required");
+}
+
+static void print_secmark(struct xt_secmark_target_info *info)
+{
+	switch (info->mode) {
+	case SECMARK_MODE_SEL:
+		printf("selctx %s ", info->u.sel.selctx);\
+		break;
+	
+	default:
+		exit_error(OTHER_PROBLEM, PFX "invalid mode %hhu\n", info->mode);
+	}
+}
+
+static void print(const struct ipt_ip *ip,
+		  const struct ipt_entry_target *target, int numeric)
+{
+	struct xt_secmark_target_info *info =
+		(struct xt_secmark_target_info*)(target)->data;
+
+	printf("SECMARK ");
+	print_secmark(info);
+}
+
+/* Saves the target info in parsable form to stdout. */
+static void save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
+{
+	struct xt_secmark_target_info *info =
+		(struct xt_secmark_target_info*)target->data;
+
+	printf("--");
+	print_secmark(info);
+}
+
+static struct iptables_target secmark = {
+	.next		= NULL,
+	.name		= "SECMARK",
+	.version	= IPTABLES_VERSION,
+	.revision	= 0,
+	.size		= IPT_ALIGN(sizeof(struct xt_secmark_target_selinux_info)),
+	.userspacesize	= IPT_ALIGN(sizeof(struct xt_secmark_target_selinux_info)),
+	.help		= &help,
+	.init		= &init,
+	.parse		= &parse,
+	.final_check	= &final_check,
+	.print		= &print,
+	.save		= &save,
+	.extra_opts	= opts
+};
+
+void _init(void)
+{
+	register_target(&secmark);
+}
diff -purN -X dontdiff iptables.p/extensions/libipt_SECMARK.man iptables.w/extensions/libipt_SECMARK.man
--- iptables.p/extensions/libipt_SECMARK.man	1969-12-31 19:00:00.000000000 -0500
+++ iptables.w/extensions/libipt_SECMARK.man	2006-04-25 20:12:16.000000000 -0400
@@ -0,0 +1,7 @@
+This is used to set the security mark value associated with the
+packet for use by security subsystems such as SELinux.  It is only
+valid in the
+.B mangle
+table.
+.TP
+.BI "--selctx " "security_context"
diff -purN -X dontdiff iptables.p/extensions/Makefile iptables.w/extensions/Makefile
--- iptables.p/extensions/Makefile	2006-04-25 20:12:07.000000000 -0400
+++ iptables.w/extensions/Makefile	2006-04-25 20:12:35.000000000 -0400
@@ -9,7 +9,7 @@ PF_EXT_SLIB:=ah addrtype comment connlim
 PF6_EXT_SLIB:=connmark eui64 hl icmp6 length limit mac mark multiport owner physdev policy standard state tcp udp CONNMARK HL LOG NFQUEUE MARK TRACE
 
 ifeq ($(DO_SELINUX), 1)
-PF_EXT_SE_SLIB:=
+PF_EXT_SE_SLIB:=SECMARK
 PF6_EXT_SE_SLIB:=
 endif
 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [RFC][SECMARK userland 03/03] Add libip6t_SECMARK
  2006-05-07 15:31 [RFC] SECMARK 1.0 James Morris
                   ` (9 preceding siblings ...)
  2006-05-07 15:43 ` [RFC][SECMARK userland 02/03] Add libipt_SECMARK James Morris
@ 2006-05-07 15:44 ` James Morris
  2006-05-07 17:04 ` [RFC] SECMARK 1.0 Joshua Brindle
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 41+ messages in thread
From: James Morris @ 2006-05-07 15:44 UTC (permalink / raw)
  To: selinux; +Cc: netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

This patch adds the shared library module for the SECMARK target (IPv6).


Signed-off-by: James Morris <jmorris@namei.org>

---

diff -purN -X dontdiff iptables.p/extensions/libip6t_SECMARK.c iptables.w/extensions/libip6t_SECMARK.c
--- iptables.p/extensions/libip6t_SECMARK.c	1969-12-31 19:00:00.000000000 -0500
+++ iptables.w/extensions/libip6t_SECMARK.c	2006-04-27 02:31:36.000000000 -0400
@@ -0,0 +1,125 @@
+/*
+ * Shared library add-on to iptables to add SECMARK target support.
+ *
+ * Based on the MARK target.
+ *
+ * IPv6 version.
+ *
+ * Copyright (C) 2006 Red Hat, Inc., James Morris <jmorris@redhat.com>
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <ip6tables.h>
+#include <linux/netfilter/xt_SECMARK.h>
+
+#define PFX "SECMARK target: "
+
+static void help(void)
+{
+	printf(
+"SECMARK target v%s options:\n"
+"  --selctx value                     Set the SELinux security context\n"
+"\n",
+IPTABLES_VERSION);
+}
+
+static struct option opts[] = {
+	{ "selctx", 1, 0, '1' },
+	{ 0 }
+};
+
+/* Initialize the target. */
+static void init(struct ip6t_entry_target *t, unsigned int *nfcache)
+{ }
+
+/*
+ * Function which parses command options; returns true if it
+ * ate an option.
+ */
+static int parse(int c, char **argv, int invert, unsigned int *flags,
+                 const struct ip6t_entry *entry, struct ip6t_entry_target **target)
+{
+	struct xt_secmark_target_info *info =
+		(struct xt_secmark_target_info*)(*target)->data;
+
+	switch (c) {
+	case '1':
+		if (*flags & SECMARK_MODE_SEL)
+			exit_error(PARAMETER_PROBLEM, PFX
+				   "Can't specify --selctx twice");
+		info->mode = SECMARK_MODE_SEL;
+
+		if (strlen(optarg) > SECMARK_SELCTX_MAX-1)
+			exit_error(PARAMETER_PROBLEM, PFX
+				   "Maximum length %u exceeded by --selctx"
+				   " parameter (%zu)",
+				   SECMARK_SELCTX_MAX-1, strlen(optarg));
+
+		strcpy(info->u.sel.selctx, optarg);
+		*flags |= SECMARK_MODE_SEL;
+		break;
+	default:
+		return 0;
+	}
+
+	return 1;
+}
+
+static void final_check(unsigned int flags)
+{
+	if (!flags)
+		exit_error(PARAMETER_PROBLEM, PFX "parameter required");
+}
+
+static void print_secmark(struct xt_secmark_target_info *info)
+{
+	switch (info->mode) {
+	case SECMARK_MODE_SEL:
+		printf("selctx %s ", info->u.sel.selctx);\
+		break;
+	
+	default:
+		exit_error(OTHER_PROBLEM, PFX "invalid mode %hhu\n", info->mode);
+	}
+}
+
+static void print(const struct ip6t_ip6 *ip,
+		  const struct ip6t_entry_target *target, int numeric)
+{
+	struct xt_secmark_target_info *info =
+		(struct xt_secmark_target_info*)(target)->data;
+
+	printf("SECMARK ");
+	print_secmark(info);
+}
+
+/* Saves the target info in parsable form to stdout. */
+static void save(const struct ip6t_ip6 *ip, const struct ip6t_entry_target *target)
+{
+	struct xt_secmark_target_info *info =
+		(struct xt_secmark_target_info*)target->data;
+
+	printf("--");
+	print_secmark(info);
+}
+
+static struct ip6tables_target secmark = {
+	.name		= "SECMARK",
+	.version	= IPTABLES_VERSION,
+	.size		= IP6T_ALIGN(sizeof(struct xt_secmark_target_selinux_info)),
+	.userspacesize	= IP6T_ALIGN(sizeof(struct xt_secmark_target_selinux_info)),
+	.help		= &help,
+	.init		= &init,
+	.parse		= &parse,
+	.final_check	= &final_check,
+	.print		= &print,
+	.save		= &save,
+	.extra_opts	= opts
+};
+
+void _init(void)
+{
+	register_target6(&secmark);
+}
diff -purN -X dontdiff iptables.p/extensions/libip6t_SECMARK.man iptables.w/extensions/libip6t_SECMARK.man
--- iptables.p/extensions/libip6t_SECMARK.man	1969-12-31 19:00:00.000000000 -0500
+++ iptables.w/extensions/libip6t_SECMARK.man	2006-04-27 02:23:09.000000000 -0400
@@ -0,0 +1,7 @@
+This is used to set the security mark value associated with the
+packet for use by security subsystems such as SELinux.  It is only
+valid in the
+.B mangle
+table.
+.TP
+.BI "--selctx " "security_context"
diff -purN -X dontdiff iptables.p/extensions/Makefile iptables.w/extensions/Makefile
--- iptables.p/extensions/Makefile	2006-04-27 02:22:22.000000000 -0400
+++ iptables.w/extensions/Makefile	2006-04-27 02:25:34.000000000 -0400
@@ -10,7 +10,7 @@ PF6_EXT_SLIB:=connmark eui64 hl icmp6 le
 
 ifeq ($(DO_SELINUX), 1)
 PF_EXT_SE_SLIB:=SECMARK
-PF6_EXT_SE_SLIB:=
+PF6_EXT_SE_SLIB:=SECMARK
 endif
 
 # Optionals

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.0
  2006-05-07 15:31 [RFC] SECMARK 1.0 James Morris
                   ` (10 preceding siblings ...)
  2006-05-07 15:44 ` [RFC][SECMARK userland 03/03] Add libip6t_SECMARK James Morris
@ 2006-05-07 17:04 ` Joshua Brindle
  2006-05-07 17:43   ` James Morris
  2006-05-07 17:44 ` James Morris
  2006-05-14  6:03 ` [RFC] SECMARK 1.1 James Morris
  13 siblings, 1 reply; 41+ messages in thread
From: Joshua Brindle @ 2006-05-07 17:04 UTC (permalink / raw)
  To: James Morris
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

James Morris wrote:
> For example, SELinux will now be able to utilize connection tracking, so 
> that only packets which are known to be valid for a specific connection 
> will be allowed to reach the subject.
>
> Sample iptables rules for labeling packets are at:
> http://people.redhat.com/jmorris/selinux/secmark/rules/
>
> And examples of new policy controls may be found here:
> http://people.redhat.com/jmorris/selinux/secmark/policy/
>   
It looks like you are labeling all packets on an established connection 
as tracked_packet_t. What is the rationale for not labeling all ftp 
traffic as ftpd_packet_t? Granted that its very unlikely for established 
connections to go to the wrong process but the SELinux policy should be 
able to clearly show that ftpd and sshd cannot see each others packets 
but these policies say that they can both send/receive tracked_packet_t.

Obviously these are just examples, I'm just curious if there was a 
reason to label established packets differently from the new connection 
packets (and the same as all the other established packets)

I imagine that, at least at first, it would be good to have allow domain 
unlabeled_t:packet { send recv }; in an (enabled) conditional so that 
the migration will be easier.

Also, we need to come up with a mechanism for distributing default 
marking rules that can accompany a policy. The rules could go into a 
section in the .pp file but how does that integrate with various 
firewall systems that take control of the iptables rules?

And finally, what happens if the labeling rule changes during an 
established connection? Do the packets related to that connection retain 
the original label or will they get the new label?

Thanks, this will be very beneficial to the SELinux community

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.0
  2006-05-07 17:04 ` [RFC] SECMARK 1.0 Joshua Brindle
@ 2006-05-07 17:43   ` James Morris
  2006-05-08 17:41     ` Karl MacMillan
  0 siblings, 1 reply; 41+ messages in thread
From: James Morris @ 2006-05-07 17:43 UTC (permalink / raw)
  To: Joshua Brindle
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

On Sun, 7 May 2006, Joshua Brindle wrote:

> It looks like you are labeling all packets on an established connection as
> tracked_packet_t. What is the rationale for not labeling all ftp traffic as
> ftpd_packet_t? Granted that its very unlikely for established connections to
> go to the wrong process but the SELinux policy should be able to clearly show
> that ftpd and sshd cannot see each others packets but these policies say that
> they can both send/receive tracked_packet_t.

Yes.  This is due to the way connection tracking works, there's no 
indication of which connection the packet belongs to, just its state.  We 
depend on conntrack to correctly determine the state of the packet, 
anyway, and we don't have real IP security without something like IPsec.

SELinux policy analysis will need to work on the assumption that conntrack 
is working correctly, and that a packet which is a valid part of an ftp 
connection won't end up delivering data to sshd.

We could look at something similar to the CONNMARK target, where 
connections are labeled, but it's very ugly and really not useful, as we 
assume that conntrack is working correctly.

You can always not use conntrack and emulate the existing controls, as 
well.

> Obviously these are just examples, I'm just curious if there was a reason to
> label established packets differently from the new connection packets (and the
> same as all the other established packets)

The label for the new connection packet is essential for ensuring that the 
connection being created is the right type.  We know that if a valid SYN 
arrives on port 22, that this is an attempt to establish a connection with 
sshd (assuming it's configured to listen on port 22).  Then, conntrack 
observes the TCP handshake, and creates connection state if successful.

Also, we only want sshd to receive new connections here, not create them.

> I imagine that, at least at first, it would be good to have allow domain
> unlabeled_t:packet { send recv }; in an (enabled) conditional so that the
> migration will be easier.

See 

http://people.redhat.com/jmorris/selinux/secmark/policy/packettest/packettest.te

# Totally insecure, for testing.
#
# Allow all unlabled packets to all domains.
#
allow domain unlabeled_t:packet { send recv };

As the policy is generated by macros, it should be very simple to change 
just a few of the macros to generate compatible policy rules for the new 
controls.

> Also, we need to come up with a mechanism for distributing default marking
> rules that can accompany a policy. The rules could go into a section in the
> .pp file but how does that integrate with various firewall systems that take
> control of the iptables rules?

I believe the way to handle this is to create SELinux input and output 
chains and then add all of the SELinux labeling rules via them, so the 
SELinux rules are at least partitioned off, and these tools will be able 
to treat them opaquely. Have a look at the example rulesets I posted on 
the web site.

> And finally, what happens if the labeling rule changes during an established
> connection? Do the packets related to that connection retain the original
> label or will they get the new label?

It depends on which rule is changed.  If it's for a NEW connection, only 
packets hitting that will get the new label.  For ESTABLISHED & RELATED, 
all packets on those rules will get the new label once the rule is 
updated.

> Thanks, this will be very beneficial to the SELinux community

I hope so, the SELinux policy should be pretty simple, and the iptables 
rules perhaps not so much, but they'll be generated by macros.

I've also seen some interesting performance improvements (especially if 
conntrack is not loaded), although we won't really know the overall 
picture until all of the current policy is converted over.  Then it'll be 
a case of how well iptables performs with lots of rules and chains.


- James
-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.0
  2006-05-07 15:31 [RFC] SECMARK 1.0 James Morris
                   ` (11 preceding siblings ...)
  2006-05-07 17:04 ` [RFC] SECMARK 1.0 Joshua Brindle
@ 2006-05-07 17:44 ` James Morris
  2006-05-14  6:03 ` [RFC] SECMARK 1.1 James Morris
  13 siblings, 0 replies; 41+ messages in thread
From: James Morris @ 2006-05-07 17:44 UTC (permalink / raw)
  To: selinux; +Cc: netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

(note: an old, incorrect address for netfilter-devel was used in the 
initial mail, please update to the correct one as above if replying to 
this thread).


-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.0
  2006-05-07 17:43   ` James Morris
@ 2006-05-08 17:41     ` Karl MacMillan
  2006-05-08 21:29       ` James Morris
  0 siblings, 1 reply; 41+ messages in thread
From: Karl MacMillan @ 2006-05-08 17:41 UTC (permalink / raw)
  To: James Morris
  Cc: Joshua Brindle, selinux, netdev, netfilter-devel, Stephen Smalley,
	Daniel J Walsh

On Sun, 2006-05-07 at 13:43 -0400, James Morris wrote:
> On Sun, 7 May 2006, Joshua Brindle wrote:
> 
> > It looks like you are labeling all packets on an established connection as
> > tracked_packet_t. What is the rationale for not labeling all ftp traffic as
> > ftpd_packet_t? Granted that its very unlikely for established connections to
> > go to the wrong process but the SELinux policy should be able to clearly show
> > that ftpd and sshd cannot see each others packets but these policies say that
> > they can both send/receive tracked_packet_t.
> 
> Yes.  This is due to the way connection tracking works, there's no 
> indication of which connection the packet belongs to, just its state.  We 
> depend on conntrack to correctly determine the state of the packet, 
> anyway, and we don't have real IP security without something like IPsec.
> 
> SELinux policy analysis will need to work on the assumption that conntrack 
> is working correctly, and that a packet which is a valid part of an ftp 
> connection won't end up delivering data to sshd.
> 
> We could look at something similar to the CONNMARK target, where 
> connections are labeled, but it's very ugly and really not useful, as we 
> assume that conntrack is working correctly.
> 

Something like CONNMARK seems preferable to me (perhaps even allowing
type_transition rules to give the related packets a unique type). This
makes the labeling reflect the real security property of the packets.
Yes, we are trusting the conntrack to mark the packets accurately, but
it makes the policy match the intent. Otherwise it is not possible to
reason about information flow using just the policy.

Are there serious downsides to this approach?

> You can always not use conntrack and emulate the existing controls, as 
> well.
> 

Yes, but gaining connection tracking is a major advantage of this
approach over the existing controls.

Karl

-- 
Karl MacMillan
Tresys Technology
www.tresys.com
> > Obviously these are just examples, I'm just curious if there was a reason to
> > label established packets differently from the new connection packets (and the
> > same as all the other established packets)
> 
> The label for the new connection packet is essential for ensuring that the 
> connection being created is the right type.  We know that if a valid SYN 
> arrives on port 22, that this is an attempt to establish a connection with 
> sshd (assuming it's configured to listen on port 22).  Then, conntrack 
> observes the TCP handshake, and creates connection state if successful.
> 
> Also, we only want sshd to receive new connections here, not create them.
> 
> > I imagine that, at least at first, it would be good to have allow domain
> > unlabeled_t:packet { send recv }; in an (enabled) conditional so that the
> > migration will be easier.
> 
> See 
> 
> http://people.redhat.com/jmorris/selinux/secmark/policy/packettest/packettest.te
> 
> # Totally insecure, for testing.
> #
> # Allow all unlabled packets to all domains.
> #
> allow domain unlabeled_t:packet { send recv };
> 
> As the policy is generated by macros, it should be very simple to change 
> just a few of the macros to generate compatible policy rules for the new 
> controls.
> 
> > Also, we need to come up with a mechanism for distributing default marking
> > rules that can accompany a policy. The rules could go into a section in the
> > .pp file but how does that integrate with various firewall systems that take
> > control of the iptables rules?
> 
> I believe the way to handle this is to create SELinux input and output 
> chains and then add all of the SELinux labeling rules via them, so the 
> SELinux rules are at least partitioned off, and these tools will be able 
> to treat them opaquely. Have a look at the example rulesets I posted on 
> the web site.
> 
> > And finally, what happens if the labeling rule changes during an established
> > connection? Do the packets related to that connection retain the original
> > label or will they get the new label?
> 
> It depends on which rule is changed.  If it's for a NEW connection, only 
> packets hitting that will get the new label.  For ESTABLISHED & RELATED, 
> all packets on those rules will get the new label once the rule is 
> updated.
> 
> > Thanks, this will be very beneficial to the SELinux community
> 
> I hope so, the SELinux policy should be pretty simple, and the iptables 
> rules perhaps not so much, but they'll be generated by macros.
> 
> I've also seen some interesting performance improvements (especially if 
> conntrack is not loaded), although we won't really know the overall 
> picture until all of the current policy is converted over.  Then it'll be 
> a case of how well iptables performs with lots of rules and chains.
> 
> 
> - James
> -- 
> James Morris
> <jmorris@namei.org>
> 
> --
> 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.


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC][SECMARK 08/08] Add selinux_relabel_packet_permission() check to xt_SECMARK
  2006-05-07 15:40 ` [RFC][SECMARK 08/08] Add selinux_relabel_packet_permission() check to xt_SECMARK James Morris
@ 2006-05-08 17:54   ` Karl MacMillan
  2006-05-08 21:19     ` James Morris
  0 siblings, 1 reply; 41+ messages in thread
From: Karl MacMillan @ 2006-05-08 17:54 UTC (permalink / raw)
  To: James Morris
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

On Sun, 2006-05-07 at 11:40 -0400, James Morris wrote:
> This patch adds the selinux_relabel_packet_permission() check to the 
> SECMARK target, so that SELinux policy is consulted to ensure that the 
> labeling operation is permitted by the current task.
> 
> 
> Signed-off-by: James Morris <jmorris@namei.org>
> 
> ---
> 
>  net/netfilter/xt_SECMARK.c |    6 ++++++
>  1 file changed, 6 insertions(+)
> 
> 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-03 11:34:12.000000000 -0400
> +++ linux-2.6.17-rc3-git7.w/net/netfilter/xt_SECMARK.c	2006-05-07 00:35:44.000000000 -0400
> @@ -72,6 +72,12 @@ static int checkentry_selinux(struct xt_
>  		return 0;
>  	}
>  
> +	err = selinux_relabel_packet_permission(sel->selsid);
> +	if (err) {
> +		printk(KERN_INFO PFX "unable to obtain relabeling permission\n");
> +		return 0;
> +	}
> +
>  	return 1;
>  }
>  
> 

Glad that you added this. This only checks on the addition of rules,
correct? Obviously changes that don't include an addition (e.g.,
removal) could change the labeling behavior. Is it possible / needed to
try to provide anything like the relabelto/relabelfrom pairing that is
present for files?

Karl

-- 
Karl MacMillan
Tresys Technology
www.tresys.com

> --
> 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.


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC][SECMARK 08/08] Add selinux_relabel_packet_permission() check to xt_SECMARK
  2006-05-08 17:54   ` Karl MacMillan
@ 2006-05-08 21:19     ` James Morris
  0 siblings, 0 replies; 41+ messages in thread
From: James Morris @ 2006-05-08 21:19 UTC (permalink / raw)
  To: Karl MacMillan
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

On Mon, 8 May 2006, Karl MacMillan wrote:

> Glad that you added this. This only checks on the addition of rules,
> correct? Obviously changes that don't include an addition (e.g.,
> removal) could change the labeling behavior. Is it possible / needed to
> try to provide anything like the relabelto/relabelfrom pairing that is
> present for files?

The xtables target knows nothing of rule deletion, so we can't detect 
anything there.  All operations require cap_net_admin, though. so we do at 
least have that.

There's also no way to do relabelfrom, as a single rule update actually 
causes the entire 'table' to be replaced, and we have no linkage between 
old and new rules, or in fact, any way to look at the previous state.  It 
turns out that we don't need a relabelfrom anyway, as packets which enter 
the system are inherently unlabeled, and all that SECMARK does is add a 
label, so we know implicitly that setting a label on a packet is always a 
'relabelfrom unlabeled'.


- James
-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.0
  2006-05-08 17:41     ` Karl MacMillan
@ 2006-05-08 21:29       ` James Morris
  2006-05-09 13:24         ` Karl MacMillan
  0 siblings, 1 reply; 41+ messages in thread
From: James Morris @ 2006-05-08 21:29 UTC (permalink / raw)
  To: Karl MacMillan
  Cc: Joshua Brindle, selinux, netdev, netfilter-devel, Stephen Smalley,
	Daniel J Walsh

On Mon, 8 May 2006, Karl MacMillan wrote:

> Something like CONNMARK seems preferable to me (perhaps even allowing
> type_transition rules to give the related packets a unique type). This
> makes the labeling reflect the real security property of the packets.

That's arguable.  The real security property afaict is that the packets 
are of some state (established or related to an existing connection).  It 
is implicit in the mechanism that they're tracked as part of an authorized 
connection.

> Yes, we are trusting the conntrack to mark the packets accurately, but
> it makes the policy match the intent. Otherwise it is not possible to
> reason about information flow using just the policy.

Why not?  You just state that all established and related packets reaching 
vsftpd are valid, and that no invalid packets can deliver data to the 
application.  You can play tricks and stick a label on a packet but that 
doesn't change what's actually happening or your ability to reason about 
it.  You assume conntrack works correctly (and if it doesn't, then 
labeling connections will break, too).

> Are there serious downsides to this approach?

Yes, it's an ugly hack which is not needed.

> > You can always not use conntrack and emulate the existing controls, as 
> > well.
> 
> Yes, but gaining connection tracking is a major advantage of this
> approach over the existing controls.

The point is to show that this scheme provides much stonger security 
assurrances, and that if you wished, you could easily rervert to stateless 
filtering and have the "correct" labels on the packets; which would be 
worse.



- James
-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.0
  2006-05-08 21:29       ` James Morris
@ 2006-05-09 13:24         ` Karl MacMillan
  2006-05-09 16:40           ` James Morris
  0 siblings, 1 reply; 41+ messages in thread
From: Karl MacMillan @ 2006-05-09 13:24 UTC (permalink / raw)
  To: James Morris
  Cc: Joshua Brindle, selinux, netdev, netfilter-devel, Stephen Smalley,
	Daniel J Walsh

On Mon, 2006-05-08 at 17:29 -0400, James Morris wrote:
> On Mon, 8 May 2006, Karl MacMillan wrote:
> 
> > Something like CONNMARK seems preferable to me (perhaps even allowing
> > type_transition rules to give the related packets a unique type). This
> > makes the labeling reflect the real security property of the packets.
> 
> That's arguable.  The real security property afaict is that the packets 
> are of some state (established or related to an existing connection).  It 
> is implicit in the mechanism that they're tracked as part of an authorized 
> connection.
> 

This loses how the connection was initiated, however. Packets that are
part of a connection that was initiated on the ftp port are different
from packets that are part of a connection initiated on the telnet port.
Now, the name_bind permissions will limit which domains can initiate
those connection, but my concern is that connection could, through error
or exploit, be passed to another domain that should not receive packets
from that type of connection (see below).

> > Yes, we are trusting the conntrack to mark the packets accurately, but
> > it makes the policy match the intent. Otherwise it is not possible to
> > reason about information flow using just the policy.
> 
> Why not?  You just state that all established and related packets reaching 
> vsftpd are valid, and that no invalid packets can deliver data to the 
> application.  You can play tricks and stick a label on a packet but that 
> doesn't change what's actually happening or your ability to reason about 
> it.  You assume conntrack works correctly (and if it doesn't, then 
> labeling connections will break, too).
> 

The use of a single related packet type loses the strong binding between
the connection type (determined on connection) and domains, most likely
because an established connection is passed to another process.

For example, for xinetd to work all of the xinetd children would be
allowed to receive all related packets (i.e., tracked_packet_t). This
means that if xinetd incorrectly passed, say, an ftp connection to
telnet it would still be allowed to receive those packets because they
would be of type tracked_packet_t. Labeling using something like
connmark seems to solve this problem. There may be other examples
relating to enforcing data separation based on other connection
information, like the network interface, but I haven't had a chance to
work through those scenarios.

Now you may be saying that it is not possible to determine with any
assurance that a related packet is related to, for example, a connection
that was initiated on the ftp port (and therefore given a different type
- related_ftp_packet_t - fixing my xinetd example). If this is the case,
your argument makes more sense to me.

Karl

-- 
Karl MacMillan
Tresys Technology
www.tresys.com

> > Are there serious downsides to this approach?
> 
> Yes, it's an ugly hack which is not needed.
> 
> > > You can always not use conntrack and emulate the existing controls, as 
> > > well.
> > 
> > Yes, but gaining connection tracking is a major advantage of this
> > approach over the existing controls.
> 
> The point is to show that this scheme provides much stonger security 
> assurrances, and that if you wished, you could easily rervert to stateless 
> filtering and have the "correct" labels on the packets; which would be 
> worse.
> 
> 
> 
> - James


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.0
  2006-05-09 13:24         ` Karl MacMillan
@ 2006-05-09 16:40           ` James Morris
  2006-05-09 17:06             ` Karl MacMillan
  2006-05-09 17:11             ` Stephen Smalley
  0 siblings, 2 replies; 41+ messages in thread
From: James Morris @ 2006-05-09 16:40 UTC (permalink / raw)
  To: Karl MacMillan
  Cc: Joshua Brindle, selinux, netdev, netfilter-devel, Stephen Smalley,
	Daniel J Walsh

On Tue, 9 May 2006, Karl MacMillan wrote:

> those connection, but my concern is that connection could, through error
> or exploit, be passed to another domain that should not receive packets
> from that type of connection (see below).

Connection passing or inheritence should be subject to kernel MAC controls 
anyway (also see below).

> The use of a single related packet type loses the strong binding between
> the connection type (determined on connection) and domains, most likely
> because an established connection is passed to another process.
> 
> For example, for xinetd to work all of the xinetd children would be
> allowed to receive all related packets (i.e., tracked_packet_t). This
> means that if xinetd incorrectly passed, say, an ftp connection to
> telnet it would still be allowed to receive those packets because they
> would be of type tracked_packet_t. Labeling using something like
> connmark seems to solve this problem.

My understanding of xinetd is that it execs server applications, which 
inherit the connection fd.  In this case, flush_unauthorized_files() will 
ensure that the new domain is authorized to access the fd.

Stephen, can you confirm this?

> There may be other examples relating to enforcing data separation based 
> on other connection information, like the network interface, but I 
> haven't had a chance to work through those scenarios.

I'm not sure exactly what you mean here, but the idea of this scheme is 
that you can create new types to represent arbitrary combinations of 
security-relevant properites of a packet.

e.g. extif_ftp_packet_t for ftp packets over an external interface.

> Now you may be saying that it is not possible to determine with any
> assurance that a related packet is related to, for example, a connection
> that was initiated on the ftp port (and therefore given a different type
> - related_ftp_packet_t - fixing my xinetd example). If this is the case,
> your argument makes more sense to me.

This is not the case.  The problem is adding a secmark field to the 
connection tracking system, and then having to implement several rules for 
each labeling intent.  The conntrack is first labeled from the initial 
packet, then tracked packets are labeled from the conntrack label.  It's 
ugly.


- James
-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.0
  2006-05-09 16:40           ` James Morris
@ 2006-05-09 17:06             ` Karl MacMillan
  2006-05-09 18:56               ` James Morris
  2006-05-09 17:11             ` Stephen Smalley
  1 sibling, 1 reply; 41+ messages in thread
From: Karl MacMillan @ 2006-05-09 17:06 UTC (permalink / raw)
  To: James Morris
  Cc: Joshua Brindle, selinux, netdev, netfilter-devel, Stephen Smalley,
	Daniel J Walsh

On Tue, 2006-05-09 at 12:40 -0400, James Morris wrote:
> On Tue, 9 May 2006, Karl MacMillan wrote:
> 
> > those connection, but my concern is that connection could, through error
> > or exploit, be passed to another domain that should not receive packets
> > from that type of connection (see below).
> 
> Connection passing or inheritence should be subject to kernel MAC controls 
> anyway (also see below).
> 

It is, but with no differentiation to how the connection was initially
established (continue to see below).

> > The use of a single related packet type loses the strong binding between
> > the connection type (determined on connection) and domains, most likely
> > because an established connection is passed to another process.
> > 
> > For example, for xinetd to work all of the xinetd children would be
> > allowed to receive all related packets (i.e., tracked_packet_t). This
> > means that if xinetd incorrectly passed, say, an ftp connection to
> > telnet it would still be allowed to receive those packets because they
> > would be of type tracked_packet_t. Labeling using something like
> > connmark seems to solve this problem.
> 
> My understanding of xinetd is that it execs server applications, which 
> inherit the connection fd.  In this case, flush_unauthorized_files() will 
> ensure that the new domain is authorized to access the fd.
> 
> Stephen, can you confirm this?
> 

It doesn't matter whether the fd is inherited or passed over a unix
domain socket, the problem is the same. The fd and the underlying socket
will have the type of the creating process. So, yes there is control but
there is no differentiation; either a child can inherit/receive the
existing connection from xinetd or it cannot, regardless of how the
connection was initiated.

Another way of looking at this is that if a single type is used for all
related packets the network controls that we can place on, for example,
ftpd depend on whether it listens directly to the ftp port or it runs
through xinetd. This seems unfortunate.

> > There may be other examples relating to enforcing data separation based 
> > on other connection information, like the network interface, but I 
> > haven't had a chance to work through those scenarios.
> 
> I'm not sure exactly what you mean here, but the idea of this scheme is 
> that you can create new types to represent arbitrary combinations of 
> security-relevant properites of a packet.
> 
> e.g. extif_ftp_packet_t for ftp packets over an external interface.
> 

Right, I understand that, but it seems that much of that granularity is
lost when connection tracking is used.

For example, if we have a xinetd execute the ftp daemon in different
domains based on the network interface, originating ip address, etc.
(presumably for confidentiality reasons). With the single related packet
type we must completely trust xinetd to pass the correct connections to
the ftp daemon in the correct domain: the related packets that the ftpd
will be the same regardless of whether the initial packets where
extif_ftp_packet_t or intern_ftp_packet_t.

If the security context of the related packets is the same as the
packets for the connection establishment we no longer have to trust
xinetd.

> > Now you may be saying that it is not possible to determine with any
> > assurance that a related packet is related to, for example, a connection
> > that was initiated on the ftp port (and therefore given a different type
> > - related_ftp_packet_t - fixing my xinetd example). If this is the case,
> > your argument makes more sense to me.
> 
> This is not the case.  The problem is adding a secmark field to the 
> connection tracking system, and then having to implement several rules for 
> each labeling intent.  The conntrack is first labeled from the initial 
> packet, then tracked packets are labeled from the conntrack label.  It's 
> ugly.
> 

Ok - I obviously don't have the expertise to judge how ugly the code to
do this is. It becomes a question of whether the feature is compelling
enough.

Karl

-- 
Karl MacMillan
Tresys Technology
www.tresys.com

> 
> - James


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.0
  2006-05-09 16:40           ` James Morris
  2006-05-09 17:06             ` Karl MacMillan
@ 2006-05-09 17:11             ` Stephen Smalley
  1 sibling, 0 replies; 41+ messages in thread
From: Stephen Smalley @ 2006-05-09 17:11 UTC (permalink / raw)
  To: James Morris
  Cc: Karl MacMillan, Joshua Brindle, selinux, netdev, netfilter-devel,
	Daniel J Walsh

On Tue, 2006-05-09 at 12:40 -0400, James Morris wrote:
> On Tue, 9 May 2006, Karl MacMillan wrote:
> 
> > those connection, but my concern is that connection could, through error
> > or exploit, be passed to another domain that should not receive packets
> > from that type of connection (see below).
> 
> Connection passing or inheritence should be subject to kernel MAC controls 
> anyway (also see below).
> 
> > The use of a single related packet type loses the strong binding between
> > the connection type (determined on connection) and domains, most likely
> > because an established connection is passed to another process.
> > 
> > For example, for xinetd to work all of the xinetd children would be
> > allowed to receive all related packets (i.e., tracked_packet_t). This
> > means that if xinetd incorrectly passed, say, an ftp connection to
> > telnet it would still be allowed to receive those packets because they
> > would be of type tracked_packet_t. Labeling using something like
> > connmark seems to solve this problem.
> 
> My understanding of xinetd is that it execs server applications, which 
> inherit the connection fd.  In this case, flush_unauthorized_files() will 
> ensure that the new domain is authorized to access the fd.
> 
> Stephen, can you confirm this?

That doesn't help, as that is just a check based on the socket label,
which will always be based on xinetd's label and won't reflect anything
about the individual connection.

-- 
Stephen Smalley
National Security Agency


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.0
  2006-05-09 17:06             ` Karl MacMillan
@ 2006-05-09 18:56               ` James Morris
  0 siblings, 0 replies; 41+ messages in thread
From: James Morris @ 2006-05-09 18:56 UTC (permalink / raw)
  To: Karl MacMillan
  Cc: Joshua Brindle, selinux, netdev, Stephen Smalley, Daniel J Walsh,
	netfilter-devel

On Tue, 9 May 2006, Karl MacMillan wrote:

> Ok - I obviously don't have the expertise to judge how ugly the code to
> do this is. It becomes a question of whether the feature is compelling
> enough.

Atcually, I think there may be a good way to do this, will investigate.


- James
-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC][SECMARK 03/08] Add xtables SECMARK target
  2006-05-07 15:35 ` [RFC][SECMARK 03/08] Add xtables SECMARK target James Morris
@ 2006-05-10  6:03   ` Patrick McHardy
  2006-05-10 13:30     ` James Morris
  0 siblings, 1 reply; 41+ messages in thread
From: Patrick McHardy @ 2006-05-10  6:03 UTC (permalink / raw)
  To: James Morris
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

James Morris wrote:
> This patch adds a SECMARK target to xtables, allowing
> the admin to apply security marks to packets via both
> iptables and ip6tables.
> 
> The target currently handles SELinux security marking,
> but can be extended for other purposes as needed.

The netfilter parts all look fine too me (just one question,
see below). Shall I add the userspace parts to SVN or do you
want to do it yourself?


> +static int checkentry_selinux(struct xt_secmark_target_info *info)
> +{
> +	int err;
> +	struct xt_secmark_target_selinux_info *sel = &info->u.sel;
> +
> +	err = selinux_string_to_sid(sel->selctx, &sel->selsid);
> +	if (err) {
> +		if (err == -EINVAL)
> +			printk(KERN_INFO PFX "invalid SELinux context \'%s\'\n",
> +			       sel->selctx);
> +		return 0;
> +	}
> +	
> +	if (!sel->selsid) {
> +		printk(KERN_INFO PFX "unable to map SELinux context \'%s\'\n",
> +		       sel->selctx);
> +		return 0;
> +	}
> +
> +	return 1;
> +}

I wonder if the result of this check could be invalidated later
by removal of the selinux context and if it would matter, since
you reject contexts not known at initialization time.


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC][SECMARK 03/08] Add xtables SECMARK target
  2006-05-10  6:03   ` Patrick McHardy
@ 2006-05-10 13:30     ` James Morris
  2006-05-11  7:06       ` Patrick McHardy
  0 siblings, 1 reply; 41+ messages in thread
From: James Morris @ 2006-05-10 13:30 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

On Wed, 10 May 2006, Patrick McHardy wrote:

> The netfilter parts all look fine too me (just one question,
> see below). Shall I add the userspace parts to SVN or do you
> want to do it yourself?

Might be better if you do it, although I'm still looking into one issue at 
this stage.

> I wonder if the result of this check could be invalidated later
> by removal of the selinux context and if it would matter, since
> you reject contexts not known at initialization time.

If the context is removed later by a change to SELinux policy, the kernel 
will remap them to "unlabeled_t", which is how packets would then be 
labeled by the rule.


- James 
-- 
James Morris <jmorris@namei.org>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC][SECMARK 03/08] Add xtables SECMARK target
  2006-05-10 13:30     ` James Morris
@ 2006-05-11  7:06       ` Patrick McHardy
  0 siblings, 0 replies; 41+ messages in thread
From: Patrick McHardy @ 2006-05-11  7:06 UTC (permalink / raw)
  To: James Morris
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh

James Morris wrote:
> On Wed, 10 May 2006, Patrick McHardy wrote:
> 
> 
>>The netfilter parts all look fine too me (just one question,
>>see below). Shall I add the userspace parts to SVN or do you
>>want to do it yourself?
> 
> 
> Might be better if you do it, although I'm still looking into one issue at 
> this stage.

Just tell me when you want me to add it.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [RFC] SECMARK 1.1
  2006-05-07 15:31 [RFC] SECMARK 1.0 James Morris
                   ` (12 preceding siblings ...)
  2006-05-07 17:44 ` James Morris
@ 2006-05-14  6:03 ` James Morris
  2006-05-14 18:37   ` Patrick McHardy
                     ` (2 more replies)
  13 siblings, 3 replies; 41+ messages in thread
From: James Morris @ 2006-05-14  6:03 UTC (permalink / raw)
  To: selinux
  Cc: netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh,
	Karl MacMillan, Patrick McHardy, David S. Miller, Thomas Bleher

Included below is an incremental patch against the initial secmark posting 
last week: http://thread.gmane.org/gmane.linux.network/34927/focus=34927

This posting to gather feedback on changes made since then primarily to 
address concerns raised by Karl MacMillan on providing fine-grained 
assurances for network applications which pass connections (e.g. xinetd).

If all looks ok, I'll rebase the entire patchset (also merging elements 
from the patch below back into other patches), and submit it for inclusion 
in 2.6.18.  As it touches a bunch of networking code, it may be best to 
aim for Dave's tree, although it could also go into -mm.

Anyway, the way the issue has been addressed is to implement something 
similar to CONNMARK, but specific to this useage scenario and dealing with 
security markings instead of network markings.

In a nutshell:

1. A --track option was added to the SECMARK target, which causes the 
   security mark being applied to the packet to also be applied to a new
   secmark field on the conntrack (only if it is unmarked).

2. A new CONNSECMARK target was added which copies the secmark value to 
   packets.

This allows all packets on a connection (or related to it) to be marked 
with the same security label, so that they can be explicitly 
differentiated.

This also turns out to simplify the SELinux policy, while the xtables 
implementation has been designed to remain as simple as possible (e.g. it 
only copies lables to packets, and has no options).

So, here's an example of per-packet network policy for vsftpd with the new 
code:

  allow ftpd_t ftpd_packet_t:packet { recv send };

Assuming it doesn't do DNS lookups, that's it in terms of access control 
rules for packets.  This covers all established and related packets, 
including ICMP and the FTP data connetion.

(see the full policy at 
http://people.redhat.com/jmorris/selinux/secmark/policy/ftpd_tracked/ftpd_tracked.te)

In terms of iptables rules, the only real change is that we need to add 
CONNSECMARK rules for all incoming and outgoing packets (assuming you want 
this for all services, otherwise, use iptables selectors to apply 
CONNSECMARK on a per-service basis).  Here's an example for the above:

#
# Accept incoming connections, label SYN packets, and copy
# labels to connections.
#
$IPT -A SEL_INPUT -p tcp --dport 21 -m state --state NEW -j SEL_FTPD
$IPT -A SEL_FTPD -j SECMARK --selctx system_u:object_r:ftpd_packet_t:s0 --track
$IPT -A SEL_FTPD -j ACCEPT

#
# Copy connection labels to established and related packets.
#
$IPT -A SEL_INPUT -m state --state ESTABLISHED,RELATED -j CONNSECMARK
$IPT -A SEL_OUTPUT -m state --state ESTABLISHED,RELATED -j CONNSECMARK


It should be easy to modularize the iptables rules and distribute them 
with policy modules, and I'd recommend always generating them with some 
script or macro.

Everything needed to get this running (including iptables patches) is at:
http://people.redhat.com/jmorris/selinux/secmark/

I've also added a patch at the site which adds a kernel boot param to 
determine whether to use the old or new packet controls, although I'm 
still not sure whether it's justified adding this stuff to the kernel when 
it can be set at runtime during early boot.

Please review and let me know if there any further issues.


Signed-off-by: James Morris <jmorris@namei.org>

---

 include/linux/netfilter/xt_SECMARK.h         |    7 +-
 include/linux/netfilter_ipv4/ip_conntrack.h  |    4 +
 include/net/netfilter/nf_conntrack.h         |    4 +
 include/net/netfilter/nf_conntrack_compat.h  |   26 +++++++
 net/ipv4/netfilter/Kconfig                   |   10 ++
 net/ipv4/netfilter/ip_conntrack_core.c       |    3 
 net/ipv4/netfilter/ip_conntrack_standalone.c |    5 +
 net/netfilter/Kconfig                        |   20 +++++
 net/netfilter/Makefile                       |    1 
 net/netfilter/nf_conntrack_core.c            |    3 
 net/netfilter/nf_conntrack_standalone.c      |    5 +
 net/netfilter/xt_CONNSECMARK.c               |   93 +++++++++++++++++++++++++++
 net/netfilter/xt_SECMARK.c                   |   45 ++++++++++++-
 13 files changed, 224 insertions(+), 2 deletions(-)

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-13 15:15:29.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-13 15:15:29.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-13 15:15:29.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-13 15:15:29.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_core.c linux-2.6.17-rc3-git7.w/net/ipv4/netfilter/ip_conntrack_core.c
--- linux-2.6.17-rc3-git7.p/net/ipv4/netfilter/ip_conntrack_core.c	2006-05-03 10:25:01.000000000 -0400
+++ linux-2.6.17-rc3-git7.w/net/ipv4/netfilter/ip_conntrack_core.c	2006-05-13 15:20:47.000000000 -0400
@@ -724,6 +724,9 @@ init_conntrack(struct ip_conntrack_tuple
 		/* this is ugly, but there is no other place where to put it */
 		conntrack->nat.masq_index = exp->master->nat.masq_index;
 #endif
+#ifdef CONFIG_IP_NF_CONNTRACK_SECMARK
+		conntrack->secmark = exp->master->secmark;
+#endif
 		nf_conntrack_get(&conntrack->master->ct_general);
 		CONNTRACK_STAT_INC(expect_new);
 	} else {
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-13 15:15:29.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-13 15:15:29.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-13 15:15:29.000000000 -0400
+++ linux-2.6.17-rc3-git7.w/net/netfilter/Kconfig	2006-05-13 15:13:08.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
@@ -183,6 +193,16 @@ config NETFILTER_XT_TARGET_SECMARK
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
+config NETFILTER_XT_TARGET_CONNSECMARK
+	tristate '"CONNSECMARK" target support'
+	depends on NETFILTER_XTABLES && NETWORK_SECMARK && (NF_CONNTRACK_SECMARK || IP_NF_CONNTRACK_SECMARK)
+	help
+	  The CONNSECMARK target copies security markings from conntracks
+	  to packets, if the packets are not already marked.  This would
+	  normally be used in conjunction with 'SECMARK --track'.
+	  
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config NETFILTER_XT_MATCH_COMMENT
 	tristate  '"comment" match support'
 	depends on NETFILTER_XTABLES
diff -purN -X dontdiff linux-2.6.17-rc3-git7.p/net/netfilter/Makefile linux-2.6.17-rc3-git7.w/net/netfilter/Makefile
--- linux-2.6.17-rc3-git7.p/net/netfilter/Makefile	2006-05-09 19:56:11.000000000 -0400
+++ linux-2.6.17-rc3-git7.w/net/netfilter/Makefile	2006-05-13 12:22:55.000000000 -0400
@@ -29,6 +29,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) +
 obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
 
 # matches
 obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o
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-13 15:15:29.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-13 15:15:29.000000000 -0400
+++ linux-2.6.17-rc3-git7.w/net/netfilter/nf_conntrack_standalone.c	2006-05-13 15:21:45.000000000 -0400
@@ -213,6 +213,11 @@ static int ct_seq_show(struct seq_file *
 		return -ENOSPC;
 #endif
 
+#ifdef 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_CONNSECMARK.c linux-2.6.17-rc3-git7.w/net/netfilter/xt_CONNSECMARK.c
--- linux-2.6.17-rc3-git7.p/net/netfilter/xt_CONNSECMARK.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.17-rc3-git7.w/net/netfilter/xt_CONNSECMARK.c	2006-05-13 23:27:00.000000000 -0400
@@ -0,0 +1,93 @@
+/*
+ * This module is used to copy security markings from conntracks
+ * to packets, most likely in conjunction with "SECMARK --track".
+ *
+ * Based on the nfmark match by:
+ * (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
+ *
+ * (C) 2006 Red Hat, Inc., James Morris <jmorris@redhat.com>
+ *
+ * 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/module.h>
+#include <linux/skbuff.h>
+#include <linux/netfilter/x_tables.h>
+#include <net/netfilter/nf_conntrack_compat.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("James Morris <jmorris@redhat.com>");
+MODULE_DESCRIPTION("ip[6]tables CONNSECMARK module");
+MODULE_ALIAS("ipt_CONNSECMARK");
+MODULE_ALIAS("ip6t_CONNSECMARK");
+
+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,
+			   const void *targinfo, void *userinfo)
+{
+	struct sk_buff *skb = *pskb;
+
+	if (!skb->secmark) {
+		u32 *connsecmark;
+		enum ip_conntrack_info ctinfo;
+		
+		/*
+		 * If packet is unlabeled, and the connection is labeled,
+		 * copy the connection label to the packet.
+		 */
+		connsecmark = nf_ct_get_secmark(skb, &ctinfo);
+		if (connsecmark && *connsecmark != 0) {
+			if (skb->secmark != *connsecmark)
+				skb->secmark = *connsecmark;
+		}
+	}
+
+	return XT_CONTINUE;
+}
+
+static struct xt_target ipt_connsecmark_reg = {
+	.name		= "CONNSECMARK",
+	.target		= target,
+	.targetsize	= 0,
+	.table		= "mangle",
+	.me		= THIS_MODULE,
+	.family		= AF_INET,
+	.revision	= 0,
+};
+
+static struct xt_target ip6t_connsecmark_reg = {
+	.name		= "CONNSECMARK",
+	.target		= target,
+	.targetsize	= 0,
+	.table		= "mangle",
+	.me		= THIS_MODULE,
+	.family		= AF_INET6,
+	.revision	= 0,
+};
+
+static int __init xt_connsecmark_init(void)
+{
+	int err;
+
+	err = xt_register_target(&ipt_connsecmark_reg);
+	if (err)
+		return err;
+
+	err = xt_register_target(&ip6t_connsecmark_reg);
+	if (err)
+		xt_unregister_target(&ipt_connsecmark_reg);
+
+	return err;
+}
+
+static void __exit xt_connsecmark_fini(void)
+{
+	xt_unregister_target(&ip6t_connsecmark_reg);
+	xt_unregister_target(&ipt_connsecmark_reg);
+}
+
+module_init(xt_connsecmark_init);
+module_exit(xt_connsecmark_fini);
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-13 15:15:29.000000000 -0400
+++ linux-2.6.17-rc3-git7.w/net/netfilter/xt_SECMARK.c	2006-05-13 15:24:28.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/selinux.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_SECMARK.h>
+#include <net/netfilter/nf_conntrack_compat.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("James Morris <jmorris@redhat.com>");
@@ -28,6 +29,37 @@ MODULE_ALIAS("ip6t_SECMARK");
 
 static u8 mode;
 
+#if defined(CONFIG_IP_NF_CONNTRACK_SECMARK) || defined(CONFIG_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;
















^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.1
  2006-05-14  6:03 ` [RFC] SECMARK 1.1 James Morris
@ 2006-05-14 18:37   ` Patrick McHardy
  2006-05-15  4:24     ` James Morris
  2006-05-15 12:35   ` Karl MacMillan
  2006-05-17 13:36   ` Thomas Bleher
  2 siblings, 1 reply; 41+ messages in thread
From: Patrick McHardy @ 2006-05-14 18:37 UTC (permalink / raw)
  To: James Morris
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh,
	Karl MacMillan, David S. Miller, Thomas Bleher

James Morris wrote:
> @@ -135,6 +175,9 @@ static int __init xt_secmark_init(void)
>  {
>  	int err;
>  
> +	if (tracking_enabled())
> +		need_conntrack();
> +

This will load the conntrack modules even if the track flag is not set.
Wouldn't it be better to put everything related to connection marking
in the CONNSECMARK target?

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.1
  2006-05-14 18:37   ` Patrick McHardy
@ 2006-05-15  4:24     ` James Morris
  2006-05-15  5:29       ` Patrick McHardy
  0 siblings, 1 reply; 41+ messages in thread
From: James Morris @ 2006-05-15  4:24 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh,
	Karl MacMillan, David S. Miller, Thomas Bleher

On Sun, 14 May 2006, Patrick McHardy wrote:

> James Morris wrote:
> > @@ -135,6 +175,9 @@ static int __init xt_secmark_init(void)
> >  {
> >  	int err;
> >  
> > +	if (tracking_enabled())
> > +		need_conntrack();
> > +
> 
> This will load the conntrack modules even if the track flag is not set.

I guess need_conntrack() could be moved to checkentry() and only called 
if the track flag is set.


> Wouldn't it be better to put everything related to connection marking
> in the CONNSECMARK target?

It's more efficient this way, and simpler to manage.  

Currently, after security marking, the chain should normally terminate 
with a -j ACCEPT.  Requiring the use of CONNSECMARK to label connections 
means inserting another rule before terminating the chain.

Also, security marking for connections only occurs in the context of 
copying the security mark from packets, so there's no reason to build a 
general feature to do this into CONNSECMARK.

Another possibility would be to get rid of CONNSECMARK completely and have 
SECMARK copy security marks from connections to packets via the use of a 
different flag (perhaps change --track into --save-state and then have 
--restore-state, or similar).


- James
-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.1
  2006-05-15  4:24     ` James Morris
@ 2006-05-15  5:29       ` Patrick McHardy
  2006-05-15  5:57         ` James Morris
  0 siblings, 1 reply; 41+ messages in thread
From: Patrick McHardy @ 2006-05-15  5:29 UTC (permalink / raw)
  To: James Morris
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh,
	Karl MacMillan, David S. Miller, Thomas Bleher

James Morris wrote:
> On Sun, 14 May 2006, Patrick McHardy wrote:
> 
> 
>>James Morris wrote:
>>
>>>@@ -135,6 +175,9 @@ static int __init xt_secmark_init(void)
>>> {
>>> 	int err;
>>> 
>>>+	if (tracking_enabled())
>>>+		need_conntrack();
>>>+
>>
>>This will load the conntrack modules even if the track flag is not set.
> 
> 
> I guess need_conntrack() could be moved to checkentry() and only called 
> if the track flag is set.


That won't help, the function itself does nothing, its just a symbol
dependency.

>>Wouldn't it be better to put everything related to connection marking
>>in the CONNSECMARK target?
> 
> 
> It's more efficient this way, and simpler to manage.  
> 
> Currently, after security marking, the chain should normally terminate 
> with a -j ACCEPT.  Requiring the use of CONNSECMARK to label connections 
> means inserting another rule before terminating the chain.
> 
> Also, security marking for connections only occurs in the context of 
> copying the security mark from packets, so there's no reason to build a 
> general feature to do this into CONNSECMARK.
> 
> Another possibility would be to get rid of CONNSECMARK completely and have 
> SECMARK copy security marks from connections to packets via the use of a 
> different flag (perhaps change --track into --save-state and then have 
> --restore-state, or similar).


The reason why I'm asking is because my understanding is that SECMARK
would also be useful without conntrack, but automatically pulling in
the module leaves no option not to use conntrack except not to compile
this part in.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.1
  2006-05-15  5:29       ` Patrick McHardy
@ 2006-05-15  5:57         ` James Morris
  2006-05-15  6:04           ` Patrick McHardy
  0 siblings, 1 reply; 41+ messages in thread
From: James Morris @ 2006-05-15  5:57 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh,
	Karl MacMillan, David S. Miller, Thomas Bleher

On Mon, 15 May 2006, Patrick McHardy wrote:

> >>This will load the conntrack modules even if the track flag is not set.
> > 
> > 
> > I guess need_conntrack() could be moved to checkentry() and only called 
> > if the track flag is set.
> 
> 
> That won't help, the function itself does nothing, its just a symbol
> dependency.

Not sure what you mean: it will cause ip_conntrack to be loaded, which 
is needed when you specify the track flag.

> > Another possibility would be to get rid of CONNSECMARK completely and have 
> > SECMARK copy security marks from connections to packets via the use of a 
> > different flag (perhaps change --track into --save-state and then have 
> > --restore-state, or similar).
> 
> 
> The reason why I'm asking is because my understanding is that SECMARK
> would also be useful without conntrack,

Yes.

>  but automatically pulling in the module leaves no option not to use 
> conntrack except not to compile this part in.

Conntrack will only be loaded if someone uses "SECMARK --track", which is 
exactly what is desired.   Without --track, conntrack will not be loaded 
by SECMARK.



- James
-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.1
  2006-05-15  5:57         ` James Morris
@ 2006-05-15  6:04           ` Patrick McHardy
  2006-05-15  6:22             ` James Morris
  0 siblings, 1 reply; 41+ messages in thread
From: Patrick McHardy @ 2006-05-15  6:04 UTC (permalink / raw)
  To: James Morris
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh,
	Karl MacMillan, David S. Miller, Thomas Bleher

James Morris wrote:
> On Mon, 15 May 2006, Patrick McHardy wrote:
> 
> 
>>>>This will load the conntrack modules even if the track flag is not set.
>>>
>>>
>>>I guess need_conntrack() could be moved to checkentry() and only called 
>>>if the track flag is set.
>>
>>
>>That won't help, the function itself does nothing, its just a symbol
>>dependency.
> 
> 
> Not sure what you mean: it will cause ip_conntrack to be loaded, which 
> is needed when you specify the track flag.


Yes, but the reason why it is loaded is because the module loader needs
to resolve the symbol, not because of anything done at module runtime.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.1
  2006-05-15  6:04           ` Patrick McHardy
@ 2006-05-15  6:22             ` James Morris
  2006-05-15  6:26               ` Patrick McHardy
  0 siblings, 1 reply; 41+ messages in thread
From: James Morris @ 2006-05-15  6:22 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh,
	Karl MacMillan, David S. Miller, Thomas Bleher

On Mon, 15 May 2006, Patrick McHardy wrote:

> > Not sure what you mean: it will cause ip_conntrack to be loaded, which 
> > is needed when you specify the track flag.
> 
> 
> Yes, but the reason why it is loaded is because the module loader needs
> to resolve the symbol, not because of anything done at module runtime.

Am I missing something?  This is what I want to happen.  If you specify 
SECMARK --track,  ip_conntrack is to be loaded.


-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.1
  2006-05-15  6:22             ` James Morris
@ 2006-05-15  6:26               ` Patrick McHardy
  2006-05-15  6:37                 ` James Morris
  0 siblings, 1 reply; 41+ messages in thread
From: Patrick McHardy @ 2006-05-15  6:26 UTC (permalink / raw)
  To: James Morris
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh,
	Karl MacMillan, David S. Miller, Thomas Bleher

James Morris wrote:
> On Mon, 15 May 2006, Patrick McHardy wrote:
> 
> 
>>>Not sure what you mean: it will cause ip_conntrack to be loaded, which 
>>>is needed when you specify the track flag.
>>
>>
>>Yes, but the reason why it is loaded is because the module loader needs
>>to resolve the symbol, not because of anything done at module runtime.
> 
> 
> Am I missing something?  This is what I want to happen.  If you specify 
> SECMARK --track,  ip_conntrack is to be loaded.


But if you don't specify --track, the module loader will still have to
resolve the symbol, so it gets loaded anyway, before your code will
even run. Just look at need_conntrack():

/* Some modules need us, but don't depend directly on any symbol.
   They should call this. */
void need_conntrack(void)
{
}

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.1
  2006-05-15  6:26               ` Patrick McHardy
@ 2006-05-15  6:37                 ` James Morris
  2006-05-15  6:42                   ` James Morris
  2006-05-15  6:43                   ` Patrick McHardy
  0 siblings, 2 replies; 41+ messages in thread
From: James Morris @ 2006-05-15  6:37 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh,
	Karl MacMillan, David S. Miller, Thomas Bleher

On Mon, 15 May 2006, Patrick McHardy wrote:

> But if you don't specify --track, the module loader will still have to
> resolve the symbol, so it gets loaded anyway, before your code will
> even run. Just look at need_conntrack():

Doh.  It should be try_module_get().  Sound ok?


- James
-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.1
  2006-05-15  6:37                 ` James Morris
@ 2006-05-15  6:42                   ` James Morris
  2006-05-15  6:43                   ` Patrick McHardy
  1 sibling, 0 replies; 41+ messages in thread
From: James Morris @ 2006-05-15  6:42 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh,
	Karl MacMillan, David S. Miller, Thomas Bleher

On Mon, 15 May 2006, James Morris wrote:

> 
> Doh.  It should be try_module_get().  Sound ok?

Of course, I mean request_module().


-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.1
  2006-05-15  6:37                 ` James Morris
  2006-05-15  6:42                   ` James Morris
@ 2006-05-15  6:43                   ` Patrick McHardy
  1 sibling, 0 replies; 41+ messages in thread
From: Patrick McHardy @ 2006-05-15  6:43 UTC (permalink / raw)
  To: James Morris
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh,
	Karl MacMillan, David S. Miller, Thomas Bleher

James Morris wrote:
> On Mon, 15 May 2006, Patrick McHardy wrote:
> 
> 
>>But if you don't specify --track, the module loader will still have to
>>resolve the symbol, so it gets loaded anyway, before your code will
>>even run. Just look at need_conntrack():
> 
> 
> Doh.  It should be try_module_get().  Sound ok?

try_module_get already needs a module reference, so this won't work
either. As far as I can tell the only thing you can do besides
putting it in a seperate module is to manually call request_module().


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.1
  2006-05-14  6:03 ` [RFC] SECMARK 1.1 James Morris
  2006-05-14 18:37   ` Patrick McHardy
@ 2006-05-15 12:35   ` Karl MacMillan
  2006-05-17 13:36   ` Thomas Bleher
  2 siblings, 0 replies; 41+ messages in thread
From: Karl MacMillan @ 2006-05-15 12:35 UTC (permalink / raw)
  To: James Morris
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh,
	Patrick McHardy, David S. Miller, Thomas Bleher

On Sun, 2006-05-14 at 02:03 -0400, James Morris wrote:
> Included below is an incremental patch against the initial secmark posting 
> last week: http://thread.gmane.org/gmane.linux.network/34927/focus=34927
> 
> This posting to gather feedback on changes made since then primarily to 
> address concerns raised by Karl MacMillan on providing fine-grained 
> assurances for network applications which pass connections (e.g. xinetd).
> 
> If all looks ok, I'll rebase the entire patchset (also merging elements 
> from the patch below back into other patches), and submit it for inclusion 
> in 2.6.18.  As it touches a bunch of networking code, it may be best to 
> aim for Dave's tree, although it could also go into -mm.
> 
> Anyway, the way the issue has been addressed is to implement something 
> similar to CONNMARK, but specific to this useage scenario and dealing with 
> security markings instead of network markings.
> 
> In a nutshell:
> 
> 1. A --track option was added to the SECMARK target, which causes the 
>    security mark being applied to the packet to also be applied to a new
>    secmark field on the conntrack (only if it is unmarked).
> 
> 2. A new CONNSECMARK target was added which copies the secmark value to 
>    packets.
> 
> This allows all packets on a connection (or related to it) to be marked 
> with the same security label, so that they can be explicitly 
> differentiated.
> 
> This also turns out to simplify the SELinux policy, while the xtables 
> implementation has been designed to remain as simple as possible (e.g. it 
> only copies lables to packets, and has no options).
> 
> So, here's an example of per-packet network policy for vsftpd with the new 
> code:
> 
>   allow ftpd_t ftpd_packet_t:packet { recv send };
> 
> Assuming it doesn't do DNS lookups, that's it in terms of access control 
> rules for packets.  This covers all established and related packets, 
> including ICMP and the FTP data connetion.
> 

James,

This seems to address my concerns - thanks.

Karl

-- 
Karl MacMillan
Tresys Technology
www.tresys.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.1
  2006-05-14  6:03 ` [RFC] SECMARK 1.1 James Morris
  2006-05-14 18:37   ` Patrick McHardy
  2006-05-15 12:35   ` Karl MacMillan
@ 2006-05-17 13:36   ` Thomas Bleher
  2006-05-17 14:56     ` James Morris
  2 siblings, 1 reply; 41+ messages in thread
From: Thomas Bleher @ 2006-05-17 13:36 UTC (permalink / raw)
  To: James Morris
  Cc: Daniel J Walsh, netdev, netfilter-devel, David S. Miller, selinux,
	Stephen Smalley, Patrick McHardy, Karl MacMillan

[-- Attachment #1: Type: text/plain, Size: 3812 bytes --]

* James Morris <jmorris@namei.org> [2006-05-14 08:03]:
> Included below is an incremental patch against the initial secmark posting 
> last week: http://thread.gmane.org/gmane.linux.network/34927/focus=34927
> 
> This posting to gather feedback on changes made since then primarily to 
> address concerns raised by Karl MacMillan on providing fine-grained 
> assurances for network applications which pass connections (e.g. xinetd).
> 
> If all looks ok, I'll rebase the entire patchset (also merging elements 
> from the patch below back into other patches), and submit it for inclusion 
> in 2.6.18.  As it touches a bunch of networking code, it may be best to 
> aim for Dave's tree, although it could also go into -mm.
> 
> Anyway, the way the issue has been addressed is to implement something 
> similar to CONNMARK, but specific to this useage scenario and dealing with 
> security markings instead of network markings.
> 
> In a nutshell:
> 
> 1. A --track option was added to the SECMARK target, which causes the 
>    security mark being applied to the packet to also be applied to a new
>    secmark field on the conntrack (only if it is unmarked).
> 
> 2. A new CONNSECMARK target was added which copies the secmark value to 
>    packets.
> 
> This allows all packets on a connection (or related to it) to be marked 
> with the same security label, so that they can be explicitly 
> differentiated.
> 
> This also turns out to simplify the SELinux policy, while the xtables 
> implementation has been designed to remain as simple as possible (e.g. it 
> only copies lables to packets, and has no options).
> 
> So, here's an example of per-packet network policy for vsftpd with the new 
> code:
> 
>   allow ftpd_t ftpd_packet_t:packet { recv send };
> 
> Assuming it doesn't do DNS lookups, that's it in terms of access control 
> rules for packets.  This covers all established and related packets, 
> including ICMP and the FTP data connetion.
> 
> (see the full policy at 
> http://people.redhat.com/jmorris/selinux/secmark/policy/ftpd_tracked/ftpd_tracked.te)
> 
> In terms of iptables rules, the only real change is that we need to add 
> CONNSECMARK rules for all incoming and outgoing packets (assuming you want 
> this for all services, otherwise, use iptables selectors to apply 
> CONNSECMARK on a per-service basis).  Here's an example for the above:
> 
> #
> # Accept incoming connections, label SYN packets, and copy
> # labels to connections.
> #
> $IPT -A SEL_INPUT -p tcp --dport 21 -m state --state NEW -j SEL_FTPD
> $IPT -A SEL_FTPD -j SECMARK --selctx system_u:object_r:ftpd_packet_t:s0 --track
> $IPT -A SEL_FTPD -j ACCEPT

This all looks very nice - Thank You!
Just one question: does the code canonicalize the security label? It
would be nice if the same rules could be used on MLS and non-MLS
systems.

Thomas

> 
> #
> # Copy connection labels to established and related packets.
> #
> $IPT -A SEL_INPUT -m state --state ESTABLISHED,RELATED -j CONNSECMARK
> $IPT -A SEL_OUTPUT -m state --state ESTABLISHED,RELATED -j CONNSECMARK
> 
> 
> It should be easy to modularize the iptables rules and distribute them 
> with policy modules, and I'd recommend always generating them with some 
> script or macro.
> 
> Everything needed to get this running (including iptables patches) is at:
> http://people.redhat.com/jmorris/selinux/secmark/
> 
> I've also added a patch at the site which adds a kernel boot param to 
> determine whether to use the old or new packet controls, although I'm 
> still not sure whether it's justified adding this stuff to the kernel when 
> it can be set at runtime during early boot.
> 
> Please review and let me know if there any further issues.
[Code snipped]

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [RFC] SECMARK 1.1
  2006-05-17 13:36   ` Thomas Bleher
@ 2006-05-17 14:56     ` James Morris
  0 siblings, 0 replies; 41+ messages in thread
From: James Morris @ 2006-05-17 14:56 UTC (permalink / raw)
  To: Thomas Bleher
  Cc: selinux, netdev, netfilter-devel, Stephen Smalley, Daniel J Walsh,
	Karl MacMillan, Patrick McHardy, David S. Miller

On Wed, 17 May 2006, Thomas Bleher wrote:

> This all looks very nice - Thank You!
> Just one question: does the code canonicalize the security label? It
> would be nice if the same rules could be used on MLS and non-MLS
> systems.

No, it shouldn't be necessary, as there's no legacy installed base of 
rulesets (as there was with disk files), and MLS is now generally enabled 
by default.  Also, these rules are never exposed to general users, and 
even sysadmins should generate the rules via some kind of tool.

It would also add some complexity.


- James
-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2006-05-17 14:56 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-05-07 15:31 [RFC] SECMARK 1.0 James Morris
2006-05-07 15:33 ` [RFC] [SECMARK 01/08] Add secmark support to core networking James Morris
2006-05-07 15:34 ` [RFC][SECMARK 02/08] Export selinux_string_to_sid from SELinux James Morris
2006-05-07 15:35 ` [RFC][SECMARK 03/08] Add xtables SECMARK target James Morris
2006-05-10  6:03   ` Patrick McHardy
2006-05-10 13:30     ` James Morris
2006-05-11  7:06       ` Patrick McHardy
2006-05-07 15:36 ` [RFC][SECMARK 04/08] Add new flask definitions to SELinux James Morris
2006-05-07 15:37 ` [RFC][SECMARK 05/08] Add new packet controls " James Morris
2006-05-07 15:38 ` [RFC][SECMARK 06/08] Define a relabelto permission in the SELinux packet class James Morris
2006-05-07 15:39 ` [RFC][SECMARK 07/08] Add selinux_relabel_packet_permission() to SELinux API James Morris
2006-05-07 15:40 ` [RFC][SECMARK 08/08] Add selinux_relabel_packet_permission() check to xt_SECMARK James Morris
2006-05-08 17:54   ` Karl MacMillan
2006-05-08 21:19     ` James Morris
2006-05-07 15:42 ` [RFC][SECMARK userland 01/03] Add libselinux support James Morris
2006-05-07 15:43 ` [RFC][SECMARK userland 02/03] Add libipt_SECMARK James Morris
2006-05-07 15:44 ` [RFC][SECMARK userland 03/03] Add libip6t_SECMARK James Morris
2006-05-07 17:04 ` [RFC] SECMARK 1.0 Joshua Brindle
2006-05-07 17:43   ` James Morris
2006-05-08 17:41     ` Karl MacMillan
2006-05-08 21:29       ` James Morris
2006-05-09 13:24         ` Karl MacMillan
2006-05-09 16:40           ` James Morris
2006-05-09 17:06             ` Karl MacMillan
2006-05-09 18:56               ` James Morris
2006-05-09 17:11             ` Stephen Smalley
2006-05-07 17:44 ` James Morris
2006-05-14  6:03 ` [RFC] SECMARK 1.1 James Morris
2006-05-14 18:37   ` Patrick McHardy
2006-05-15  4:24     ` James Morris
2006-05-15  5:29       ` Patrick McHardy
2006-05-15  5:57         ` James Morris
2006-05-15  6:04           ` Patrick McHardy
2006-05-15  6:22             ` James Morris
2006-05-15  6:26               ` Patrick McHardy
2006-05-15  6:37                 ` James Morris
2006-05-15  6:42                   ` James Morris
2006-05-15  6:43                   ` Patrick McHardy
2006-05-15 12:35   ` Karl MacMillan
2006-05-17 13:36   ` Thomas Bleher
2006-05-17 14:56     ` James Morris

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).