Patchwork [2/2] iptables (kernel): add secmark match

login
register
mail settings
Submitter Mr Dash Four
Date March 5, 2013, 12:48 p.m.
Message ID <5135E9BB.8080409@googlemail.com>
Download mbox | patch
Permalink /patch/225005/
State Not Applicable
Headers show

Comments

Mr Dash Four - March 5, 2013, 12:48 p.m.
This patch is part of the kernel changes needed for the "secmark" match
in iptables.

Signed-off-by: Mr Dash Four <mr.dash.four@googlemail.com>
---
  include/uapi/linux/netfilter/Kbuild       |    1 +
  include/uapi/linux/netfilter/xt_secmark.h |   24 ++++++
  net/netfilter/Kconfig                     |   10 +++
  net/netfilter/Makefile                    |    1 +
  net/netfilter/xt_secmark.c                |  117 +++++++++++++++++++++++++++++
  5 files changed, 153 insertions(+)
  create mode 100644 include/uapi/linux/netfilter/xt_secmark.h
  create mode 100644 net/netfilter/xt_secmark.c





--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/include/uapi/linux/netfilter/Kbuild b/include/uapi/linux/netfilter/Kbuild
index 4111577..4884edd 100644
--- a/include/uapi/linux/netfilter/Kbuild
+++ b/include/uapi/linux/netfilter/Kbuild
@@ -69,6 +69,7 @@  header-y += xt_rateest.h
  header-y += xt_realm.h
  header-y += xt_recent.h
  header-y += xt_sctp.h
+header-y += xt_secmark.h
  header-y += xt_set.h
  header-y += xt_socket.h
  header-y += xt_state.h
diff --git a/include/uapi/linux/netfilter/xt_secmark.h b/include/uapi/linux/netfilter/xt_secmark.h
new file mode 100644
index 0000000..c74a35d
--- /dev/null
+++ b/include/uapi/linux/netfilter/xt_secmark.h
@@ -0,0 +1,24 @@ 
+#ifndef _XT_SECMARK_MATCH_H
+#define _XT_SECMARK_MATCH_H
+
+#include <linux/types.h>
+
+/*
+ * Header file for iptables xt_secmark match
+ *
+ * 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_SECCTX_MAX	256
+
+struct xt_secmark_match_info {
+	__u8 mode;
+	__u32 secid;
+	char secctx[SECMARK_SECCTX_MAX];
+};
+
+#endif /* _XT_SECMARK_MATCH_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 56d22ca..d53ea14 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -1166,6 +1166,16 @@  config NETFILTER_XT_MATCH_RECENT
  	Short options are available by using 'iptables -m recent -h'
  	Official Website: <http://snowman.net/projects/ipt_recent/>

+config NETFILTER_XT_MATCH_SECMARK
+	tristate '"secmark" match support'
+	depends on NF_CONNTRACK && NF_CONNTRACK_SECMARK
+	default m if NETFILTER_ADVANCED=n
+	help
+	  The SECMARK match allows matching on 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_SCTP
  	tristate  '"sctp" protocol match support'
  	depends on NETFILTER_ADVANCED
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index a1abf87..686c4c3 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -139,6 +139,7 @@  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_SECMARK) += xt_secmark.o

  # ipset
  obj-$(CONFIG_IP_SET) += ipset/
diff --git a/net/netfilter/xt_secmark.c b/net/netfilter/xt_secmark.c
new file mode 100644
index 0000000..8837d13
--- /dev/null
+++ b/net/netfilter/xt_secmark.c
@@ -0,0 +1,117 @@ 
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 (or any
+ * later at your option) as published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/module.h>
+#include <linux/security.h>
+#include <linux/skbuff.h>
+
+#include <linux/netfilter/x_tables.h>
+#include <uapi/linux/netfilter/xt_secmark.h>
+
+MODULE_AUTHOR("Mr Dash Four <mr.dash.four@googlemail.com>");
+MODULE_DESCRIPTION("Xtables: security mark match");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_secmark");
+MODULE_ALIAS("ip6t_secmark");
+
+static u8 mode;
+
+static bool secmark_mt(const struct sk_buff *skb, struct xt_action_param *par)
+{
+	const struct xt_secmark_match_info *info = par->targinfo;
+	u32 secmark = 0;
+
+	BUG_ON(info->mode != mode);
+
+	switch (mode) {
+	case SECMARK_MODE_SEL:
+		secmark = info->secid;
+		break;
+	default:
+		BUG();
+	}
+
+	return (skb->secmark != 0 && secmark != 0 && skb->secmark == secmark);
+}
+
+static int checkentry_lsm(struct xt_secmark_match_info *info)
+{
+	int err;
+
+	info->secctx[SECMARK_SECCTX_MAX - 1] = '\0';
+	info->secid = 0;
+
+	err = security_secctx_to_secid(info->secctx, strlen(info->secctx),
+				       &info->secid);
+	if (err) {
+		if (err == -EINVAL)
+			pr_info("invalid security context \'%s\'\n", info->secctx);
+		return err;
+	}
+
+	if (!info->secid) {
+		pr_info("unable to map security context \'%s\'\n", info->secctx);
+		return -ENOENT;
+	}
+
+	return 0;
+}
+
+static int
+secmark_mt_checkentry(const struct xt_mtchk_param *par)
+{
+	struct xt_secmark_match_info *info = par->matchinfo;
+	int err;
+
+	if (mode && mode != info->mode) {
+		pr_info("mode already set to %hu cannot mix with "
+			"rules for mode %hu\n", mode, info->mode);
+		return -EINVAL;
+	}
+
+	switch (info->mode) {
+	case SECMARK_MODE_SEL:
+		break;
+	default:
+		pr_info("invalid mode: %hu\n", info->mode);
+		return -EINVAL;
+	}
+
+	err = checkentry_lsm(info);
+	if (err)
+		return err;
+
+	if (!mode)
+		mode = info->mode;
+	return 0;
+}
+
+static void
+secmark_mt_destroy(const struct xt_mtdtor_param *par) { }
+
+static struct xt_match secmark_mt_reg __read_mostly = {
+	.name       = "secmark",
+	.family     = NFPROTO_UNSPEC,
+	.checkentry = secmark_mt_checkentry,
+	.match      = secmark_mt,
+	.destroy    = secmark_mt_destroy,
+	.matchsize  = sizeof(struct xt_secmark_match_info),
+	.me         = THIS_MODULE,
+};
+
+static int __init secmark_mt_init(void)
+{
+	return xt_register_match(&secmark_mt_reg);
+}
+
+static void __exit secmark_mt_exit(void)
+{
+	xt_unregister_match(&secmark_mt_reg);
+}
+
+module_init(secmark_mt_init);
+module_exit(secmark_mt_exit);