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:
Harout Hedeshian 2015-01-27 09:26:30 -07:00 committed by Gerrit - the friendly Code Review server
parent e84c87557a
commit d74dbe5345
1 changed files with 14 additions and 4 deletions

View File

@ -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;
}