This patch is part of the kernel changes needed for the "secmark" match in iptables. Signed-off-by: Mr Dash Four <mr.dash.four@xxxxxxxxxxxxxx> --- 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@xxxxxxxxxxxxxx>"); +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); -- selinux mailing list selinux@xxxxxxxxxxxxxxxxxxxxxxx https://admin.fedoraproject.org/mailman/listinfo/selinux