linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* SMACK netfilter smacklabel socket match
@ 2008-09-25 17:25 Tilman Baumann
  2008-09-25 18:26 ` Paul Moore
  2008-09-26  3:43 ` Casey Schaufler
  0 siblings, 2 replies; 30+ messages in thread
From: Tilman Baumann @ 2008-09-25 17:25 UTC (permalink / raw)
  To: Linux-Kernel

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

Hi all,

i made some SMACK related patches. I hope this list is the right place 
to post them.

The intention behind this patch is that i needed a way to (firewall) 
match for packets originating from specific processes.
The existing owner match did not work well enough, especially since the 
cmd-owner part is removed.
Then i thought about a way to tag processes and somehow match this tag 
in the firewall.
I recalled that SELinux can do this (SECMARK) but SELinux would have 
been way to complex for what i want. But the idea was born, i just 
needed something more simple.

SMACK seemed to be the right way. So i made a little primitive netfilter 
match to match against the security context of sockets.
SMACK does CIPSO labels, but this was not what i wanted, i wanted to 
label the socket not the packet (on the wire).
This of course only works for packets with a local socket, but this was 
my intention anyway.

This way i can label a process and all it's sockets carry the same label 
which i then can use to match against in the firewall.

The code is pretty much based on cargo cult coding from other netfilter 
matches, especially the owner match (which turned out to be a bad 
reference since it is crapped with tons of compat interfaces).

I have no kernel coding experience whatsoever and little C coding 
history. So i would really like you guys to look over it a bit.

Originally i intended to put this mask in the xtables_match structure.
.hooks = (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_LOCAL_IN)
But it turned out that i then could not longer put the rule in a chain 
which is called by the OUTPUT chain but only in OUTPUT directly.
I did not investigate much more since i did not really understand this 
part. Allowing the user to add this match wherever he wants to does not 
hurt, if there is no local socket there is no matching.
But maybe this is something that should be changed.

About the Files:
SMACK-netfilter-socket-label-match.patch
is a git patch for the current kernel.

iptables-smacklabel.patch
contains the iptables userspace part (applies to iptables-1.4.1.1)


Regards
  Tilman Baumann
-- 
Tilman Baumann
Software Developer
Collax GmbH . Boetzinger Strasse 60 . 79111 Freiburg . Germany

p: +49 (0) 89-990157-0
f: +49 (0) 89-990157-11

Geschaeftsfuehrer: William K. Hite / Boris Nalbach
AG Muenchen HRB 158898, Ust.-IdNr: DE 814464942

