kernel: bump 4.9 to 4.9.192
[openwrt/staging/chunkeey.git] / target / linux / generic / backport-4.14 / 390-v5.3-net-sched-fix-action-ipt-crash.patch
1 From: Cong Wang <xiyou.wangcong@gmail.com>
2 To: netdev@vger.kernel.org
3 Cc: Cong Wang <xiyou.wangcong@gmail.com>,
4 Tony Ambardar <itugrok@yahoo.com>,
5 Jamal Hadi Salim <jhs@mojatatu.com>,
6 Jiri Pirko <jiri@resnulli.us>
7 Subject: [Patch net] net_sched: fix a NULL pointer deref in ipt action
8 Date: Sun, 25 Aug 2019 10:01:32 -0700
9
10 The net pointer in struct xt_tgdtor_param is not explicitly
11 initialized therefore is still NULL when dereferencing it.
12 So we have to find a way to pass the correct net pointer to
13 ipt_destroy_target().
14
15 The best way I find is just saving the net pointer inside the per
16 netns struct tcf_idrinfo, which could make this patch smaller.
17
18 Fixes: 0c66dc1ea3f0 ("netfilter: conntrack: register hooks in netns when needed by ruleset")
19 Reported-and-tested-by: Tony Ambardar <itugrok@yahoo.com>
20 Cc: Jamal Hadi Salim <jhs@mojatatu.com>
21 Cc: Jiri Pirko <jiri@resnulli.us>
22 Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
23
24 [Backported for kernel v4.14]
25 Signed-off-by: Tony Ambardar <itugrok@yahoo.com>
26 ---
27 include/net/act_api.h | 4 +++-
28 net/sched/act_bpf.c | 2 +-
29 net/sched/act_connmark.c | 2 +-
30 net/sched/act_csum.c | 2 +-
31 net/sched/act_gact.c | 2 +-
32 net/sched/act_ife.c | 2 +-
33 net/sched/act_ipt.c | 11 ++++++-----
34 net/sched/act_mirred.c | 2 +-
35 net/sched/act_nat.c | 2 +-
36 net/sched/act_pedit.c | 2 +-
37 net/sched/act_police.c | 2 +-
38 net/sched/act_sample.c | 2 +-
39 net/sched/act_simple.c | 2 +-
40 net/sched/act_skbedit.c | 2 +-
41 net/sched/act_skbmod.c | 2 +-
42 net/sched/act_tunnel_key.c | 2 +-
43 net/sched/act_vlan.c | 2 +-
44 17 files changed, 24 insertions(+), 21 deletions(-)
45
46 --- a/include/net/act_api.h
47 +++ b/include/net/act_api.h
48 @@ -14,6 +14,7 @@
49 struct tcf_idrinfo {
50 spinlock_t lock;
51 struct idr action_idr;
52 + struct net *net;
53 };
54
55 struct tc_action_ops;
56 @@ -104,7 +105,7 @@ struct tc_action_net {
57 };
58
59 static inline
60 -int tc_action_net_init(struct tc_action_net *tn,
61 +int tc_action_net_init(struct net *net, struct tc_action_net *tn,
62 const struct tc_action_ops *ops)
63 {
64 int err = 0;
65 @@ -113,6 +114,7 @@ int tc_action_net_init(struct tc_action_
66 if (!tn->idrinfo)
67 return -ENOMEM;
68 tn->ops = ops;
69 + tn->idrinfo->net = net;
70 spin_lock_init(&tn->idrinfo->lock);
71 idr_init(&tn->idrinfo->action_idr);
72 return err;
73 --- a/net/sched/act_bpf.c
74 +++ b/net/sched/act_bpf.c
75 @@ -402,7 +402,7 @@ static __net_init int bpf_init_net(struc
76 {
77 struct tc_action_net *tn = net_generic(net, bpf_net_id);
78
79 - return tc_action_net_init(tn, &act_bpf_ops);
80 + return tc_action_net_init(net, tn, &act_bpf_ops);
81 }
82
83 static void __net_exit bpf_exit_net(struct net *net)
84 --- a/net/sched/act_connmark.c
85 +++ b/net/sched/act_connmark.c
86 @@ -206,7 +206,7 @@ static __net_init int connmark_init_net(
87 {
88 struct tc_action_net *tn = net_generic(net, connmark_net_id);
89
90 - return tc_action_net_init(tn, &act_connmark_ops);
91 + return tc_action_net_init(net, tn, &act_connmark_ops);
92 }
93
94 static void __net_exit connmark_exit_net(struct net *net)
95 --- a/net/sched/act_csum.c
96 +++ b/net/sched/act_csum.c
97 @@ -632,7 +632,7 @@ static __net_init int csum_init_net(stru
98 {
99 struct tc_action_net *tn = net_generic(net, csum_net_id);
100
101 - return tc_action_net_init(tn, &act_csum_ops);
102 + return tc_action_net_init(net, tn, &act_csum_ops);
103 }
104
105 static void __net_exit csum_exit_net(struct net *net)
106 --- a/net/sched/act_gact.c
107 +++ b/net/sched/act_gact.c
108 @@ -232,7 +232,7 @@ static __net_init int gact_init_net(stru
109 {
110 struct tc_action_net *tn = net_generic(net, gact_net_id);
111
112 - return tc_action_net_init(tn, &act_gact_ops);
113 + return tc_action_net_init(net, tn, &act_gact_ops);
114 }
115
116 static void __net_exit gact_exit_net(struct net *net)
117 --- a/net/sched/act_ife.c
118 +++ b/net/sched/act_ife.c
119 @@ -837,7 +837,7 @@ static __net_init int ife_init_net(struc
120 {
121 struct tc_action_net *tn = net_generic(net, ife_net_id);
122
123 - return tc_action_net_init(tn, &act_ife_ops);
124 + return tc_action_net_init(net, tn, &act_ife_ops);
125 }
126
127 static void __net_exit ife_exit_net(struct net *net)
128 --- a/net/sched/act_ipt.c
129 +++ b/net/sched/act_ipt.c
130 @@ -65,12 +65,13 @@ static int ipt_init_target(struct net *n
131 return 0;
132 }
133
134 -static void ipt_destroy_target(struct xt_entry_target *t)
135 +static void ipt_destroy_target(struct xt_entry_target *t, struct net *net)
136 {
137 struct xt_tgdtor_param par = {
138 .target = t->u.kernel.target,
139 .targinfo = t->data,
140 .family = NFPROTO_IPV4,
141 + .net = net,
142 };
143 if (par.target->destroy != NULL)
144 par.target->destroy(&par);
145 @@ -82,7 +83,7 @@ static void tcf_ipt_release(struct tc_ac
146 struct tcf_ipt *ipt = to_ipt(a);
147
148 if (ipt->tcfi_t) {
149 - ipt_destroy_target(ipt->tcfi_t);
150 + ipt_destroy_target(ipt->tcfi_t, a->idrinfo->net);
151 kfree(ipt->tcfi_t);
152 }
153 kfree(ipt->tcfi_tname);
154 @@ -172,7 +173,7 @@ static int __tcf_ipt_init(struct net *ne
155
156 spin_lock_bh(&ipt->tcf_lock);
157 if (ret != ACT_P_CREATED) {
158 - ipt_destroy_target(ipt->tcfi_t);
159 + ipt_destroy_target(ipt->tcfi_t, net);
160 kfree(ipt->tcfi_tname);
161 kfree(ipt->tcfi_t);
162 }
163 @@ -337,7 +338,7 @@ static __net_init int ipt_init_net(struc
164 {
165 struct tc_action_net *tn = net_generic(net, ipt_net_id);
166
167 - return tc_action_net_init(tn, &act_ipt_ops);
168 + return tc_action_net_init(net, tn, &act_ipt_ops);
169 }
170
171 static void __net_exit ipt_exit_net(struct net *net)
172 @@ -387,7 +388,7 @@ static __net_init int xt_init_net(struct
173 {
174 struct tc_action_net *tn = net_generic(net, xt_net_id);
175
176 - return tc_action_net_init(tn, &act_xt_ops);
177 + return tc_action_net_init(net, tn, &act_xt_ops);
178 }
179
180 static void __net_exit xt_exit_net(struct net *net)
181 --- a/net/sched/act_mirred.c
182 +++ b/net/sched/act_mirred.c
183 @@ -343,7 +343,7 @@ static __net_init int mirred_init_net(st
184 {
185 struct tc_action_net *tn = net_generic(net, mirred_net_id);
186
187 - return tc_action_net_init(tn, &act_mirred_ops);
188 + return tc_action_net_init(net, tn, &act_mirred_ops);
189 }
190
191 static void __net_exit mirred_exit_net(struct net *net)
192 --- a/net/sched/act_nat.c
193 +++ b/net/sched/act_nat.c
194 @@ -307,7 +307,7 @@ static __net_init int nat_init_net(struc
195 {
196 struct tc_action_net *tn = net_generic(net, nat_net_id);
197
198 - return tc_action_net_init(tn, &act_nat_ops);
199 + return tc_action_net_init(net, tn, &act_nat_ops);
200 }
201
202 static void __net_exit nat_exit_net(struct net *net)
203 --- a/net/sched/act_pedit.c
204 +++ b/net/sched/act_pedit.c
205 @@ -458,7 +458,7 @@ static __net_init int pedit_init_net(str
206 {
207 struct tc_action_net *tn = net_generic(net, pedit_net_id);
208
209 - return tc_action_net_init(tn, &act_pedit_ops);
210 + return tc_action_net_init(net, tn, &act_pedit_ops);
211 }
212
213 static void __net_exit pedit_exit_net(struct net *net)
214 --- a/net/sched/act_police.c
215 +++ b/net/sched/act_police.c
216 @@ -331,7 +331,7 @@ static __net_init int police_init_net(st
217 {
218 struct tc_action_net *tn = net_generic(net, police_net_id);
219
220 - return tc_action_net_init(tn, &act_police_ops);
221 + return tc_action_net_init(net, tn, &act_police_ops);
222 }
223
224 static void __net_exit police_exit_net(struct net *net)
225 --- a/net/sched/act_sample.c
226 +++ b/net/sched/act_sample.c
227 @@ -249,7 +249,7 @@ static __net_init int sample_init_net(st
228 {
229 struct tc_action_net *tn = net_generic(net, sample_net_id);
230
231 - return tc_action_net_init(tn, &act_sample_ops);
232 + return tc_action_net_init(net, tn, &act_sample_ops);
233 }
234
235 static void __net_exit sample_exit_net(struct net *net)
236 --- a/net/sched/act_simple.c
237 +++ b/net/sched/act_simple.c
238 @@ -198,7 +198,7 @@ static __net_init int simp_init_net(stru
239 {
240 struct tc_action_net *tn = net_generic(net, simp_net_id);
241
242 - return tc_action_net_init(tn, &act_simp_ops);
243 + return tc_action_net_init(net, tn, &act_simp_ops);
244 }
245
246 static void __net_exit simp_exit_net(struct net *net)
247 --- a/net/sched/act_skbedit.c
248 +++ b/net/sched/act_skbedit.c
249 @@ -239,7 +239,7 @@ static __net_init int skbedit_init_net(s
250 {
251 struct tc_action_net *tn = net_generic(net, skbedit_net_id);
252
253 - return tc_action_net_init(tn, &act_skbedit_ops);
254 + return tc_action_net_init(net, tn, &act_skbedit_ops);
255 }
256
257 static void __net_exit skbedit_exit_net(struct net *net)
258 --- a/net/sched/act_skbmod.c
259 +++ b/net/sched/act_skbmod.c
260 @@ -267,7 +267,7 @@ static __net_init int skbmod_init_net(st
261 {
262 struct tc_action_net *tn = net_generic(net, skbmod_net_id);
263
264 - return tc_action_net_init(tn, &act_skbmod_ops);
265 + return tc_action_net_init(net, tn, &act_skbmod_ops);
266 }
267
268 static void __net_exit skbmod_exit_net(struct net *net)
269 --- a/net/sched/act_tunnel_key.c
270 +++ b/net/sched/act_tunnel_key.c
271 @@ -324,7 +324,7 @@ static __net_init int tunnel_key_init_ne
272 {
273 struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
274
275 - return tc_action_net_init(tn, &act_tunnel_key_ops);
276 + return tc_action_net_init(net, tn, &act_tunnel_key_ops);
277 }
278
279 static void __net_exit tunnel_key_exit_net(struct net *net)
280 --- a/net/sched/act_vlan.c
281 +++ b/net/sched/act_vlan.c
282 @@ -271,7 +271,7 @@ static __net_init int vlan_init_net(stru
283 {
284 struct tc_action_net *tn = net_generic(net, vlan_net_id);
285
286 - return tc_action_net_init(tn, &act_vlan_ops);
287 + return tc_action_net_init(net, tn, &act_vlan_ops);
288 }
289
290 static void __net_exit vlan_exit_net(struct net *net)