diff options
-rw-r--r-- | include/linux/netfilter_ipv4.h | 1 | ||||
-rw-r--r-- | include/net/netns/ipv4.h | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/Kconfig | 12 | ||||
-rw-r--r-- | net/ipv4/netfilter/Makefile | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/iptable_security.c | 180 | ||||
-rw-r--r-- | net/netfilter/xt_CONNSECMARK.c | 10 | ||||
-rw-r--r-- | net/netfilter/xt_SECMARK.c | 10 |
7 files changed, 209 insertions, 6 deletions
diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h index 650318b0c405..29c7727ff0e8 100644 --- a/include/linux/netfilter_ipv4.h +++ b/include/linux/netfilter_ipv4.h | |||
@@ -60,6 +60,7 @@ enum nf_ip_hook_priorities { | |||
60 | NF_IP_PRI_MANGLE = -150, | 60 | NF_IP_PRI_MANGLE = -150, |
61 | NF_IP_PRI_NAT_DST = -100, | 61 | NF_IP_PRI_NAT_DST = -100, |
62 | NF_IP_PRI_FILTER = 0, | 62 | NF_IP_PRI_FILTER = 0, |
63 | NF_IP_PRI_SECURITY = 50, | ||
63 | NF_IP_PRI_NAT_SRC = 100, | 64 | NF_IP_PRI_NAT_SRC = 100, |
64 | NF_IP_PRI_SELINUX_LAST = 225, | 65 | NF_IP_PRI_SELINUX_LAST = 225, |
65 | NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX, | 66 | NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX, |
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index 34ee348a2cf2..6ef90b5fafb3 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h | |||
@@ -36,6 +36,7 @@ struct netns_ipv4 { | |||
36 | struct xt_table *iptable_mangle; | 36 | struct xt_table *iptable_mangle; |
37 | struct xt_table *iptable_raw; | 37 | struct xt_table *iptable_raw; |
38 | struct xt_table *arptable_filter; | 38 | struct xt_table *arptable_filter; |
39 | struct xt_table *iptable_security; | ||
39 | #endif | 40 | #endif |
40 | 41 | ||
41 | int sysctl_icmp_echo_ignore_all; | 42 | int sysctl_icmp_echo_ignore_all; |
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 2767841a8cef..6e251402506e 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
@@ -365,6 +365,18 @@ config IP_NF_RAW | |||
365 | If you want to compile it as a module, say M here and read | 365 | If you want to compile it as a module, say M here and read |
366 | <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. | 366 | <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. |
367 | 367 | ||
368 | # security table for MAC policy | ||
369 | config IP_NF_SECURITY | ||
370 | tristate "Security table" | ||
371 | depends on IP_NF_IPTABLES | ||
372 | depends on SECURITY | ||
373 | default m if NETFILTER_ADVANCED=n | ||
374 | help | ||
375 | This option adds a `security' table to iptables, for use | ||
376 | with Mandatory Access Control (MAC) policy. | ||
377 | |||
378 | If unsure, say N. | ||
379 | |||
368 | # ARP tables | 380 | # ARP tables |
369 | config IP_NF_ARPTABLES | 381 | config IP_NF_ARPTABLES |
370 | tristate "ARP tables support" | 382 | tristate "ARP tables support" |
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index d9b92fbf5579..3f31291f37ce 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
@@ -42,6 +42,7 @@ obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o | |||
42 | obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o | 42 | obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o |
43 | obj-$(CONFIG_NF_NAT) += iptable_nat.o | 43 | obj-$(CONFIG_NF_NAT) += iptable_nat.o |
44 | obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o | 44 | obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o |
45 | obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.o | ||
45 | 46 | ||
46 | # matches | 47 | # matches |
47 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o | 48 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o |
diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c new file mode 100644 index 000000000000..2b472ac2263a --- /dev/null +++ b/net/ipv4/netfilter/iptable_security.c | |||
@@ -0,0 +1,180 @@ | |||
1 | /* | ||
2 | * "security" table | ||
3 | * | ||
4 | * This is for use by Mandatory Access Control (MAC) security models, | ||
5 | * which need to be able to manage security policy in separate context | ||
6 | * to DAC. | ||
7 | * | ||
8 | * Based on iptable_mangle.c | ||
9 | * | ||
10 | * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling | ||
11 | * Copyright (C) 2000-2004 Netfilter Core Team <coreteam <at> netfilter.org> | ||
12 | * Copyright (C) 2008 Red Hat, Inc., James Morris <jmorris <at> redhat.com> | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License version 2 as | ||
16 | * published by the Free Software Foundation. | ||
17 | */ | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
20 | #include <net/ip.h> | ||
21 | |||
22 | MODULE_LICENSE("GPL"); | ||
23 | MODULE_AUTHOR("James Morris <jmorris <at> redhat.com>"); | ||
24 | MODULE_DESCRIPTION("iptables security table, for MAC rules"); | ||
25 | |||
26 | #define SECURITY_VALID_HOOKS (1 << NF_INET_LOCAL_IN) | \ | ||
27 | (1 << NF_INET_FORWARD) | \ | ||
28 | (1 << NF_INET_LOCAL_OUT) | ||
29 | |||
30 | static struct | ||
31 | { | ||
32 | struct ipt_replace repl; | ||
33 | struct ipt_standard entries[3]; | ||
34 | struct ipt_error term; | ||
35 | } initial_table __initdata = { | ||
36 | .repl = { | ||
37 | .name = "security", | ||
38 | .valid_hooks = SECURITY_VALID_HOOKS, | ||
39 | .num_entries = 4, | ||
40 | .size = sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error), | ||
41 | .hook_entry = { | ||
42 | [NF_INET_LOCAL_IN] = 0, | ||
43 | [NF_INET_FORWARD] = sizeof(struct ipt_standard), | ||
44 | [NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard) * 2, | ||
45 | }, | ||
46 | .underflow = { | ||
47 | [NF_INET_LOCAL_IN] = 0, | ||
48 | [NF_INET_FORWARD] = sizeof(struct ipt_standard), | ||
49 | [NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard) * 2, | ||
50 | }, | ||
51 | }, | ||
52 | .entries = { | ||
53 | IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */ | ||
54 | IPT_STANDARD_INIT(NF_ACCEPT), /* FORWARD */ | ||
55 | IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ | ||
56 | }, | ||
57 | .term = IPT_ERROR_INIT, /* ERROR */ | ||
58 | }; | ||
59 | |||
60 | static struct xt_table security_table = { | ||
61 | .name = "security", | ||
62 | .valid_hooks = SECURITY_VALID_HOOKS, | ||
63 | .lock = __RW_LOCK_UNLOCKED(security_table.lock), | ||
64 | .me = THIS_MODULE, | ||
65 | .af = AF_INET, | ||
66 | }; | ||
67 | |||
68 | static unsigned int | ||
69 | ipt_local_in_hook(unsigned int hook, | ||
70 | struct sk_buff *skb, | ||
71 | const struct net_device *in, | ||
72 | const struct net_device *out, | ||
73 | int (*okfn)(struct sk_buff *)) | ||
74 | { | ||
75 | return ipt_do_table(skb, hook, in, out, | ||
76 | nf_local_in_net(in, out)->ipv4.iptable_security); | ||
77 | } | ||
78 | |||
79 | static unsigned int | ||
80 | ipt_forward_hook(unsigned int hook, | ||
81 | struct sk_buff *skb, | ||
82 | const struct net_device *in, | ||
83 | const struct net_device *out, | ||
84 | int (*okfn)(struct sk_buff *)) | ||
85 | { | ||
86 | return ipt_do_table(skb, hook, in, out, | ||
87 | nf_forward_net(in, out)->ipv4.iptable_security); | ||
88 | } | ||
89 | |||
90 | static unsigned int | ||
91 | ipt_local_out_hook(unsigned int hook, | ||
92 | struct sk_buff *skb, | ||
93 | const struct net_device *in, | ||
94 | const struct net_device *out, | ||
95 | int (*okfn)(struct sk_buff *)) | ||
96 | { | ||
97 | /* Somebody is playing with raw sockets. */ | ||
98 | if (skb->len < sizeof(struct iphdr) | ||
99 | || ip_hdrlen(skb) < sizeof(struct iphdr)) { | ||
100 | if (net_ratelimit()) | ||
101 | printk(KERN_INFO "iptable_security: ignoring short " | ||
102 | "SOCK_RAW packet.\n"); | ||
103 | return NF_ACCEPT; | ||
104 | } | ||
105 | return ipt_do_table(skb, hook, in, out, | ||
106 | nf_local_out_net(in, out)->ipv4.iptable_security); | ||
107 | } | ||
108 | |||
109 | static struct nf_hook_ops ipt_ops[] __read_mostly = { | ||
110 | { | ||
111 | .hook = ipt_local_in_hook, | ||
112 | .owner = THIS_MODULE, | ||
113 | .pf = PF_INET, | ||
114 | .hooknum = NF_INET_LOCAL_IN, | ||
115 | .priority = NF_IP_PRI_SECURITY, | ||
116 | }, | ||
117 | { | ||
118 | .hook = ipt_forward_hook, | ||
119 | .owner = THIS_MODULE, | ||
120 | .pf = PF_INET, | ||
121 | .hooknum = NF_INET_FORWARD, | ||
122 | .priority = NF_IP_PRI_SECURITY, | ||
123 | }, | ||
124 | { | ||
125 | .hook = ipt_local_out_hook, | ||
126 | .owner = THIS_MODULE, | ||
127 | .pf = PF_INET, | ||
128 | .hooknum = NF_INET_LOCAL_OUT, | ||
129 | .priority = NF_IP_PRI_SECURITY, | ||
130 | }, | ||
131 | }; | ||
132 | |||
133 | static int __net_init iptable_security_net_init(struct net *net) | ||
134 | { | ||
135 | net->ipv4.iptable_security = | ||
136 | ipt_register_table(net, &security_table, &initial_table.repl); | ||
137 | |||
138 | if (IS_ERR(net->ipv4.iptable_security)) | ||
139 | return PTR_ERR(net->ipv4.iptable_security); | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | static void __net_exit iptable_security_net_exit(struct net *net) | ||
145 | { | ||
146 | ipt_unregister_table(net->ipv4.iptable_security); | ||
147 | } | ||
148 | |||
149 | static struct pernet_operations iptable_security_net_ops = { | ||
150 | .init = iptable_security_net_init, | ||
151 | .exit = iptable_security_net_exit, | ||
152 | }; | ||
153 | |||
154 | static int __init iptable_security_init(void) | ||
155 | { | ||
156 | int ret; | ||
157 | |||
158 | ret = register_pernet_subsys(&iptable_security_net_ops); | ||
159 | if (ret < 0) | ||
160 | return ret; | ||
161 | |||
162 | ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); | ||
163 | if (ret < 0) | ||
164 | goto cleanup_table; | ||
165 | |||
166 | return ret; | ||
167 | |||
168 | cleanup_table: | ||
169 | unregister_pernet_subsys(&iptable_security_net_ops); | ||
170 | return ret; | ||
171 | } | ||
172 | |||
173 | static void __exit iptable_security_fini(void) | ||
174 | { | ||
175 | nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); | ||
176 | unregister_pernet_subsys(&iptable_security_net_ops); | ||
177 | } | ||
178 | |||
179 | module_init(iptable_security_init); | ||
180 | module_exit(iptable_security_fini); | ||
diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c index 211189eb2b67..76ca1f2421eb 100644 --- a/net/netfilter/xt_CONNSECMARK.c +++ b/net/netfilter/xt_CONNSECMARK.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> | 8 | * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> |
9 | * by Henrik Nordstrom <hno@marasystems.com> | 9 | * by Henrik Nordstrom <hno@marasystems.com> |
10 | * | 10 | * |
11 | * (C) 2006 Red Hat, Inc., James Morris <jmorris@redhat.com> | 11 | * (C) 2006,2008 Red Hat, Inc., James Morris <jmorris@redhat.com> |
12 | * | 12 | * |
13 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
14 | * it under the terms of the GNU General Public License version 2 as | 14 | * it under the terms of the GNU General Public License version 2 as |
@@ -94,6 +94,12 @@ connsecmark_tg_check(const char *tablename, const void *entry, | |||
94 | { | 94 | { |
95 | const struct xt_connsecmark_target_info *info = targinfo; | 95 | const struct xt_connsecmark_target_info *info = targinfo; |
96 | 96 | ||
97 | if (strcmp(tablename, "mangle") && strcmp(tablename, "security")) { | ||
98 | printk(KERN_INFO PFX "target only valid in the \'mangle\' " | ||
99 | "or \'security\' tables, not \'%s\'.\n", tablename); | ||
100 | return false; | ||
101 | } | ||
102 | |||
97 | switch (info->mode) { | 103 | switch (info->mode) { |
98 | case CONNSECMARK_SAVE: | 104 | case CONNSECMARK_SAVE: |
99 | case CONNSECMARK_RESTORE: | 105 | case CONNSECMARK_RESTORE: |
@@ -126,7 +132,6 @@ static struct xt_target connsecmark_tg_reg[] __read_mostly = { | |||
126 | .destroy = connsecmark_tg_destroy, | 132 | .destroy = connsecmark_tg_destroy, |
127 | .target = connsecmark_tg, | 133 | .target = connsecmark_tg, |
128 | .targetsize = sizeof(struct xt_connsecmark_target_info), | 134 | .targetsize = sizeof(struct xt_connsecmark_target_info), |
129 | .table = "mangle", | ||
130 | .me = THIS_MODULE, | 135 | .me = THIS_MODULE, |
131 | }, | 136 | }, |
132 | { | 137 | { |
@@ -136,7 +141,6 @@ static struct xt_target connsecmark_tg_reg[] __read_mostly = { | |||
136 | .destroy = connsecmark_tg_destroy, | 141 | .destroy = connsecmark_tg_destroy, |
137 | .target = connsecmark_tg, | 142 | .target = connsecmark_tg, |
138 | .targetsize = sizeof(struct xt_connsecmark_target_info), | 143 | .targetsize = sizeof(struct xt_connsecmark_target_info), |
139 | .table = "mangle", | ||
140 | .me = THIS_MODULE, | 144 | .me = THIS_MODULE, |
141 | }, | 145 | }, |
142 | }; | 146 | }; |
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c index c0284856ccd4..94f87ee7552b 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * Based on the nfmark match by: | 5 | * Based on the nfmark match by: |
6 | * (C) 1999-2001 Marc Boucher <marc@mbsi.ca> | 6 | * (C) 1999-2001 Marc Boucher <marc@mbsi.ca> |
7 | * | 7 | * |
8 | * (C) 2006 Red Hat, Inc., James Morris <jmorris@redhat.com> | 8 | * (C) 2006,2008 Red Hat, Inc., James Morris <jmorris@redhat.com> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 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 | 11 | * it under the terms of the GNU General Public License version 2 as |
@@ -89,6 +89,12 @@ secmark_tg_check(const char *tablename, const void *entry, | |||
89 | { | 89 | { |
90 | struct xt_secmark_target_info *info = targinfo; | 90 | struct xt_secmark_target_info *info = targinfo; |
91 | 91 | ||
92 | if (strcmp(tablename, "mangle") && strcmp(tablename, "security")) { | ||
93 | printk(KERN_INFO PFX "target only valid in the \'mangle\' " | ||
94 | "or \'security\' tables, not \'%s\'.\n", tablename); | ||
95 | return false; | ||
96 | } | ||
97 | |||
92 | if (mode && mode != info->mode) { | 98 | if (mode && mode != info->mode) { |
93 | printk(KERN_INFO PFX "mode already set to %hu cannot mix with " | 99 | printk(KERN_INFO PFX "mode already set to %hu cannot mix with " |
94 | "rules for mode %hu\n", mode, info->mode); | 100 | "rules for mode %hu\n", mode, info->mode); |
@@ -127,7 +133,6 @@ static struct xt_target secmark_tg_reg[] __read_mostly = { | |||
127 | .destroy = secmark_tg_destroy, | 133 | .destroy = secmark_tg_destroy, |
128 | .target = secmark_tg, | 134 | .target = secmark_tg, |
129 | .targetsize = sizeof(struct xt_secmark_target_info), | 135 | .targetsize = sizeof(struct xt_secmark_target_info), |
130 | .table = "mangle", | ||
131 | .me = THIS_MODULE, | 136 | .me = THIS_MODULE, |
132 | }, | 137 | }, |
133 | { | 138 | { |
@@ -137,7 +142,6 @@ static struct xt_target secmark_tg_reg[] __read_mostly = { | |||
137 | .destroy = secmark_tg_destroy, | 142 | .destroy = secmark_tg_destroy, |
138 | .target = secmark_tg, | 143 | .target = secmark_tg, |
139 | .targetsize = sizeof(struct xt_secmark_target_info), | 144 | .targetsize = sizeof(struct xt_secmark_target_info), |
140 | .table = "mangle", | ||
141 | .me = THIS_MODULE, | 145 | .me = THIS_MODULE, |
142 | }, | 146 | }, |
143 | }; | 147 | }; |