aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter/xt_SECMARK.h26
-rw-r--r--net/netfilter/Kconfig9
-rw-r--r--net/netfilter/Makefile1
-rw-r--r--net/netfilter/xt_SECMARK.c156
4 files changed, 192 insertions, 0 deletions
diff --git a/include/linux/netfilter/xt_SECMARK.h b/include/linux/netfilter/xt_SECMARK.h
new file mode 100644
index 000000000000..c53fbffa997d
--- /dev/null
+++ b/include/linux/netfilter/xt_SECMARK.h
@@ -0,0 +1,26 @@
1#ifndef _XT_SECMARK_H_target
2#define _XT_SECMARK_H_target
3
4/*
5 * This is intended for use by various security subsystems (but not
6 * at the same time).
7 *
8 * 'mode' refers to the specific security subsystem which the
9 * packets are being marked for.
10 */
11#define SECMARK_MODE_SEL 0x01 /* SELinux */
12#define SECMARK_SELCTX_MAX 256
13
14struct xt_secmark_target_selinux_info {
15 u_int32_t selsid;
16 char selctx[SECMARK_SELCTX_MAX];
17};
18
19struct xt_secmark_target_info {
20 u_int8_t mode;
21 union {
22 struct xt_secmark_target_selinux_info sel;
23 } u;
24};
25
26#endif /*_XT_SECMARK_H_target */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 85a7e1770252..10eccdd4d6ea 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -174,6 +174,15 @@ config NETFILTER_XT_TARGET_NOTRACK
174 If you want to compile it as a module, say M here and read 174 If you want to compile it as a module, say M here and read
175 <file:Documentation/modules.txt>. If unsure, say `N'. 175 <file:Documentation/modules.txt>. If unsure, say `N'.
176 176
177config NETFILTER_XT_TARGET_SECMARK
178 tristate '"SECMARK" target support'
179 depends on NETFILTER_XTABLES && NETWORK_SECMARK
180 help
181 The SECMARK target allows security marking of network
182 packets, for use with security subsystems.
183
184 To compile it as a module, choose M here. If unsure, say N.
185
177config NETFILTER_XT_MATCH_COMMENT 186config NETFILTER_XT_MATCH_COMMENT
178 tristate '"comment" match support' 187 tristate '"comment" match support'
179 depends on NETFILTER_XTABLES 188 depends on NETFILTER_XTABLES
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index df1da25f40df..3645de046890 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o
28obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o 28obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
29obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o 29obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
30obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o 30obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
31obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
31 32
32# matches 33# matches
33obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o 34obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
new file mode 100644
index 000000000000..c2ce9c4011cc
--- /dev/null
+++ b/net/netfilter/xt_SECMARK.c
@@ -0,0 +1,156 @@
1/*
2 * Module for modifying the secmark field of the skb, for use by
3 * security subsystems.
4 *
5 * Based on the nfmark match by:
6 * (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
7 *
8 * (C) 2006 Red Hat, Inc., James Morris <jmorris@redhat.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15#include <linux/module.h>
16#include <linux/skbuff.h>
17#include <linux/selinux.h>
18#include <linux/netfilter/x_tables.h>
19#include <linux/netfilter/xt_SECMARK.h>
20
21MODULE_LICENSE("GPL");
22MODULE_AUTHOR("James Morris <jmorris@redhat.com>");
23MODULE_DESCRIPTION("ip[6]tables SECMARK modification module");
24MODULE_ALIAS("ipt_SECMARK");
25MODULE_ALIAS("ip6t_SECMARK");
26
27#define PFX "SECMARK: "
28
29static u8 mode;
30
31static unsigned int target(struct sk_buff **pskb, const struct net_device *in,
32 const struct net_device *out, unsigned int hooknum,
33 const struct xt_target *target,
34 const void *targinfo, void *userinfo)
35{
36 u32 secmark = 0;
37 const struct xt_secmark_target_info *info = targinfo;
38
39 BUG_ON(info->mode != mode);
40
41 switch (mode) {
42 case SECMARK_MODE_SEL:
43 secmark = info->u.sel.selsid;
44 break;
45
46 default:
47 BUG();
48 }
49
50 if ((*pskb)->secmark != secmark)
51 (*pskb)->secmark = secmark;
52
53 return XT_CONTINUE;
54}
55
56static int checkentry_selinux(struct xt_secmark_target_info *info)
57{
58 int err;
59 struct xt_secmark_target_selinux_info *sel = &info->u.sel;
60
61 err = selinux_string_to_sid(sel->selctx, &sel->selsid);
62 if (err) {
63 if (err == -EINVAL)
64 printk(KERN_INFO PFX "invalid SELinux context \'%s\'\n",
65 sel->selctx);
66 return 0;
67 }
68
69 if (!sel->selsid) {
70 printk(KERN_INFO PFX "unable to map SELinux context \'%s\'\n",
71 sel->selctx);
72 return 0;
73 }
74
75 err = selinux_relabel_packet_permission(sel->selsid);
76 if (err) {
77 printk(KERN_INFO PFX "unable to obtain relabeling permission\n");
78 return 0;
79 }
80
81 return 1;
82}
83
84static int checkentry(const char *tablename, const void *entry,
85 const struct xt_target *target, void *targinfo,
86 unsigned int targinfosize, unsigned int hook_mask)
87{
88 struct xt_secmark_target_info *info = targinfo;
89
90 if (mode && mode != info->mode) {
91 printk(KERN_INFO PFX "mode already set to %hu cannot mix with "
92 "rules for mode %hu\n", mode, info->mode);
93 return 0;
94 }
95
96 switch (info->mode) {
97 case SECMARK_MODE_SEL:
98 if (!checkentry_selinux(info))
99 return 0;
100 break;
101
102 default:
103 printk(KERN_INFO PFX "invalid mode: %hu\n", info->mode);
104 return 0;
105 }
106
107 if (!mode)
108 mode = info->mode;
109 return 1;
110}
111
112static struct xt_target ipt_secmark_reg = {
113 .name = "SECMARK",
114 .target = target,
115 .targetsize = sizeof(struct xt_secmark_target_info),
116 .table = "mangle",
117 .checkentry = checkentry,
118 .me = THIS_MODULE,
119 .family = AF_INET,
120 .revision = 0,
121};
122
123static struct xt_target ip6t_secmark_reg = {
124 .name = "SECMARK",
125 .target = target,
126 .targetsize = sizeof(struct xt_secmark_target_info),
127 .table = "mangle",
128 .checkentry = checkentry,
129 .me = THIS_MODULE,
130 .family = AF_INET6,
131 .revision = 0,
132};
133
134static int __init xt_secmark_init(void)
135{
136 int err;
137
138 err = xt_register_target(&ipt_secmark_reg);
139 if (err)
140 return err;
141
142 err = xt_register_target(&ip6t_secmark_reg);
143 if (err)
144 xt_unregister_target(&ipt_secmark_reg);
145
146 return err;
147}
148
149static void __exit xt_secmark_fini(void)
150{
151 xt_unregister_target(&ip6t_secmark_reg);
152 xt_unregister_target(&ipt_secmark_reg);
153}
154
155module_init(xt_secmark_init);
156module_exit(xt_secmark_fini);