]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.18.14/tipc-call-start-and-done-ops-directly-in-__tipc_nl_compat_dumpit.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.18.14 / tipc-call-start-and-done-ops-directly-in-__tipc_nl_compat_dumpit.patch
CommitLineData
54545ec3
GKH
1From 8f5c5fcf353302374b36232d6885c1a3b579e5ca Mon Sep 17 00:00:00 2001
2From: Cong Wang <xiyou.wangcong@gmail.com>
3Date: Tue, 4 Sep 2018 14:54:55 -0700
4Subject: tipc: call start and done ops directly in __tipc_nl_compat_dumpit()
5
6From: Cong Wang <xiyou.wangcong@gmail.com>
7
8commit 8f5c5fcf353302374b36232d6885c1a3b579e5ca upstream.
9
10__tipc_nl_compat_dumpit() uses a netlink_callback on stack,
11so the only way to align it with other ->dumpit() call path
12is calling tipc_dump_start() and tipc_dump_done() directly
13inside it. Otherwise ->dumpit() would always get NULL from
14cb->args[].
15
16But tipc_dump_start() uses sock_net(cb->skb->sk) to retrieve
17net pointer, the cb->skb here doesn't set skb->sk, the net pointer
18is saved in msg->net instead, so introduce a helper function
19__tipc_dump_start() to pass in msg->net.
20
21Ying pointed out cb->args[0...3] are already used by other
22callbacks on this call path, so we can't use cb->args[0] any
23more, use cb->args[4] instead.
24
25Fixes: 9a07efa9aea2 ("tipc: switch to rhashtable iterator")
26Reported-and-tested-by: syzbot+e93a2c41f91b8e2c7d9b@syzkaller.appspotmail.com
27Cc: Jon Maloy <jon.maloy@ericsson.com>
28Cc: Ying Xue <ying.xue@windriver.com>
29Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
30Acked-by: Ying Xue <ying.xue@windriver.com>
31Signed-off-by: David S. Miller <davem@davemloft.net>
32Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
33
34---
35 net/tipc/netlink_compat.c | 2 ++
36 net/tipc/socket.c | 17 +++++++++++------
37 net/tipc/socket.h | 1 +
38 3 files changed, 14 insertions(+), 6 deletions(-)
39
40--- a/net/tipc/netlink_compat.c
41+++ b/net/tipc/netlink_compat.c
42@@ -185,6 +185,7 @@ static int __tipc_nl_compat_dumpit(struc
43 return -ENOMEM;
44
45 buf->sk = msg->dst_sk;
46+ __tipc_dump_start(&cb, msg->net);
47
48 do {
49 int rem;
50@@ -216,6 +217,7 @@ static int __tipc_nl_compat_dumpit(struc
51 err = 0;
52
53 err_out:
54+ tipc_dump_done(&cb);
55 kfree_skb(buf);
56
57 if (err == -EMSGSIZE) {
58--- a/net/tipc/socket.c
59+++ b/net/tipc/socket.c
60@@ -3233,7 +3233,7 @@ int tipc_nl_sk_walk(struct sk_buff *skb,
61 struct netlink_callback *cb,
62 struct tipc_sock *tsk))
63 {
64- struct rhashtable_iter *iter = (void *)cb->args[0];
65+ struct rhashtable_iter *iter = (void *)cb->args[4];
66 struct tipc_sock *tsk;
67 int err;
68
69@@ -3269,8 +3269,14 @@ EXPORT_SYMBOL(tipc_nl_sk_walk);
70
71 int tipc_dump_start(struct netlink_callback *cb)
72 {
73- struct rhashtable_iter *iter = (void *)cb->args[0];
74- struct net *net = sock_net(cb->skb->sk);
75+ return __tipc_dump_start(cb, sock_net(cb->skb->sk));
76+}
77+EXPORT_SYMBOL(tipc_dump_start);
78+
79+int __tipc_dump_start(struct netlink_callback *cb, struct net *net)
80+{
81+ /* tipc_nl_name_table_dump() uses cb->args[0...3]. */
82+ struct rhashtable_iter *iter = (void *)cb->args[4];
83 struct tipc_net *tn = tipc_net(net);
84
85 if (!iter) {
86@@ -3278,17 +3284,16 @@ int tipc_dump_start(struct netlink_callb
87 if (!iter)
88 return -ENOMEM;
89
90- cb->args[0] = (long)iter;
91+ cb->args[4] = (long)iter;
92 }
93
94 rhashtable_walk_enter(&tn->sk_rht, iter);
95 return 0;
96 }
97-EXPORT_SYMBOL(tipc_dump_start);
98
99 int tipc_dump_done(struct netlink_callback *cb)
100 {
101- struct rhashtable_iter *hti = (void *)cb->args[0];
102+ struct rhashtable_iter *hti = (void *)cb->args[4];
103
104 rhashtable_walk_exit(hti);
105 kfree(hti);
106--- a/net/tipc/socket.h
107+++ b/net/tipc/socket.h
108@@ -69,5 +69,6 @@ int tipc_nl_sk_walk(struct sk_buff *skb,
109 struct netlink_callback *cb,
110 struct tipc_sock *tsk));
111 int tipc_dump_start(struct netlink_callback *cb);
112+int __tipc_dump_start(struct netlink_callback *cb, struct net *net);
113 int tipc_dump_done(struct netlink_callback *cb);
114 #endif