diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/Kconfig | 9 | ||||
-rw-r--r-- | net/netfilter/Makefile | 1 | ||||
-rw-r--r-- | net/netfilter/xt_SECMARK.c | 156 |
3 files changed, 166 insertions, 0 deletions
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 | ||
177 | config 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 | |||
177 | config NETFILTER_XT_MATCH_COMMENT | 186 | config 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 | |||
28 | obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o | 28 | obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o |
29 | obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o | 29 | obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o |
30 | obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o | 30 | obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o |
31 | obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o | ||
31 | 32 | ||
32 | # matches | 33 | # matches |
33 | obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o | 34 | obj-$(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 | |||
21 | MODULE_LICENSE("GPL"); | ||
22 | MODULE_AUTHOR("James Morris <jmorris@redhat.com>"); | ||
23 | MODULE_DESCRIPTION("ip[6]tables SECMARK modification module"); | ||
24 | MODULE_ALIAS("ipt_SECMARK"); | ||
25 | MODULE_ALIAS("ip6t_SECMARK"); | ||
26 | |||
27 | #define PFX "SECMARK: " | ||
28 | |||
29 | static u8 mode; | ||
30 | |||
31 | static 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 | |||
56 | static 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 | |||
84 | static 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 | |||
112 | static 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 | |||
123 | static 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 | |||
134 | static 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 | |||
149 | static void __exit xt_secmark_fini(void) | ||
150 | { | ||
151 | xt_unregister_target(&ip6t_secmark_reg); | ||
152 | xt_unregister_target(&ipt_secmark_reg); | ||
153 | } | ||
154 | |||
155 | module_init(xt_secmark_init); | ||
156 | module_exit(xt_secmark_fini); | ||