This is a note to let you know that I've just added the patch titled ax25: Fix refcount leaks caused by ax25_cb_del() to the 4.14-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: ax25-fix-refcount-leaks-caused-by-ax25_cb_del.patch and it can be found in the queue-4.14 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From foo@baz Tue Apr 26 09:02:03 AM CEST 2022 From: Ovidiu Panait <ovidiu.panait@xxxxxxxxxxxxx> Date: Thu, 21 Apr 2022 13:37:35 +0300 Subject: ax25: Fix refcount leaks caused by ax25_cb_del() To: stable@xxxxxxxxxxxxxxx Cc: Duoming Zhou <duoming@xxxxxxxxxx>, Thomas Osterried <thomas@xxxxxxxxxxxx>, "David S . Miller" <davem@xxxxxxxxxxxxx>, Ovidiu Panait <ovidiu.panait@xxxxxxxxxxxxx> Message-ID: <20220421103739.1274449-4-ovidiu.panait@xxxxxxxxxxxxx> From: Duoming Zhou <duoming@xxxxxxxxxx> commit 9fd75b66b8f68498454d685dc4ba13192ae069b0 upstream. The previous commit d01ffb9eee4a ("ax25: add refcount in ax25_dev to avoid UAF bugs") and commit feef318c855a ("ax25: fix UAF bugs of net_device caused by rebinding operation") increase the refcounts of ax25_dev and net_device in ax25_bind() and decrease the matching refcounts in ax25_kill_by_device() in order to prevent UAF bugs, but there are reference count leaks. The root cause of refcount leaks is shown below: (Thread 1) | (Thread 2) ax25_bind() | ... | ax25_addr_ax25dev() | ax25_dev_hold() //(1) | ... | dev_hold_track() //(2) | ... | ax25_destroy_socket() | ax25_cb_del() | ... | hlist_del_init() //(3) | | (Thread 3) | ax25_kill_by_device() | ... | ax25_for_each(s, &ax25_list) { | if (s->ax25_dev == ax25_dev) //(4) | ... | Firstly, we use ax25_bind() to increase the refcount of ax25_dev in position (1) and increase the refcount of net_device in position (2). Then, we use ax25_cb_del() invoked by ax25_destroy_socket() to delete ax25_cb in hlist in position (3) before calling ax25_kill_by_device(). Finally, the decrements of refcounts in ax25_kill_by_device() will not be executed, because no s->ax25_dev equals to ax25_dev in position (4). This patch adds decrements of refcounts in ax25_release() and use lock_sock() to do synchronization. If refcounts decrease in ax25_release(), the decrements of refcounts in ax25_kill_by_device() will not be executed and vice versa. Fixes: d01ffb9eee4a ("ax25: add refcount in ax25_dev to avoid UAF bugs") Fixes: 87563a043cef ("ax25: fix reference count leaks of ax25_dev") Fixes: feef318c855a ("ax25: fix UAF bugs of net_device caused by rebinding operation") Reported-by: Thomas Osterried <thomas@xxxxxxxxxxxx> Signed-off-by: Duoming Zhou <duoming@xxxxxxxxxx> Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx> [OP: backport to 4.14: adjust dev_put_track()->dev_put()] Signed-off-by: Ovidiu Panait <ovidiu.panait@xxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- net/ax25/af_ax25.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -101,8 +101,10 @@ again: spin_unlock_bh(&ax25_list_lock); lock_sock(sk); s->ax25_dev = NULL; - dev_put(ax25_dev->dev); - ax25_dev_put(ax25_dev); + if (sk->sk_socket) { + dev_put(ax25_dev->dev); + ax25_dev_put(ax25_dev); + } release_sock(sk); ax25_disconnect(s, ENETUNREACH); spin_lock_bh(&ax25_list_lock); @@ -982,14 +984,20 @@ static int ax25_release(struct socket *s { struct sock *sk = sock->sk; ax25_cb *ax25; + ax25_dev *ax25_dev; if (sk == NULL) return 0; sock_hold(sk); - sock_orphan(sk); lock_sock(sk); + sock_orphan(sk); ax25 = sk_to_ax25(sk); + ax25_dev = ax25->ax25_dev; + if (ax25_dev) { + dev_put(ax25_dev->dev); + ax25_dev_put(ax25_dev); + } if (sk->sk_type == SOCK_SEQPACKET) { switch (ax25->state) { Patches currently in stable-queue which might be from ovidiu.panait@xxxxxxxxxxxxx are queue-4.14/ax25-fix-refcount-leaks-caused-by-ax25_cb_del.patch queue-4.14/ax25-fix-uaf-bug-in-ax25_send_control.patch queue-4.14/ax25-fix-uaf-bugs-of-net_device-caused-by-rebinding-operation.patch queue-4.14/ax25-fix-npd-bug-in-ax25_disconnect.patch queue-4.14/ax25-add-refcount-in-ax25_dev-to-avoid-uaf-bugs.patch queue-4.14/ax25-fix-uaf-bugs-in-ax25-timers.patch queue-4.14/ax25-fix-reference-count-leaks-of-ax25_dev.patch queue-4.14/ax25-fix-null-pointer-dereferences-in-ax25-timers.patch