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