kernel: bump 4.9 to 4.9.192
[oweals/openwrt.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)