This patch is part of the kernel changes needed for the "secmark" match
in iptables.
Signed-off-by: Mr Dash Four <mr.dash.four(a)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
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(a)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);