[-- Attachment #2: SMACK-netfilter-socket-label-match.patch --]
[-- Type: text/x-patch, Size: 5430 bytes --]

>From 1c79c7c413dd3ebd72dbe12e1133037c6ea223af Mon Sep 17 00:00:00 2001
From: Tilman Baumann <tilman.baumann@collax.com>
Date: Thu, 25 Sep 2008 19:07:37 +0200
Subject: [PATCH] SMACK netfilter socket label match


Signed-off-by: Tilman Baumann <tilman.baumann@collax.com>
---
 include/linux/netfilter/Kbuild     |    1 +
 include/linux/netfilter/xt_smack.h |   21 +++++++++
 net/netfilter/Kconfig              |   10 +++++
 net/netfilter/Makefile             |    1 +
 net/netfilter/xt_smack.c           |   79 ++++++++++++++++++++++++++++++++++++
 5 files changed, 112 insertions(+), 0 deletions(-)
 create mode 100644 include/linux/netfilter/xt_smack.h
 create mode 100644 net/netfilter/xt_smack.c

diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild
index 3aff513..9c8fffd 100644
--- a/include/linux/netfilter/Kbuild
+++ b/include/linux/netfilter/Kbuild
@@ -29,6 +29,7 @@ header-y += xt_mac.h
 header-y += xt_mark.h
 header-y += xt_multiport.h
 header-y += xt_owner.h
+header-y += xt_smack.h
 header-y += xt_pkttype.h
 header-y += xt_rateest.h
 header-y += xt_realm.h
diff --git a/include/linux/netfilter/xt_smack.h b/include/linux/netfilter/xt_smack.h
new file mode 100644
index 0000000..a3a4471
--- /dev/null
+++ b/include/linux/netfilter/xt_smack.h
@@ -0,0 +1,21 @@
+#ifndef _XT_SMACK_MATCH_H
+#define _XT_SMACK_MATCH_H
+
+#define SMK_MAXLEN      23
+#define SMK_LABELLEN    (SMK_MAXLEN+1)
+
+enum {
+	XT_SMACK_IN   = 1 << 0,
+	XT_SMACK_OUT  = 1 << 1,
+	XT_SMACK_PEER = 1 << 2,
+};
+
+struct xt_smack_match_info {
+	u_int8_t	mask, invert;
+	char    	match_in[SMK_LABELLEN];
+	char    	match_out[SMK_LABELLEN];
+	char    	match_peer_packet[SMK_LABELLEN];
+
+};
+
+#endif /* _XT_SMACK_MATCH_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index ee898e7..e03ff69 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -650,6 +650,16 @@ config NETFILTER_XT_MATCH_OWNER
 	based on who created the socket: the user or group. It is also
 	possible to check whether a socket actually exists.
 
+config NETFILTER_XT_MATCH_SMACK
+	tristate '"smack" socket label match support'
+	depends on NETFILTER_XTABLES
+	depends on NETFILTER_ADVANCED
+	depends on SECURITY_SMACK
+	help
+	  SMACK label matching allows you to match locally generated packets
+	  based on the smack labels of the socket which is inherited from the
+	  associated process and allows matching on the TCP peers CIPSO label.
+
 config NETFILTER_XT_MATCH_POLICY
 	tristate 'IPsec "policy" match support'
 	depends on NETFILTER_XTABLES && XFRM
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 3bd2cc5..dc2efe5 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -83,3 +83,4 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_TIME) += xt_time.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_SMACK) += xt_smack.o
diff --git a/net/netfilter/xt_smack.c b/net/netfilter/xt_smack.c
new file mode 100644
index 0000000..b41a559
--- /dev/null
+++ b/net/netfilter/xt_smack.c
@@ -0,0 +1,79 @@
+/*
+ * Kernel module to match against SMACK labels
+ *
+ * (C) 2008 Tilman Baumann <tilman.baumann@collax.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/file.h>
+#include <net/sock.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_smack.h>
+#include <../security/smack/smack.h>
+
+
+static bool
+smack_mt(const struct sk_buff *skb, const struct net_device *in,
+         const struct net_device *out, const struct xt_match *match,
+         const void *matchinfo, int offset, unsigned int protoff,
+         bool *hotdrop)
+{
+	const struct xt_smack_match_info *info = matchinfo;
+	struct socket_smack *smacks;
+
+	if (skb->sk == NULL || skb->sk->sk_socket == NULL)
+		return (info->mask ^ info->invert) == 0;
+	smacks = skb->sk->sk_security;
+	if (smacks == NULL){
+		 return (info->mask ^ info->invert);
+	}
+
+	if(info->mask & XT_SMACK_IN){
+		return ! ((!strncmp(smacks->smk_in, info->match_in, SMK_LABELLEN)) ^
+			(info->invert & XT_SMACK_IN));
+	}
+	
+	if(info->mask & XT_SMACK_OUT){
+		return ! ((!strncmp(smacks->smk_in, info->match_out, SMK_LABELLEN)) ^
+			(info->invert & XT_SMACK_OUT));
+	}
+
+	if(info->mask & XT_SMACK_PEER){
+		return ! ((!strncmp(smacks->smk_packet, info->match_peer_packet, SMK_LABELLEN)) ^
+			(info->invert & XT_SMACK_IN));
+	}
+	return true;
+}
+
+
+static struct xt_match smack_mt_reg[] __read_mostly = {
+	{
+		.name       = "smack",
+		.match      = smack_mt,
+		.matchsize  = sizeof(struct xt_smack_match_info),
+		.family     = AF_INET,
+		.me         = THIS_MODULE,
+	},
+};
+
+static int __init smack_mt_init(void)
+{
+	return xt_register_matches(smack_mt_reg, ARRAY_SIZE(smack_mt_reg));
+}
+
+static void __exit smack_mt_exit(void)
+{
+	xt_unregister_matches(smack_mt_reg, ARRAY_SIZE(smack_mt_reg));
+}
+
+module_init(smack_mt_init);
+module_exit(smack_mt_exit);
+MODULE_AUTHOR("Tilman Baumann <tilman@baumann.name>");
+MODULE_DESCRIPTION("Xtables: socket SMACK label matching");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_smack");
+MODULE_ALIAS("ip6t_smack");
-- 
1.5.6.3


[-- Attachment #3: iptables-smacklabel.patch --]
[-- Type: text/x-patch, Size: 4461 bytes --]

diff -Nur iptables-1.4.1.1/extensions/libxt_smack.c iptables-1.4.1.1-new/extensions/libxt_smack.c
--- iptables-1.4.1.1/extensions/libxt_smack.c	1970-01-01 01:00:00.000000000 +0100
+++ iptables-1.4.1.1-new/extensions/libxt_smack.c	2008-09-11 18:15:23.000000000 +0200
@@ -0,0 +1,129 @@
+#include <stdbool.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include <xtables.h>
+#include <linux/netfilter/xt_smack.h>
+
+/* Function which prints out usage message. */
+static void smack_help(void)
+{
+	printf(
+"smack match options:\n"
+"[!] --in       label      Match socket in label\n"
+"[!] --out      label      Match socket out label\n"
+"[!] --tcp-peer label      Match TCP peer label (CIPSO)\n");
+}
+
+
+static const struct option smack_opts[] = {
+	{.name = "in",       .has_arg = true, .val = 'i'},
+	{.name = "out",      .has_arg = true, .val = 'o'},
+	{.name = "tcp-peer", .has_arg = true, .val = 'p'},
+	{ .name = NULL }
+};
+
+static void parse_label(const char *s, char *d)
+{	
+	int slen = strlen(s);
+
+	if (slen >= SMK_LABELLEN) {
+		exit_error(PARAMETER_PROBLEM,
+			"SMACK label must be shorter than %i characters", SMK_LABELLEN);
+	}
+	strcpy(d, s);
+}
+
+static int smack_parse(int c, char **argv, int invert, unsigned int *flags,
+                          const void *entry, struct xt_entry_match **match)
+{
+	struct xt_smack_match_info *info = (void *)(*match)->data;
+
+	switch (c) {
+	case 'i':
+		param_act(P_ONLY_ONCE, "smack", "--in", *flags & XT_SMACK_IN);
+		
+		if (invert)
+			info->invert |= XT_SMACK_IN;
+		info->mask  |= XT_SMACK_IN;
+		parse_label(optarg, info->match_in);
+		*flags       |= XT_SMACK_IN;
+		return true;
+
+	case 'o':
+		param_act(P_ONLY_ONCE, "smack", "--out", *flags & XT_SMACK_OUT);
+		
+		if (invert)
+			info->invert |= XT_SMACK_OUT;
+		info->mask  |= XT_SMACK_OUT;
+		parse_label(optarg, info->match_out);
+		*flags       |= XT_SMACK_OUT;
+		return true;
+
+	case 'p':
+		param_act(P_ONLY_ONCE, "smack", "--tcp-peer", *flags & XT_SMACK_PEER);
+		
+		if (invert)
+			info->invert |= XT_SMACK_PEER;
+		info->mask  |= XT_SMACK_PEER;
+		parse_label(optarg, info->match_peer_packet);
+		*flags       |= XT_SMACK_PEER;
+		return true;
+	}
+	return false;
+}
+
+static void smack_check(unsigned int flags)
+{
+	if (!flags)
+		exit_error(PARAMETER_PROBLEM,
+			   "SMACK match: You must at least specify one match");
+}
+
+static void smack_save_item(const char *param, const char *label, u_int8_t invert){
+	if (invert)
+		printf("! ");
+	printf("--%s \"%s\" ", param, label);
+}
+
+static void smack_save(const void *ip, const struct xt_entry_match *match)
+{
+	struct xt_smack_match_info *info = (struct xt_smack_match_info *)match->data;
+
+	if(info->mask & XT_SMACK_IN)
+		smack_save_item("in", info->match_in, info->invert & XT_SMACK_IN);
+	if(info->mask & XT_SMACK_OUT)
+		smack_save_item("out", info->match_out, info->invert & XT_SMACK_OUT);
+	if(info->mask & XT_SMACK_PEER)
+		smack_save_item("tcp-peer", info->match_peer_packet, info->invert & XT_SMACK_PEER);
+
+}
+
+static void smack_print(const void *ip, const struct xt_entry_match *match, int numeric)
+{
+	printf("SMACK label match ");
+	smack_save(ip, match);
+	
+}
+
+static struct xtables_match smack_match = {
+	.family		= AF_UNSPEC,
+	.name		= "smack",
+	.version	= XTABLES_VERSION,
+	.size		= XT_ALIGN(sizeof(struct xt_smack_match_info)),
+	.userspacesize	= XT_ALIGN(sizeof(struct xt_smack_match_info)),
+	.help		= smack_help,
+	.parse		= smack_parse,
+	.final_check	= smack_check,
+	.print		= smack_print,
+	.save		= smack_save,
+	.extra_opts	= smack_opts,
+};
+
+void _init(void)
+{
+	xtables_register_match(&smack_match);
+}
diff -Nur iptables-1.4.1.1/include/linux/netfilter/xt_smack.h iptables-1.4.1.1-new/include/linux/netfilter/xt_smack.h
--- iptables-1.4.1.1/include/linux/netfilter/xt_smack.h	1970-01-01 01:00:00.000000000 +0100
+++ iptables-1.4.1.1-new/include/linux/netfilter/xt_smack.h	2008-09-11 17:36:25.000000000 +0200
@@ -0,0 +1,21 @@
+#ifndef _XT_SMACK_MATCH_H
+#define _XT_SMACK_MATCH_H
+
+#define SMK_MAXLEN      23
+#define SMK_LABELLEN    (SMK_MAXLEN+1)
+
+enum {
+	XT_SMACK_IN   = 1 << 0,
+	XT_SMACK_OUT  = 1 << 1,
+	XT_SMACK_PEER = 1 << 2,
+};
+
+struct xt_smack_match_info {
+	u_int8_t	mask, invert;
+	char    	match_in[SMK_LABELLEN];
+	char    	match_out[SMK_LABELLEN];
+	char    	match_peer_packet[SMK_LABELLEN];
+
+};
+
+#endif /* _XT_SMACK_MATCH_H */

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

