Commit 9b338c3d authored by David Herrmann's avatar David Herrmann Committed by Gustavo F. Padovan

Bluetooth: bnep: Fix module reference

We cannot call module_put(THIS_MODULE) if this is our last reference. Otherwise,
this call may cleanup our module before it returns.

Gladly, the kthread API provides a simple wrapper for us. So lets use
module_put_and_exit() to avoid a race condition with the module cleanup code.
Signed-off-by: default avatarDavid Herrmann <dh.herrmann@googlemail.com>
Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
Signed-off-by: default avatarGustavo F. Padovan <padovan@profusion.mobi>
parent 48b28b8d
...@@ -79,17 +79,12 @@ static struct bnep_session *__bnep_get_session(u8 *dst) ...@@ -79,17 +79,12 @@ static struct bnep_session *__bnep_get_session(u8 *dst)
static void __bnep_link_session(struct bnep_session *s) static void __bnep_link_session(struct bnep_session *s)
{ {
/* It's safe to call __module_get() here because sessions are added
by the socket layer which has to hold the reference to this module.
*/
__module_get(THIS_MODULE);
list_add(&s->list, &bnep_session_list); list_add(&s->list, &bnep_session_list);
} }
static void __bnep_unlink_session(struct bnep_session *s) static void __bnep_unlink_session(struct bnep_session *s)
{ {
list_del(&s->list); list_del(&s->list);
module_put(THIS_MODULE);
} }
static int bnep_send(struct bnep_session *s, void *data, size_t len) static int bnep_send(struct bnep_session *s, void *data, size_t len)
...@@ -530,6 +525,7 @@ static int bnep_session(void *arg) ...@@ -530,6 +525,7 @@ static int bnep_session(void *arg)
up_write(&bnep_session_sem); up_write(&bnep_session_sem);
free_netdev(dev); free_netdev(dev);
module_put_and_exit(0);
return 0; return 0;
} }
...@@ -616,9 +612,11 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) ...@@ -616,9 +612,11 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
__bnep_link_session(s); __bnep_link_session(s);
__module_get(THIS_MODULE);
s->task = kthread_run(bnep_session, s, "kbnepd %s", dev->name); s->task = kthread_run(bnep_session, s, "kbnepd %s", dev->name);
if (IS_ERR(s->task)) { if (IS_ERR(s->task)) {
/* Session thread start failed, gotta cleanup. */ /* Session thread start failed, gotta cleanup. */
module_put(THIS_MODULE);
unregister_netdev(dev); unregister_netdev(dev);
__bnep_unlink_session(s); __bnep_unlink_session(s);
err = PTR_ERR(s->task); err = PTR_ERR(s->task);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment