NACK: [SRU][J][PATCH 1/1] ax25: Remove broken autobind
Andrei Gherzan
andrei.gherzan at canonical.com
Mon Sep 14 22:35:42 UTC 2026
On 26/09/09 07:26PM, Cengiz Can via kernel-team wrote:
> From: Murad Masimov <m.masimov at mt-integration.ru>
>
> Binding AX25 socket by using the autobind feature leads to memory leaks
> in ax25_connect() and also refcount leaks in ax25_release(). Memory
> leak was detected with kmemleak:
>
> ================================================================
> unreferenced object 0xffff8880253cd680 (size 96):
> backtrace:
> __kmalloc_node_track_caller_noprof (./include/linux/kmemleak.h:43)
> kmemdup_noprof (mm/util.c:136)
> ax25_rt_autobind (net/ax25/ax25_route.c:428)
> ax25_connect (net/ax25/af_ax25.c:1282)
> __sys_connect_file (net/socket.c:2045)
> __sys_connect (net/socket.c:2064)
> __x64_sys_connect (net/socket.c:2067)
> do_syscall_64 (arch/x86/entry/common.c:52 arch/x86/entry/common.c:83)
> entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
> ================================================================
>
> When socket is bound, refcounts must be incremented the way it is done
> in ax25_bind() and ax25_setsockopt() (SO_BINDTODEVICE). In case of
> autobind, the refcounts are not incremented.
>
> This bug leads to the following issue reported by Syzkaller:
>
> ================================================================
> ax25_connect(): syz-executor318 uses autobind, please contact jreuter at yaina.de
> ------------[ cut here ]------------
> refcount_t: decrement hit 0; leaking memory.
> WARNING: CPU: 0 PID: 5317 at lib/refcount.c:31 refcount_warn_saturate+0xfa/0x1d0 lib/refcount.c:31
> Modules linked in:
> CPU: 0 UID: 0 PID: 5317 Comm: syz-executor318 Not tainted 6.14.0-rc4-syzkaller-00278-gece144f151ac #0
> Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
> RIP: 0010:refcount_warn_saturate+0xfa/0x1d0 lib/refcount.c:31
> ...
> Call Trace:
> <TASK>
> __refcount_dec include/linux/refcount.h:336 [inline]
> refcount_dec include/linux/refcount.h:351 [inline]
> ref_tracker_free+0x6af/0x7e0 lib/ref_tracker.c:236
> netdev_tracker_free include/linux/netdevice.h:4302 [inline]
> netdev_put include/linux/netdevice.h:4319 [inline]
> ax25_release+0x368/0x960 net/ax25/af_ax25.c:1080
> __sock_release net/socket.c:647 [inline]
> sock_close+0xbc/0x240 net/socket.c:1398
> __fput+0x3e9/0x9f0 fs/file_table.c:464
> __do_sys_close fs/open.c:1580 [inline]
> __se_sys_close fs/open.c:1565 [inline]
> __x64_sys_close+0x7f/0x110 fs/open.c:1565
> do_syscall_x64 arch/x86/entry/common.c:52 [inline]
> do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
> entry_SYSCALL_64_after_hwframe+0x77/0x7f
> ...
> </TASK>
> ================================================================
>
> Considering the issues above and the comments left in the code that say:
> "check if we can remove this feature. It is broken."; "autobinding in this
> may or may not work"; - it is better to completely remove this feature than
> to fix it because it is broken and leads to various kinds of memory bugs.
>
> Now calling connect() without first binding socket will result in an
> error (-EINVAL). Userspace software that relies on the autobind feature
> might get broken. However, this feature does not seem widely used with
> this specific driver as it was not reliable at any point of time, and it
> is already broken anyway. E.g. ax25-tools and ax25-apps packages for
> popular distributions do not use the autobind feature for AF_AX25.
>
> Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
>
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Reported-by: syzbot+33841dc6aa3e1d86b78a at syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=33841dc6aa3e1d86b78a
> Signed-off-by: Murad Masimov <m.masimov at mt-integration.ru>
> Signed-off-by: David S. Miller <davem at davemloft.net>
> (backported from commit 2f6efbabceb6b2914ee9bafb86d9a51feae9cce8)
> [bot_kybele: backported to jammy/linux; review and refine this note]
This should be replaced by the actual backporting comment. Same for the cover letter.
> CVE-2025-22109
> Assisted-by: kybele:claude-opus-4.8
> Signed-off-by: Cengiz Can <cengiz.can at canonical.com>
> ---
> include/net/ax25.h | 1 -
> net/ax25/af_ax25.c | 30 ++++++------------
> net/ax25/ax25_route.c | 72 -------------------------------------------
> 3 files changed, 10 insertions(+), 93 deletions(-)
>
> diff --git a/include/net/ax25.h b/include/net/ax25.h
> index aadff553e4b7..097ecf787864 100644
> --- a/include/net/ax25.h
> +++ b/include/net/ax25.h
> @@ -426,7 +426,6 @@ void ax25_rt_device_down(struct net_device *);
> int ax25_rt_ioctl(unsigned int, void __user *);
> extern const struct seq_operations ax25_rt_seqops;
> ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev);
> -int ax25_rt_autobind(ax25_cb *, ax25_address *);
> struct sk_buff *ax25_rt_build_path(struct sk_buff *, ax25_address *,
> ax25_address *, ax25_digi *);
> void ax25_rt_free(void);
> diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
> index b9df05f40513..e111730dd4f4 100644
> --- a/net/ax25/af_ax25.c
> +++ b/net/ax25/af_ax25.c
> @@ -1251,28 +1251,18 @@ static int __must_check ax25_connect(struct socket *sock,
> }
> }
>
> - /*
> - * Must bind first - autobinding in this may or may not work. If
> - * the socket is already bound, check to see if the device has
> - * been filled in, error if it hasn't.
> - */
> + /* Must bind first - autobinding does not work. */
> if (sock_flag(sk, SOCK_ZAPPED)) {
> - /* check if we can remove this feature. It is broken. */
> - printk(KERN_WARNING "ax25_connect(): %s uses autobind, please contact jreuter at yaina.de\n",
> - current->comm);
> - if ((err = ax25_rt_autobind(ax25, &fsa->fsa_ax25.sax25_call)) < 0) {
> - kfree(digi);
> - goto out_release;
> - }
> + kfree(digi);
> + err = -EINVAL;
> + goto out_release;
> + }
>
> - ax25_fillin_cb(ax25, ax25->ax25_dev);
> - ax25_cb_add(ax25);
> - } else {
> - if (ax25->ax25_dev == NULL) {
> - kfree(digi);
> - err = -EHOSTUNREACH;
> - goto out_release;
> - }
> + /* Check to see if the device has been filled in, error if it hasn't. */
> + if (ax25->ax25_dev == NULL) {
> + kfree(digi);
> + err = -EHOSTUNREACH;
> + goto out_release;
> }
>
> if (sk->sk_type == SOCK_SEQPACKET &&
> diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
> index 9751207f7757..17034ad61113 100644
> --- a/net/ax25/ax25_route.c
> +++ b/net/ax25/ax25_route.c
> @@ -374,78 +374,6 @@ ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev)
> return ax25_rt;
> }
>
> -/*
> - * Adjust path: If you specify a default route and want to connect
> - * a target on the digipeater path but w/o having a special route
> - * set before, the path has to be truncated from your target on.
> - */
> -static inline void ax25_adjust_path(ax25_address *addr, ax25_digi *digipeat)
> -{
> - int k;
> -
> - for (k = 0; k < digipeat->ndigi; k++) {
> - if (ax25cmp(addr, &digipeat->calls[k]) == 0)
> - break;
> - }
> -
> - digipeat->ndigi = k;
> -}
> -
> -
> -/*
> - * Find which interface to use.
> - */
> -int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
> -{
> - ax25_uid_assoc *user;
> - ax25_route *ax25_rt;
> - int err = 0;
> -
> - ax25_route_lock_use();
> - ax25_rt = ax25_get_route(addr, NULL);
> - if (!ax25_rt) {
> - ax25_route_lock_unuse();
> - return -EHOSTUNREACH;
> - }
> - if ((ax25->ax25_dev = ax25_dev_ax25dev(ax25_rt->dev)) == NULL) {
> - err = -EHOSTUNREACH;
> - goto put;
> - }
> -
> - user = ax25_findbyuid(current_euid());
> - if (user) {
> - ax25->source_addr = user->call;
> - ax25_uid_put(user);
> - } else {
> - if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) {
> - err = -EPERM;
> - goto put;
> - }
> - ax25->source_addr = *(ax25_address *)ax25->ax25_dev->dev->dev_addr;
> - }
> -
> - if (ax25_rt->digipeat != NULL) {
> - ax25->digipeat = kmemdup(ax25_rt->digipeat, sizeof(ax25_digi),
> - GFP_ATOMIC);
> - if (ax25->digipeat == NULL) {
> - err = -ENOMEM;
> - goto put;
> - }
> - ax25_adjust_path(addr, ax25->digipeat);
> - }
> -
> - if (ax25->sk != NULL) {
> - local_bh_disable();
> - bh_lock_sock(ax25->sk);
> - sock_reset_flag(ax25->sk, SOCK_ZAPPED);
> - bh_unlock_sock(ax25->sk);
> - local_bh_enable();
> - }
> -
> -put:
> - ax25_route_lock_unuse();
> - return err;
> -}
>
> struct sk_buff *ax25_rt_build_path(struct sk_buff *skb, ax25_address *src,
> ax25_address *dest, ax25_digi *digi)
The backport looks fine otherwise.
--
Andrei Gherzan
gpg: rsa4096/D4D94F67AD0E9640
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://lists.ubuntu.com/archives/kernel-team/attachments/20260914/a38696d1/attachment-0001.sig>
More information about the kernel-team
mailing list