lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 15 May 2024 17:52:25 +0800 (GMT+08:00)
From: duoming@....edu.cn
To: "Lars Kellogg-Stedman" <lars@...bit.com>
Cc: linux-hams@...r.kernel.org, netdev@...r.kernel.org,
	linux-kernel@...r.kernel.org, pabeni@...hat.com, kuba@...nel.org,
	edumazet@...gle.com, davem@...emloft.net, jreuter@...na.de,
	dan.carpenter@...aro.org
Subject: Re: [PATCH net] ax25: Fix refcount leak issues of ax25_dev

On Wed, 1 May 2024 21:29:16 -0400 Lars Kellogg-Stedman wrote:
> Assume we have the following two interfaces configured on a system:
> 
>     $ cat /etc/ax25/axports
>     udp0 test0-0 9600 255 2 axudp0
>     udp1 test0-1 9600 255 2 axudp1
> 
> And we have ax25d listening on both interfaces:
> 
>     [udp0]
>     default  * * * * * *  - root  /usr/sbin/axwrapper axwrapper -- /bin/sh sh /etc/ax25/example-output.sh
>     [udp1]
>     default  * * * * * *  - root  /usr/sbin/axwrapper axwrapper -- /bin/sh sh /etc/ax25/example-output.sh
> 
> Using the 'ax-devs' and 'ax-sockets' gdb commands shown at the end of
> this message, we start with:
> 
>     (gdb) ax-devs
>     ax1 ax_refcnt:2 dev_refcnt:9 dev_untracked:1 dev_notrack:1
>     ax0 ax_refcnt:2 dev_refcnt:9 dev_untracked:1 dev_notrack:1
>     (gdb) ax-sockets
>     0xffff8881002b6800 if:ax1 state:0 refcnt:2 dev_tracker:0xffff888100ded200
>     0xffff888101ac4e00 if:ax0 state:0 refcnt:2 dev_tracker:0xffff888100dec4c0
> 
> We initiate a connection from ax0 to ax1:
> 
>     call -r udp0 test0-1
> 
> When we first enter ax25_rcv, we have:
> 
>     (gdb) ax-devs
>     ax1 ax_refcnt:2 dev_refcnt:9 dev_untracked:1 dev_notrack:1
>     ax0 ax_refcnt:3 dev_refcnt:10 dev_untracked:1 dev_notrack:1
>     (gdb) ax-sockets
>     0xffff888101ac8000 if:ax0 state:1 refcnt:2 dev_tracker:0xffff888100dedb80
>     0xffff8881002b6800 if:ax1 state:0 refcnt:2 dev_tracker:0xffff888100ded200
>     0xffff888101ac4e00 if:ax0 state:0 refcnt:2 dev_tracker:0xffff888100dec4c0
> 
> After we reach line 413 (in net/ax25/ax25_in.c) and add a new control
> block:
> 
>     ax25_cb_add(ax25)
> 
> We have:
> 
>     (gdb) ax-devs
>     ax1 ax_refcnt:2 dev_refcnt:9 dev_untracked:1 dev_notrack:1
>     ax0 ax_refcnt:3 dev_refcnt:10 dev_untracked:1 dev_notrack:1
>     (gdb) ax-sockets
>     0xffff88810245ac00 if:ax1 state:3 refcnt:2 dev_tracker:0x0 <fixed_percpu_data>
>     0xffff88810245ba00 if:ax0 state:1 refcnt:2 dev_tracker:0xffff88810136c800
>     0xffff888100c79e00 if:ax1 state:0 refcnt:2 dev_tracker:0xffff88810136c6e0
>     0xffff8881018e9800 if:ax0 state:0 refcnt:2 dev_tracker:0xffff88810170c860
> 
> Note that (a) ax25->dev_tracker is NULL, and (b) we have incremeted the
> refcount on ax0 (the source interface), but not on ax1 (the destination
> interface). When we call ax25_release for this control block, we get to:
> 
>     netdev_put(ax25_dev->dev, &ax25->dev_tracker);
>     ax25_dev_put(ax25_dev);
> 
> With:
> 
>     (gdb) ax-devs
>     ax1 ax_refcnt:2 dev_refcnt:9 dev_untracked:1 dev_notrack:1
>     ax0 ax_refcnt:3 dev_refcnt:10 dev_untracked:1 dev_notrack:1
> 
> After the calls to netdev_put() and ax25_dev_put(), we have:
> 
>     (gdb) ax-devs
>     ax1 ax_refcnt:1 dev_refcnt:8 dev_untracked:-1073741824 dev_notrack:1
>     ax0 ax_refcnt:2 dev_refcnt:9 dev_untracked:1 dev_notrack:1
> 
> You can see that (a) ax25_dev->dev->refcnt_tracker->untracked is now
> invalid, and ax25_dev->dev->dev_refcnt is in trouble: it decrements by
> one for each closed connection, even though it was never incremented
> when we accepted the connection. The underflow in
> ...refcnt_tracker->untracked yields the traceback with:
> 
>     refcount_t: decrement hit 0; leaking memory.
> 
> Additional connections will eventually trigger more problems; we will
> ultimately underflow ax25_dev->dev->dev_refcnt, but we may also run into
> memory corruption because of the invalid tracker data, resulting in:
> 
>     BUG: unable to handle page fault for address: 00000010000003b0

Do you know how to trigger this bug? Could you share the POC?

Best regards,
Duoming Zhou

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