end of thread, other threads:[~2008-12-11 16:29 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-09-25 17:25 SMACK netfilter smacklabel socket match Tilman Baumann
2008-09-25 18:26 ` Paul Moore
2008-09-25 19:26   ` Tilman Baumann
2008-09-25 19:57     ` Paul Moore
2008-09-25 20:32       ` Tilman Baumann
2008-09-26 12:35   ` Tilman Baumann
2008-09-26 19:55     ` Paul Moore
2008-09-26  3:43 ` Casey Schaufler
2008-09-26  8:19   ` Tilman Baumann
2008-09-27  5:01     ` Casey Schaufler
2008-09-29 16:21       ` Tilman Baumann
2008-09-30  3:29         ` Casey Schaufler
2008-10-01 11:29           ` Tilman Baumann
2008-10-01 15:21             ` Casey Schaufler
2008-10-01 16:55               ` Tilman Baumann
2008-10-01 18:22                 ` Casey Schaufler
2008-10-06 12:57                   ` Tilman Baumann
2008-10-06 23:05                     ` Ahmed S. Darwish
2008-10-07  2:42                     ` Casey Schaufler
2008-10-17 16:57                       ` Tilman Baumann
2008-10-17 17:53                         ` Casey Schaufler
2008-10-20 12:06                           ` Tilman Baumann
2008-10-20 15:01                             ` Casey Schaufler
2008-10-22  3:36                             ` Casey Schaufler
2008-10-30 16:06                               ` Tilman Baumann
2008-10-31  3:46                                 ` Casey Schaufler
2008-12-11  0:03                                 ` Casey Schaufler
2008-12-11 10:18                                   ` Tilman Baumann
2008-12-11 16:29                                     ` Casey Schaufler
2008-10-23 11:55                           ` Paul Moore

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