diff options
author | James Morris <jmorris@namei.org> | 2008-06-09 18:58:05 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-06-09 18:58:05 -0400 |
commit | 17e6e59f0a1d7188d783c15dc3ccebd95a0840cd (patch) | |
tree | aabe39d205166733003dcc22b95bc77714691de1 | |
parent | 560ee653b67074b805f1b661988a72a0e58811a5 (diff) |
netfilter: ip6_tables: add ip6tables security table
This is a port of the IPv4 security table for IPv6.
Signed-off-by: James Morris <jmorris@namei.org>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/netfilter_ipv6.h | 1 | ||||
-rw-r--r-- | include/net/netns/ipv6.h | 1 | ||||
-rw-r--r-- | net/ipv6/netfilter/Kconfig | 12 | ||||
-rw-r--r-- | net/ipv6/netfilter/Makefile | 1 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6table_security.c | 172 |
5 files changed, 187 insertions, 0 deletions
diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h index 3475a65dae9b..fd50988b83ec 100644 --- a/include/linux/netfilter_ipv6.h +++ b/include/linux/netfilter_ipv6.h | |||
@@ -64,6 +64,7 @@ enum nf_ip6_hook_priorities { | |||
64 | NF_IP6_PRI_MANGLE = -150, | 64 | NF_IP6_PRI_MANGLE = -150, |
65 | NF_IP6_PRI_NAT_DST = -100, | 65 | NF_IP6_PRI_NAT_DST = -100, |
66 | NF_IP6_PRI_FILTER = 0, | 66 | NF_IP6_PRI_FILTER = 0, |
67 | NF_IP6_PRI_SECURITY = 50, | ||
67 | NF_IP6_PRI_NAT_SRC = 100, | 68 | NF_IP6_PRI_NAT_SRC = 100, |
68 | NF_IP6_PRI_SELINUX_LAST = 225, | 69 | NF_IP6_PRI_SELINUX_LAST = 225, |
69 | NF_IP6_PRI_LAST = INT_MAX, | 70 | NF_IP6_PRI_LAST = INT_MAX, |
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index ac053be6c256..5bacd838e88b 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h | |||
@@ -35,6 +35,7 @@ struct netns_ipv6 { | |||
35 | struct xt_table *ip6table_filter; | 35 | struct xt_table *ip6table_filter; |
36 | struct xt_table *ip6table_mangle; | 36 | struct xt_table *ip6table_mangle; |
37 | struct xt_table *ip6table_raw; | 37 | struct xt_table *ip6table_raw; |
38 | struct xt_table *ip6table_security; | ||
38 | #endif | 39 | #endif |
39 | struct rt6_info *ip6_null_entry; | 40 | struct rt6_info *ip6_null_entry; |
40 | struct rt6_statistics *rt6_stats; | 41 | struct rt6_statistics *rt6_stats; |
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 6cae5475737e..689dec899c57 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig | |||
@@ -208,5 +208,17 @@ config IP6_NF_RAW | |||
208 | If you want to compile it as a module, say M here and read | 208 | If you want to compile it as a module, say M here and read |
209 | <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. | 209 | <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. |
210 | 210 | ||
211 | # security table for MAC policy | ||
212 | config IP6_NF_SECURITY | ||
213 | tristate "Security table" | ||
214 | depends on IP6_NF_IPTABLES | ||
215 | depends on SECURITY | ||
216 | default m if NETFILTER_ADVANCED=n | ||
217 | help | ||
218 | This option adds a `security' table to iptables, for use | ||
219 | with Mandatory Access Control (MAC) policy. | ||
220 | |||
221 | If unsure, say N. | ||
222 | |||
211 | endmenu | 223 | endmenu |
212 | 224 | ||
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index fbf2c14ed887..3f17c948eefb 100644 --- a/net/ipv6/netfilter/Makefile +++ b/net/ipv6/netfilter/Makefile | |||
@@ -8,6 +8,7 @@ obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o | |||
8 | obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o | 8 | obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o |
9 | obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o | 9 | obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o |
10 | obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o | 10 | obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o |
11 | obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o | ||
11 | 12 | ||
12 | # objects for l3 independent conntrack | 13 | # objects for l3 independent conntrack |
13 | nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o | 14 | nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o |
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c new file mode 100644 index 000000000000..063a3d9c3c67 --- /dev/null +++ b/net/ipv6/netfilter/ip6table_security.c | |||
@@ -0,0 +1,172 @@ | |||
1 | /* | ||
2 | * "security" table for IPv6 | ||
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_ipv6/ip6_tables.h> | ||
20 | |||
21 | MODULE_LICENSE("GPL"); | ||
22 | MODULE_AUTHOR("James Morris <jmorris <at> redhat.com>"); | ||
23 | MODULE_DESCRIPTION("ip6tables security table, for MAC rules"); | ||
24 | |||
25 | #define SECURITY_VALID_HOOKS (1 << NF_INET_LOCAL_IN) | \ | ||
26 | (1 << NF_INET_FORWARD) | \ | ||
27 | (1 << NF_INET_LOCAL_OUT) | ||
28 | |||
29 | static struct | ||
30 | { | ||
31 | struct ip6t_replace repl; | ||
32 | struct ip6t_standard entries[3]; | ||
33 | struct ip6t_error term; | ||
34 | } initial_table __initdata = { | ||
35 | .repl = { | ||
36 | .name = "security", | ||
37 | .valid_hooks = SECURITY_VALID_HOOKS, | ||
38 | .num_entries = 4, | ||
39 | .size = sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error), | ||
40 | .hook_entry = { | ||
41 | [NF_INET_LOCAL_IN] = 0, | ||
42 | [NF_INET_FORWARD] = sizeof(struct ip6t_standard), | ||
43 | [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2, | ||
44 | }, | ||
45 | .underflow = { | ||
46 | [NF_INET_LOCAL_IN] = 0, | ||
47 | [NF_INET_FORWARD] = sizeof(struct ip6t_standard), | ||
48 | [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2, | ||
49 | }, | ||
50 | }, | ||
51 | .entries = { | ||
52 | IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */ | ||
53 | IP6T_STANDARD_INIT(NF_ACCEPT), /* FORWARD */ | ||
54 | IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ | ||
55 | }, | ||
56 | .term = IP6T_ERROR_INIT, /* ERROR */ | ||
57 | }; | ||
58 | |||
59 | static struct xt_table security_table = { | ||
60 | .name = "security", | ||
61 | .valid_hooks = SECURITY_VALID_HOOKS, | ||
62 | .lock = __RW_LOCK_UNLOCKED(security_table.lock), | ||
63 | .me = THIS_MODULE, | ||
64 | .af = AF_INET6, | ||
65 | }; | ||
66 | |||
67 | static unsigned int | ||
68 | ip6t_local_in_hook(unsigned int hook, | ||
69 | struct sk_buff *skb, | ||
70 | const struct net_device *in, | ||
71 | const struct net_device *out, | ||
72 | int (*okfn)(struct sk_buff *)) | ||
73 | { | ||
74 | return ip6t_do_table(skb, hook, in, out, | ||
75 | init_net.ipv6.ip6table_security); | ||
76 | } | ||
77 | |||
78 | static unsigned int | ||
79 | ip6t_forward_hook(unsigned int hook, | ||
80 | struct sk_buff *skb, | ||
81 | const struct net_device *in, | ||
82 | const struct net_device *out, | ||
83 | int (*okfn)(struct sk_buff *)) | ||
84 | { | ||
85 | return ip6t_do_table(skb, hook, in, out, | ||
86 | init_net.ipv6.ip6table_security); | ||
87 | } | ||
88 | |||
89 | static unsigned int | ||
90 | ip6t_local_out_hook(unsigned int hook, | ||
91 | struct sk_buff *skb, | ||
92 | const struct net_device *in, | ||
93 | const struct net_device *out, | ||
94 | int (*okfn)(struct sk_buff *)) | ||
95 | { | ||
96 | /* TBD: handle short packets via raw socket */ | ||
97 | return ip6t_do_table(skb, hook, in, out, | ||
98 | init_net.ipv6.ip6table_security); | ||
99 | } | ||
100 | |||
101 | static struct nf_hook_ops ip6t_ops[] __read_mostly = { | ||
102 | { | ||
103 | .hook = ip6t_local_in_hook, | ||
104 | .owner = THIS_MODULE, | ||
105 | .pf = PF_INET6, | ||
106 | .hooknum = NF_INET_LOCAL_IN, | ||
107 | .priority = NF_IP6_PRI_SECURITY, | ||
108 | }, | ||
109 | { | ||
110 | .hook = ip6t_forward_hook, | ||
111 | .owner = THIS_MODULE, | ||
112 | .pf = PF_INET6, | ||
113 | .hooknum = NF_INET_FORWARD, | ||
114 | .priority = NF_IP6_PRI_SECURITY, | ||
115 | }, | ||
116 | { | ||
117 | .hook = ip6t_local_out_hook, | ||
118 | .owner = THIS_MODULE, | ||
119 | .pf = PF_INET6, | ||
120 | .hooknum = NF_INET_LOCAL_OUT, | ||
121 | .priority = NF_IP6_PRI_SECURITY, | ||
122 | }, | ||
123 | }; | ||
124 | |||
125 | static int __net_init ip6table_security_net_init(struct net *net) | ||
126 | { | ||
127 | net->ipv6.ip6table_security = | ||
128 | ip6t_register_table(net, &security_table, &initial_table.repl); | ||
129 | |||
130 | if (IS_ERR(net->ipv6.ip6table_security)) | ||
131 | return PTR_ERR(net->ipv6.ip6table_security); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static void __net_exit ip6table_security_net_exit(struct net *net) | ||
137 | { | ||
138 | ip6t_unregister_table(net->ipv6.ip6table_security); | ||
139 | } | ||
140 | |||
141 | static struct pernet_operations ip6table_security_net_ops = { | ||
142 | .init = ip6table_security_net_init, | ||
143 | .exit = ip6table_security_net_exit, | ||
144 | }; | ||
145 | |||
146 | static int __init ip6table_security_init(void) | ||
147 | { | ||
148 | int ret; | ||
149 | |||
150 | ret = register_pernet_subsys(&ip6table_security_net_ops); | ||
151 | if (ret < 0) | ||
152 | return ret; | ||
153 | |||
154 | ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); | ||
155 | if (ret < 0) | ||
156 | goto cleanup_table; | ||
157 | |||
158 | return ret; | ||
159 | |||
160 | cleanup_table: | ||
161 | unregister_pernet_subsys(&ip6table_security_net_ops); | ||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | static void __exit ip6table_security_fini(void) | ||
166 | { | ||
167 | nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); | ||
168 | unregister_pernet_subsys(&ip6table_security_net_ops); | ||
169 | } | ||
170 | |||
171 | module_init(ip6table_security_init); | ||
172 | module_exit(ip6table_security_fini); | ||