1 |
commit: 20bfdd395abdeb66604fa2dfa14eaf8a0e3d508c |
2 |
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
3 |
AuthorDate: Thu Aug 27 13:19:09 2020 +0000 |
4 |
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
5 |
CommitDate: Thu Aug 27 13:19:09 2020 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=20bfdd39 |
7 |
|
8 |
Linux patch 5.7.19 |
9 |
|
10 |
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> |
11 |
|
12 |
0000_README | 4 + |
13 |
1018_linux-5.7.19.patch | 382 ++++++++++++++++++++++++++++++++++++++++++++++++ |
14 |
2 files changed, 386 insertions(+) |
15 |
|
16 |
diff --git a/0000_README b/0000_README |
17 |
index 1ab468f..11a3e8d 100644 |
18 |
--- a/0000_README |
19 |
+++ b/0000_README |
20 |
@@ -115,6 +115,10 @@ Patch: 1017_linux-5.7.18.patch |
21 |
From: http://www.kernel.org |
22 |
Desc: Linux 5.7.18 |
23 |
|
24 |
+Patch: 1018_linux-5.7.19.patch |
25 |
+From: http://www.kernel.org |
26 |
+Desc: Linux 5.7.19 |
27 |
+ |
28 |
Patch: 1500_XATTR_USER_PREFIX.patch |
29 |
From: https://bugs.gentoo.org/show_bug.cgi?id=470644 |
30 |
Desc: Support for namespace user.pax.* on tmpfs. |
31 |
|
32 |
diff --git a/1018_linux-5.7.19.patch b/1018_linux-5.7.19.patch |
33 |
new file mode 100644 |
34 |
index 0000000..005c31b |
35 |
--- /dev/null |
36 |
+++ b/1018_linux-5.7.19.patch |
37 |
@@ -0,0 +1,382 @@ |
38 |
+diff --git a/Makefile b/Makefile |
39 |
+index b56456c45c97f..b60ba59cfb196 100644 |
40 |
+--- a/Makefile |
41 |
++++ b/Makefile |
42 |
+@@ -1,7 +1,7 @@ |
43 |
+ # SPDX-License-Identifier: GPL-2.0 |
44 |
+ VERSION = 5 |
45 |
+ PATCHLEVEL = 7 |
46 |
+-SUBLEVEL = 18 |
47 |
++SUBLEVEL = 19 |
48 |
+ EXTRAVERSION = |
49 |
+ NAME = Kleptomaniac Octopus |
50 |
+ |
51 |
+diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S |
52 |
+index a460298c7ddb4..f91ecb10d0ae7 100644 |
53 |
+--- a/arch/powerpc/kernel/cpu_setup_power.S |
54 |
++++ b/arch/powerpc/kernel/cpu_setup_power.S |
55 |
+@@ -184,7 +184,7 @@ __init_LPCR_ISA300: |
56 |
+ |
57 |
+ __init_FSCR: |
58 |
+ mfspr r3,SPRN_FSCR |
59 |
+- ori r3,r3,FSCR_TAR|FSCR_DSCR|FSCR_EBB |
60 |
++ ori r3,r3,FSCR_TAR|FSCR_EBB |
61 |
+ mtspr SPRN_FSCR,r3 |
62 |
+ blr |
63 |
+ |
64 |
+diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c |
65 |
+index c501a4edc34d6..51b9b49a295e9 100644 |
66 |
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c |
67 |
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c |
68 |
+@@ -3594,7 +3594,7 @@ static int check_missing_comp_in_tx_queue(struct ena_adapter *adapter, |
69 |
+ } |
70 |
+ |
71 |
+ u64_stats_update_begin(&tx_ring->syncp); |
72 |
+- tx_ring->tx_stats.missed_tx = missed_tx; |
73 |
++ tx_ring->tx_stats.missed_tx += missed_tx; |
74 |
+ u64_stats_update_end(&tx_ring->syncp); |
75 |
+ |
76 |
+ return rc; |
77 |
+@@ -4519,6 +4519,9 @@ static void ena_keep_alive_wd(void *adapter_data, |
78 |
+ rx_drops = ((u64)desc->rx_drops_high << 32) | desc->rx_drops_low; |
79 |
+ |
80 |
+ u64_stats_update_begin(&adapter->syncp); |
81 |
++ /* These stats are accumulated by the device, so the counters indicate |
82 |
++ * all drops since last reset. |
83 |
++ */ |
84 |
+ adapter->dev_stats.rx_drops = rx_drops; |
85 |
+ u64_stats_update_end(&adapter->syncp); |
86 |
+ } |
87 |
+diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c |
88 |
+index 831a2b25ba79f..196f9f64d075c 100644 |
89 |
+--- a/fs/binfmt_flat.c |
90 |
++++ b/fs/binfmt_flat.c |
91 |
+@@ -571,7 +571,7 @@ static int load_flat_file(struct linux_binprm *bprm, |
92 |
+ goto err; |
93 |
+ } |
94 |
+ |
95 |
+- len = data_len + extra; |
96 |
++ len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); |
97 |
+ len = PAGE_ALIGN(len); |
98 |
+ realdatastart = vm_mmap(NULL, 0, len, |
99 |
+ PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); |
100 |
+@@ -585,7 +585,9 @@ static int load_flat_file(struct linux_binprm *bprm, |
101 |
+ vm_munmap(textpos, text_len); |
102 |
+ goto err; |
103 |
+ } |
104 |
+- datapos = ALIGN(realdatastart, FLAT_DATA_ALIGN); |
105 |
++ datapos = ALIGN(realdatastart + |
106 |
++ MAX_SHARED_LIBS * sizeof(unsigned long), |
107 |
++ FLAT_DATA_ALIGN); |
108 |
+ |
109 |
+ pr_debug("Allocated data+bss+stack (%u bytes): %lx\n", |
110 |
+ data_len + bss_len + stack_len, datapos); |
111 |
+@@ -615,7 +617,7 @@ static int load_flat_file(struct linux_binprm *bprm, |
112 |
+ memp_size = len; |
113 |
+ } else { |
114 |
+ |
115 |
+- len = text_len + data_len + extra; |
116 |
++ len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(u32); |
117 |
+ len = PAGE_ALIGN(len); |
118 |
+ textpos = vm_mmap(NULL, 0, len, |
119 |
+ PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); |
120 |
+@@ -630,7 +632,9 @@ static int load_flat_file(struct linux_binprm *bprm, |
121 |
+ } |
122 |
+ |
123 |
+ realdatastart = textpos + ntohl(hdr->data_start); |
124 |
+- datapos = ALIGN(realdatastart, FLAT_DATA_ALIGN); |
125 |
++ datapos = ALIGN(realdatastart + |
126 |
++ MAX_SHARED_LIBS * sizeof(u32), |
127 |
++ FLAT_DATA_ALIGN); |
128 |
+ |
129 |
+ reloc = (__be32 __user *) |
130 |
+ (datapos + (ntohl(hdr->reloc_start) - text_len)); |
131 |
+@@ -647,9 +651,8 @@ static int load_flat_file(struct linux_binprm *bprm, |
132 |
+ (text_len + full_data |
133 |
+ - sizeof(struct flat_hdr)), |
134 |
+ 0); |
135 |
+- if (datapos != realdatastart) |
136 |
+- memmove((void *)datapos, (void *)realdatastart, |
137 |
+- full_data); |
138 |
++ memmove((void *) datapos, (void *) realdatastart, |
139 |
++ full_data); |
140 |
+ #else |
141 |
+ /* |
142 |
+ * This is used on MMU systems mainly for testing. |
143 |
+@@ -705,7 +708,8 @@ static int load_flat_file(struct linux_binprm *bprm, |
144 |
+ if (IS_ERR_VALUE(result)) { |
145 |
+ ret = result; |
146 |
+ pr_err("Unable to read code+data+bss, errno %d\n", ret); |
147 |
+- vm_munmap(textpos, text_len + data_len + extra); |
148 |
++ vm_munmap(textpos, text_len + data_len + extra + |
149 |
++ MAX_SHARED_LIBS * sizeof(u32)); |
150 |
+ goto err; |
151 |
+ } |
152 |
+ } |
153 |
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c |
154 |
+index 7e29590482ce5..115f3fde314f3 100644 |
155 |
+--- a/net/core/skbuff.c |
156 |
++++ b/net/core/skbuff.c |
157 |
+@@ -5421,8 +5421,8 @@ struct sk_buff *skb_vlan_untag(struct sk_buff *skb) |
158 |
+ skb = skb_share_check(skb, GFP_ATOMIC); |
159 |
+ if (unlikely(!skb)) |
160 |
+ goto err_free; |
161 |
+- |
162 |
+- if (unlikely(!pskb_may_pull(skb, VLAN_HLEN))) |
163 |
++ /* We may access the two bytes after vlan_hdr in vlan_set_encap_proto(). */ |
164 |
++ if (unlikely(!pskb_may_pull(skb, VLAN_HLEN + sizeof(unsigned short)))) |
165 |
+ goto err_free; |
166 |
+ |
167 |
+ vhdr = (struct vlan_hdr *)skb->data; |
168 |
+diff --git a/net/ethtool/features.c b/net/ethtool/features.c |
169 |
+index 4e632dc987d85..495635f152ba6 100644 |
170 |
+--- a/net/ethtool/features.c |
171 |
++++ b/net/ethtool/features.c |
172 |
+@@ -224,7 +224,9 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info) |
173 |
+ DECLARE_BITMAP(wanted_diff_mask, NETDEV_FEATURE_COUNT); |
174 |
+ DECLARE_BITMAP(active_diff_mask, NETDEV_FEATURE_COUNT); |
175 |
+ DECLARE_BITMAP(old_active, NETDEV_FEATURE_COUNT); |
176 |
++ DECLARE_BITMAP(old_wanted, NETDEV_FEATURE_COUNT); |
177 |
+ DECLARE_BITMAP(new_active, NETDEV_FEATURE_COUNT); |
178 |
++ DECLARE_BITMAP(new_wanted, NETDEV_FEATURE_COUNT); |
179 |
+ DECLARE_BITMAP(req_wanted, NETDEV_FEATURE_COUNT); |
180 |
+ DECLARE_BITMAP(req_mask, NETDEV_FEATURE_COUNT); |
181 |
+ struct nlattr *tb[ETHTOOL_A_FEATURES_MAX + 1]; |
182 |
+@@ -250,6 +252,7 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info) |
183 |
+ |
184 |
+ rtnl_lock(); |
185 |
+ ethnl_features_to_bitmap(old_active, dev->features); |
186 |
++ ethnl_features_to_bitmap(old_wanted, dev->wanted_features); |
187 |
+ ret = ethnl_parse_bitset(req_wanted, req_mask, NETDEV_FEATURE_COUNT, |
188 |
+ tb[ETHTOOL_A_FEATURES_WANTED], |
189 |
+ netdev_features_strings, info->extack); |
190 |
+@@ -261,17 +264,15 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info) |
191 |
+ goto out_rtnl; |
192 |
+ } |
193 |
+ |
194 |
+- /* set req_wanted bits not in req_mask from old_active */ |
195 |
++ /* set req_wanted bits not in req_mask from old_wanted */ |
196 |
+ bitmap_and(req_wanted, req_wanted, req_mask, NETDEV_FEATURE_COUNT); |
197 |
+- bitmap_andnot(new_active, old_active, req_mask, NETDEV_FEATURE_COUNT); |
198 |
+- bitmap_or(req_wanted, new_active, req_wanted, NETDEV_FEATURE_COUNT); |
199 |
+- if (bitmap_equal(req_wanted, old_active, NETDEV_FEATURE_COUNT)) { |
200 |
+- ret = 0; |
201 |
+- goto out_rtnl; |
202 |
++ bitmap_andnot(new_wanted, old_wanted, req_mask, NETDEV_FEATURE_COUNT); |
203 |
++ bitmap_or(req_wanted, new_wanted, req_wanted, NETDEV_FEATURE_COUNT); |
204 |
++ if (!bitmap_equal(req_wanted, old_wanted, NETDEV_FEATURE_COUNT)) { |
205 |
++ dev->wanted_features &= ~dev->hw_features; |
206 |
++ dev->wanted_features |= ethnl_bitmap_to_features(req_wanted) & dev->hw_features; |
207 |
++ __netdev_update_features(dev); |
208 |
+ } |
209 |
+- |
210 |
+- dev->wanted_features = ethnl_bitmap_to_features(req_wanted); |
211 |
+- __netdev_update_features(dev); |
212 |
+ ethnl_features_to_bitmap(new_active, dev->features); |
213 |
+ mod = !bitmap_equal(old_active, new_active, NETDEV_FEATURE_COUNT); |
214 |
+ |
215 |
+diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c |
216 |
+index 563f71bcb2d74..c97069e799811 100644 |
217 |
+--- a/net/ipv4/nexthop.c |
218 |
++++ b/net/ipv4/nexthop.c |
219 |
+@@ -402,7 +402,7 @@ static int nh_check_attr_group(struct net *net, struct nlattr *tb[], |
220 |
+ struct nexthop_grp *nhg; |
221 |
+ unsigned int i, j; |
222 |
+ |
223 |
+- if (len & (sizeof(struct nexthop_grp) - 1)) { |
224 |
++ if (!len || len & (sizeof(struct nexthop_grp) - 1)) { |
225 |
+ NL_SET_ERR_MSG(extack, |
226 |
+ "Invalid length for nexthop group attribute"); |
227 |
+ return -EINVAL; |
228 |
+@@ -1104,6 +1104,9 @@ static struct nexthop *nexthop_create_group(struct net *net, |
229 |
+ struct nexthop *nh; |
230 |
+ int i; |
231 |
+ |
232 |
++ if (WARN_ON(!num_nh)) |
233 |
++ return ERR_PTR(-EINVAL); |
234 |
++ |
235 |
+ nh = nexthop_alloc(); |
236 |
+ if (!nh) |
237 |
+ return ERR_PTR(-ENOMEM); |
238 |
+diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c |
239 |
+index 4703b09808d0a..84f90b8b88903 100644 |
240 |
+--- a/net/ipv6/ip6_tunnel.c |
241 |
++++ b/net/ipv6/ip6_tunnel.c |
242 |
+@@ -886,7 +886,15 @@ int ip6_tnl_rcv(struct ip6_tnl *t, struct sk_buff *skb, |
243 |
+ struct metadata_dst *tun_dst, |
244 |
+ bool log_ecn_err) |
245 |
+ { |
246 |
+- return __ip6_tnl_rcv(t, skb, tpi, tun_dst, ip6ip6_dscp_ecn_decapsulate, |
247 |
++ int (*dscp_ecn_decapsulate)(const struct ip6_tnl *t, |
248 |
++ const struct ipv6hdr *ipv6h, |
249 |
++ struct sk_buff *skb); |
250 |
++ |
251 |
++ dscp_ecn_decapsulate = ip6ip6_dscp_ecn_decapsulate; |
252 |
++ if (tpi->proto == htons(ETH_P_IP)) |
253 |
++ dscp_ecn_decapsulate = ip4ip6_dscp_ecn_decapsulate; |
254 |
++ |
255 |
++ return __ip6_tnl_rcv(t, skb, tpi, tun_dst, dscp_ecn_decapsulate, |
256 |
+ log_ecn_err); |
257 |
+ } |
258 |
+ EXPORT_SYMBOL(ip6_tnl_rcv); |
259 |
+diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c |
260 |
+index 300a104b9a0fb..85ab4559f0577 100644 |
261 |
+--- a/net/qrtr/qrtr.c |
262 |
++++ b/net/qrtr/qrtr.c |
263 |
+@@ -692,23 +692,25 @@ static void qrtr_port_remove(struct qrtr_sock *ipc) |
264 |
+ */ |
265 |
+ static int qrtr_port_assign(struct qrtr_sock *ipc, int *port) |
266 |
+ { |
267 |
++ u32 min_port; |
268 |
+ int rc; |
269 |
+ |
270 |
+ mutex_lock(&qrtr_port_lock); |
271 |
+ if (!*port) { |
272 |
+- rc = idr_alloc(&qrtr_ports, ipc, |
273 |
+- QRTR_MIN_EPH_SOCKET, QRTR_MAX_EPH_SOCKET + 1, |
274 |
+- GFP_ATOMIC); |
275 |
+- if (rc >= 0) |
276 |
+- *port = rc; |
277 |
++ min_port = QRTR_MIN_EPH_SOCKET; |
278 |
++ rc = idr_alloc_u32(&qrtr_ports, ipc, &min_port, QRTR_MAX_EPH_SOCKET, GFP_ATOMIC); |
279 |
++ if (!rc) |
280 |
++ *port = min_port; |
281 |
+ } else if (*port < QRTR_MIN_EPH_SOCKET && !capable(CAP_NET_ADMIN)) { |
282 |
+ rc = -EACCES; |
283 |
+ } else if (*port == QRTR_PORT_CTRL) { |
284 |
+- rc = idr_alloc(&qrtr_ports, ipc, 0, 1, GFP_ATOMIC); |
285 |
++ min_port = 0; |
286 |
++ rc = idr_alloc_u32(&qrtr_ports, ipc, &min_port, 0, GFP_ATOMIC); |
287 |
+ } else { |
288 |
+- rc = idr_alloc(&qrtr_ports, ipc, *port, *port + 1, GFP_ATOMIC); |
289 |
+- if (rc >= 0) |
290 |
+- *port = rc; |
291 |
++ min_port = *port; |
292 |
++ rc = idr_alloc_u32(&qrtr_ports, ipc, &min_port, *port, GFP_ATOMIC); |
293 |
++ if (!rc) |
294 |
++ *port = min_port; |
295 |
+ } |
296 |
+ mutex_unlock(&qrtr_port_lock); |
297 |
+ |
298 |
+diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c |
299 |
+index 417526d7741bf..16bc5b0d1eaaa 100644 |
300 |
+--- a/net/sched/act_ct.c |
301 |
++++ b/net/sched/act_ct.c |
302 |
+@@ -702,7 +702,7 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb, |
303 |
+ err = ip_defrag(net, skb, user); |
304 |
+ local_bh_enable(); |
305 |
+ if (err && err != -EINPROGRESS) |
306 |
+- goto out_free; |
307 |
++ return err; |
308 |
+ |
309 |
+ if (!err) { |
310 |
+ *defrag = true; |
311 |
+diff --git a/net/sctp/stream.c b/net/sctp/stream.c |
312 |
+index bda2536dd740f..6dc95dcc0ff4f 100644 |
313 |
+--- a/net/sctp/stream.c |
314 |
++++ b/net/sctp/stream.c |
315 |
+@@ -88,12 +88,13 @@ static int sctp_stream_alloc_out(struct sctp_stream *stream, __u16 outcnt, |
316 |
+ int ret; |
317 |
+ |
318 |
+ if (outcnt <= stream->outcnt) |
319 |
+- return 0; |
320 |
++ goto out; |
321 |
+ |
322 |
+ ret = genradix_prealloc(&stream->out, outcnt, gfp); |
323 |
+ if (ret) |
324 |
+ return ret; |
325 |
+ |
326 |
++out: |
327 |
+ stream->outcnt = outcnt; |
328 |
+ return 0; |
329 |
+ } |
330 |
+@@ -104,12 +105,13 @@ static int sctp_stream_alloc_in(struct sctp_stream *stream, __u16 incnt, |
331 |
+ int ret; |
332 |
+ |
333 |
+ if (incnt <= stream->incnt) |
334 |
+- return 0; |
335 |
++ goto out; |
336 |
+ |
337 |
+ ret = genradix_prealloc(&stream->in, incnt, gfp); |
338 |
+ if (ret) |
339 |
+ return ret; |
340 |
+ |
341 |
++out: |
342 |
+ stream->incnt = incnt; |
343 |
+ return 0; |
344 |
+ } |
345 |
+diff --git a/net/smc/smc_diag.c b/net/smc/smc_diag.c |
346 |
+index e1f64f4ba2361..da9ba6d1679b7 100644 |
347 |
+--- a/net/smc/smc_diag.c |
348 |
++++ b/net/smc/smc_diag.c |
349 |
+@@ -170,13 +170,15 @@ static int __smc_diag_dump(struct sock *sk, struct sk_buff *skb, |
350 |
+ (req->diag_ext & (1 << (SMC_DIAG_DMBINFO - 1))) && |
351 |
+ !list_empty(&smc->conn.lgr->list)) { |
352 |
+ struct smc_connection *conn = &smc->conn; |
353 |
+- struct smcd_diag_dmbinfo dinfo = { |
354 |
+- .linkid = *((u32 *)conn->lgr->id), |
355 |
+- .peer_gid = conn->lgr->peer_gid, |
356 |
+- .my_gid = conn->lgr->smcd->local_gid, |
357 |
+- .token = conn->rmb_desc->token, |
358 |
+- .peer_token = conn->peer_token |
359 |
+- }; |
360 |
++ struct smcd_diag_dmbinfo dinfo; |
361 |
++ |
362 |
++ memset(&dinfo, 0, sizeof(dinfo)); |
363 |
++ |
364 |
++ dinfo.linkid = *((u32 *)conn->lgr->id); |
365 |
++ dinfo.peer_gid = conn->lgr->peer_gid; |
366 |
++ dinfo.my_gid = conn->lgr->smcd->local_gid; |
367 |
++ dinfo.token = conn->rmb_desc->token; |
368 |
++ dinfo.peer_token = conn->peer_token; |
369 |
+ |
370 |
+ if (nla_put(skb, SMC_DIAG_DMBINFO, sizeof(dinfo), &dinfo) < 0) |
371 |
+ goto errout; |
372 |
+diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c |
373 |
+index 8c47ded2edb61..b214b898d11ad 100644 |
374 |
+--- a/net/tipc/crypto.c |
375 |
++++ b/net/tipc/crypto.c |
376 |
+@@ -757,10 +757,12 @@ static void tipc_aead_encrypt_done(struct crypto_async_request *base, int err) |
377 |
+ switch (err) { |
378 |
+ case 0: |
379 |
+ this_cpu_inc(tx->stats->stat[STAT_ASYNC_OK]); |
380 |
++ rcu_read_lock(); |
381 |
+ if (likely(test_bit(0, &b->up))) |
382 |
+ b->media->send_msg(net, skb, b, &tx_ctx->dst); |
383 |
+ else |
384 |
+ kfree_skb(skb); |
385 |
++ rcu_read_unlock(); |
386 |
+ break; |
387 |
+ case -EINPROGRESS: |
388 |
+ return; |
389 |
+diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c |
390 |
+index 217516357ef26..90e3c70a91ad0 100644 |
391 |
+--- a/net/tipc/netlink_compat.c |
392 |
++++ b/net/tipc/netlink_compat.c |
393 |
+@@ -275,8 +275,9 @@ err_out: |
394 |
+ static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, |
395 |
+ struct tipc_nl_compat_msg *msg) |
396 |
+ { |
397 |
+- int err; |
398 |
++ struct nlmsghdr *nlh; |
399 |
+ struct sk_buff *arg; |
400 |
++ int err; |
401 |
+ |
402 |
+ if (msg->req_type && (!msg->req_size || |
403 |
+ !TLV_CHECK_TYPE(msg->req, msg->req_type))) |
404 |
+@@ -305,6 +306,15 @@ static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, |
405 |
+ return -ENOMEM; |
406 |
+ } |
407 |
+ |
408 |
++ nlh = nlmsg_put(arg, 0, 0, tipc_genl_family.id, 0, NLM_F_MULTI); |
409 |
++ if (!nlh) { |
410 |
++ kfree_skb(arg); |
411 |
++ kfree_skb(msg->rep); |
412 |
++ msg->rep = NULL; |
413 |
++ return -EMSGSIZE; |
414 |
++ } |
415 |
++ nlmsg_end(arg, nlh); |
416 |
++ |
417 |
+ err = __tipc_nl_compat_dumpit(cmd, msg, arg); |
418 |
+ if (err) { |
419 |
+ kfree_skb(msg->rep); |