net: socket: make sure refs are not released on fd before calling sockev
Ensure that BIND and LISTEN syscalls do fput_light AFTER sockev notifier callback has returned. Also, increase refcount on sock->sk (if available) before invoking the notifier callback. Prevent crash due to use-after-free. [<c0891d5c>] (sockev_client_cb+0xfc/0x1e4) from [<c0a273a4>] (notifier_cal [<c0a273a4>] (notifier_call_chain+0x44/0x84) from [<c01422cc>] (__blocking [<c01422cc>] (__blocking_notifier_call_chain+0x48/0x60) from [<c01422fc>] [<c01422fc>] (blocking_notifier_call_chain+0x18/0x20) from [<c0865968>] (S [<c0865968>] (SyS_bind+0xb0/0xe8) from [<c0105ba0>] (ret_fast_syscall+0x0/ CRs-Fixed: 787283 Change-Id: I2de65929b22c58637692cf582b6b46b11713494e Signed-off-by: Harout Hedeshian <harouth@codeaurora.org>
This commit is contained in:
parent
e84c87557a
commit
d74dbe5345
18
net/socket.c
18
net/socket.c
|
@ -1527,9 +1527,14 @@ SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen)
|
|||
(struct sockaddr *)
|
||||
&address, addrlen);
|
||||
}
|
||||
fput_light(sock->file, fput_needed);
|
||||
if (!err)
|
||||
if (!err) {
|
||||
if (sock->sk)
|
||||
sock_hold(sock->sk);
|
||||
sockev_notify(SOCKEV_BIND, sock);
|
||||
if (sock->sk)
|
||||
sock_put(sock->sk);
|
||||
}
|
||||
fput_light(sock->file, fput_needed);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
@ -1556,9 +1561,14 @@ SYSCALL_DEFINE2(listen, int, fd, int, backlog)
|
|||
if (!err)
|
||||
err = sock->ops->listen(sock, backlog);
|
||||
|
||||
fput_light(sock->file, fput_needed);
|
||||
if (!err)
|
||||
if (!err) {
|
||||
if (sock->sk)
|
||||
sock_hold(sock->sk);
|
||||
sockev_notify(SOCKEV_LISTEN, sock);
|
||||
if (sock->sk)
|
||||
sock_put(sock->sk);
|
||||
}
|
||||
fput_light(sock->file, fput_needed);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue