Skip to content

Commit 41c8742

Browse files
zx2c4davem330
authored andcommitted
netlink: do not set cb_running if dump's start() errs
It turns out that multiple places can call netlink_dump(), which means it's still possible to dereference partially initialized values in dump() that were the result of a faulty returned start(). This fixes the issue by calling start() _before_ setting cb_running to true, so that there's no chance at all of hitting the dump() function through any indirect paths. It also moves the call to start() to be when the mutex is held. This has the nice side effect of serializing invocations to start(), which is likely desirable anyway. It also prevents any possible other races that might come out of this logic. In testing this with several different pieces of tricky code to trigger these issues, this commit fixes all avenues that I'm aware of. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Cc: Johannes Berg <johannes@sipsolutions.net> Reviewed-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 6df4d17 commit 41c8742

File tree

1 file changed

+7
-6
lines changed

1 file changed

+7
-6
lines changed

net/netlink/af_netlink.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2266,16 +2266,17 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
22662266
cb->min_dump_alloc = control->min_dump_alloc;
22672267
cb->skb = skb;
22682268

2269+
if (cb->start) {
2270+
ret = cb->start(cb);
2271+
if (ret)
2272+
goto error_unlock;
2273+
}
2274+
22692275
nlk->cb_running = true;
22702276

22712277
mutex_unlock(nlk->cb_mutex);
22722278

2273-
ret = 0;
2274-
if (cb->start)
2275-
ret = cb->start(cb);
2276-
2277-
if (!ret)
2278-
ret = netlink_dump(sk);
2279+
ret = netlink_dump(sk);
22792280

22802281
sock_put(sk);
22812282

0 commit comments

Comments
 (0)