]>
Commit | Line | Data |
---|---|---|
8ed9d391 GKH |
1 | From 8dddd32756f6fe8e4e82a63361119b7e2384e02f Mon Sep 17 00:00:00 2001 |
2 | From: Florian Westphal <fw@strlen.de> | |
3 | Date: Fri, 1 Apr 2016 14:17:32 +0200 | |
4 | Subject: netfilter: arp_tables: simplify translate_compat_table args | |
5 | ||
6 | From: Florian Westphal <fw@strlen.de> | |
7 | ||
8 | commit 8dddd32756f6fe8e4e82a63361119b7e2384e02f upstream. | |
9 | ||
10 | Signed-off-by: Florian Westphal <fw@strlen.de> | |
11 | Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |
12 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
13 | ||
14 | --- | |
15 | net/ipv4/netfilter/arp_tables.c | 82 +++++++++++++++++----------------------- | |
16 | 1 file changed, 36 insertions(+), 46 deletions(-) | |
17 | ||
18 | --- a/net/ipv4/netfilter/arp_tables.c | |
19 | +++ b/net/ipv4/netfilter/arp_tables.c | |
20 | @@ -1213,6 +1213,18 @@ static int do_add_counters(struct net *n | |
21 | } | |
22 | ||
23 | #ifdef CONFIG_COMPAT | |
24 | +struct compat_arpt_replace { | |
25 | + char name[XT_TABLE_MAXNAMELEN]; | |
26 | + u32 valid_hooks; | |
27 | + u32 num_entries; | |
28 | + u32 size; | |
29 | + u32 hook_entry[NF_ARP_NUMHOOKS]; | |
30 | + u32 underflow[NF_ARP_NUMHOOKS]; | |
31 | + u32 num_counters; | |
32 | + compat_uptr_t counters; | |
33 | + struct compat_arpt_entry entries[0]; | |
34 | +}; | |
35 | + | |
36 | static inline void compat_release_entry(struct compat_arpt_entry *e) | |
37 | { | |
38 | struct xt_entry_target *t; | |
39 | @@ -1228,8 +1240,7 @@ check_compat_entry_size_and_hooks(struct | |
40 | const unsigned char *base, | |
41 | const unsigned char *limit, | |
42 | const unsigned int *hook_entries, | |
43 | - const unsigned int *underflows, | |
44 | - const char *name) | |
45 | + const unsigned int *underflows) | |
46 | { | |
47 | struct xt_entry_target *t; | |
48 | struct xt_target *target; | |
49 | @@ -1300,7 +1311,7 @@ out: | |
50 | ||
51 | static int | |
52 | compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr, | |
53 | - unsigned int *size, const char *name, | |
54 | + unsigned int *size, | |
55 | struct xt_table_info *newinfo, unsigned char *base) | |
56 | { | |
57 | struct xt_entry_target *t; | |
58 | @@ -1333,14 +1344,9 @@ compat_copy_entry_from_user(struct compa | |
59 | return ret; | |
60 | } | |
61 | ||
62 | -static int translate_compat_table(const char *name, | |
63 | - unsigned int valid_hooks, | |
64 | - struct xt_table_info **pinfo, | |
65 | +static int translate_compat_table(struct xt_table_info **pinfo, | |
66 | void **pentry0, | |
67 | - unsigned int total_size, | |
68 | - unsigned int number, | |
69 | - unsigned int *hook_entries, | |
70 | - unsigned int *underflows) | |
71 | + const struct compat_arpt_replace *compatr) | |
72 | { | |
73 | unsigned int i, j; | |
74 | struct xt_table_info *newinfo, *info; | |
75 | @@ -1352,8 +1358,8 @@ static int translate_compat_table(const | |
76 | ||
77 | info = *pinfo; | |
78 | entry0 = *pentry0; | |
79 | - size = total_size; | |
80 | - info->number = number; | |
81 | + size = compatr->size; | |
82 | + info->number = compatr->num_entries; | |
83 | ||
84 | /* Init all hooks to impossible value. */ | |
85 | for (i = 0; i < NF_ARP_NUMHOOKS; i++) { | |
86 | @@ -1364,40 +1370,39 @@ static int translate_compat_table(const | |
87 | duprintf("translate_compat_table: size %u\n", info->size); | |
88 | j = 0; | |
89 | xt_compat_lock(NFPROTO_ARP); | |
90 | - xt_compat_init_offsets(NFPROTO_ARP, number); | |
91 | + xt_compat_init_offsets(NFPROTO_ARP, compatr->num_entries); | |
92 | /* Walk through entries, checking offsets. */ | |
93 | - xt_entry_foreach(iter0, entry0, total_size) { | |
94 | + xt_entry_foreach(iter0, entry0, compatr->size) { | |
95 | ret = check_compat_entry_size_and_hooks(iter0, info, &size, | |
96 | entry0, | |
97 | - entry0 + total_size, | |
98 | - hook_entries, | |
99 | - underflows, | |
100 | - name); | |
101 | + entry0 + compatr->size, | |
102 | + compatr->hook_entry, | |
103 | + compatr->underflow); | |
104 | if (ret != 0) | |
105 | goto out_unlock; | |
106 | ++j; | |
107 | } | |
108 | ||
109 | ret = -EINVAL; | |
110 | - if (j != number) { | |
111 | + if (j != compatr->num_entries) { | |
112 | duprintf("translate_compat_table: %u not %u entries\n", | |
113 | - j, number); | |
114 | + j, compatr->num_entries); | |
115 | goto out_unlock; | |
116 | } | |
117 | ||
118 | /* Check hooks all assigned */ | |
119 | for (i = 0; i < NF_ARP_NUMHOOKS; i++) { | |
120 | /* Only hooks which are valid */ | |
121 | - if (!(valid_hooks & (1 << i))) | |
122 | + if (!(compatr->valid_hooks & (1 << i))) | |
123 | continue; | |
124 | if (info->hook_entry[i] == 0xFFFFFFFF) { | |
125 | duprintf("Invalid hook entry %u %u\n", | |
126 | - i, hook_entries[i]); | |
127 | + i, info->hook_entry[i]); | |
128 | goto out_unlock; | |
129 | } | |
130 | if (info->underflow[i] == 0xFFFFFFFF) { | |
131 | duprintf("Invalid underflow %u %u\n", | |
132 | - i, underflows[i]); | |
133 | + i, info->underflow[i]); | |
134 | goto out_unlock; | |
135 | } | |
136 | } | |
137 | @@ -1407,17 +1412,17 @@ static int translate_compat_table(const | |
138 | if (!newinfo) | |
139 | goto out_unlock; | |
140 | ||
141 | - newinfo->number = number; | |
142 | + newinfo->number = compatr->num_entries; | |
143 | for (i = 0; i < NF_ARP_NUMHOOKS; i++) { | |
144 | newinfo->hook_entry[i] = info->hook_entry[i]; | |
145 | newinfo->underflow[i] = info->underflow[i]; | |
146 | } | |
147 | entry1 = newinfo->entries; | |
148 | pos = entry1; | |
149 | - size = total_size; | |
150 | - xt_entry_foreach(iter0, entry0, total_size) { | |
151 | + size = compatr->size; | |
152 | + xt_entry_foreach(iter0, entry0, compatr->size) { | |
153 | ret = compat_copy_entry_from_user(iter0, &pos, &size, | |
154 | - name, newinfo, entry1); | |
155 | + newinfo, entry1); | |
156 | if (ret != 0) | |
157 | break; | |
158 | } | |
159 | @@ -1427,7 +1432,7 @@ static int translate_compat_table(const | |
160 | goto free_newinfo; | |
161 | ||
162 | ret = -ELOOP; | |
163 | - if (!mark_source_chains(newinfo, valid_hooks, entry1)) | |
164 | + if (!mark_source_chains(newinfo, compatr->valid_hooks, entry1)) | |
165 | goto free_newinfo; | |
166 | ||
167 | i = 0; | |
168 | @@ -1438,7 +1443,7 @@ static int translate_compat_table(const | |
169 | break; | |
170 | } | |
171 | ||
172 | - ret = check_target(iter1, name); | |
173 | + ret = check_target(iter1, compatr->name); | |
174 | if (ret != 0) { | |
175 | xt_percpu_counter_free(iter1->counters.pcnt); | |
176 | break; | |
177 | @@ -1480,7 +1485,7 @@ static int translate_compat_table(const | |
178 | free_newinfo: | |
179 | xt_free_table_info(newinfo); | |
180 | out: | |
181 | - xt_entry_foreach(iter0, entry0, total_size) { | |
182 | + xt_entry_foreach(iter0, entry0, compatr->size) { | |
183 | if (j-- == 0) | |
184 | break; | |
185 | compat_release_entry(iter0); | |
186 | @@ -1492,18 +1497,6 @@ out_unlock: | |
187 | goto out; | |
188 | } | |
189 | ||
190 | -struct compat_arpt_replace { | |
191 | - char name[XT_TABLE_MAXNAMELEN]; | |
192 | - u32 valid_hooks; | |
193 | - u32 num_entries; | |
194 | - u32 size; | |
195 | - u32 hook_entry[NF_ARP_NUMHOOKS]; | |
196 | - u32 underflow[NF_ARP_NUMHOOKS]; | |
197 | - u32 num_counters; | |
198 | - compat_uptr_t counters; | |
199 | - struct compat_arpt_entry entries[0]; | |
200 | -}; | |
201 | - | |
202 | static int compat_do_replace(struct net *net, void __user *user, | |
203 | unsigned int len) | |
204 | { | |
205 | @@ -1536,10 +1529,7 @@ static int compat_do_replace(struct net | |
206 | goto free_newinfo; | |
207 | } | |
208 | ||
209 | - ret = translate_compat_table(tmp.name, tmp.valid_hooks, | |
210 | - &newinfo, &loc_cpu_entry, tmp.size, | |
211 | - tmp.num_entries, tmp.hook_entry, | |
212 | - tmp.underflow); | |
213 | + ret = translate_compat_table(&newinfo, &loc_cpu_entry, &tmp); | |
214 | if (ret != 0) | |
215 | goto free_newinfo; | |
216 |