From: Thomas Osterried <thomas@osterried.de>
To: Roland Schwarz <roland.schwarz@blackspace.at>
Cc: linux-hams@vger.kernel.org
Subject: Re: Kernel freeze on killall kissattach
Date: Sun, 6 Mar 2022 20:01:09 +0100 [thread overview]
Message-ID: <YiUE9XaViss5I2HR@x-berg.in-berlin.de> (raw)
In-Reply-To: <e037cff4-87fa-ce95-438d-66be0754c6b2@blackspace.at>
Hello,
thank you Roland for bringing this up.
I also have prepared a posting to this list; but I liked to first discuss the
new problem with the authors of the patch that caused the regression.
I'll try to keep it short:
Starting with commit 1ade48d0c27d5da1ccf4b583d8c5fc8b534a3ac8
(author Lin Ma <linma@zju.edu.cn> 2021-12-17 10:29:41 +0800)
kernel will panic if
1. there's an active connection
AND
2. you kill kissattach (or rmmod bpqether, etc)
The patch above tries to fix a problem that hhas been in the kernel for many years,
but rarely occured (possible nullpointer exception in ax25_sendmsg()).
This new bug caused by patch 1ade48d0c27d5da1ccf4b583d8c5fc8b534a3ac8 is already
in current linux distributions, like debian bullseye (comes with kernel version 5.10).
Unfortunately, that patch has a real stability impact:
In the kernel trace message I'll append below (Appendix I) we see, that the kernel
panics due to null pointer exception.
Lin Ma tried to assure in ax25_kill_by_device socket locking,
before setting s->ax25_dev to NULL:
+ lock_sock(s->sk);
+ s->ax25_dev = NULL;
But:
s->sk can be NULL.
lock_sock(NULL) leads to kernel panic.
You may argue: can s->sk be NULL, or is there another bug somewhere that should
be fixed instead?
Maybe, but: until we really understand what causes s->sk to be NULL in some situations
(and we'll hav found really all such possible cases), we'll have to assure that we
don't lock_sock(NULL).
The sense of the new lock_sock() is to assure that "s->ax25_dev = NULL" will not cause
a null pointer deference in ax25_sendmsg() [and may be other functions in
the ax25 protocol stack].
On the other hand, if we don't set s->ax25_dev = NULL, it may point to a free()'d
structure, after the device is free'd.
Consider the following as a quick fix (it's tested) against the kernel panic,
caused by 1ade48d0c27d5da1ccf4b583d8c5fc8b534a3ac8:
diff -up a/af_ax25.c b/af_ax25.c
--- a/net/ax25/af_ax25.c 2022-02-26 15:30:35.529637338 +0100
+++ b/net/ax25/af_ax25.c 2022-02-26 15:34:08.789076313 +0100
@@ -86,10 +86,16 @@ again:
ax25_for_each(s, &ax25_list) {
if (s->ax25_dev == ax25_dev) {
spin_unlock_bh(&ax25_list_lock);
+ if (!s->sk) {
+ ax25_dev = NULL;
+ ax25_disconnect(s, ENETUNREACH);
+ goto out;
+ }
lock_sock(s->sk);
s->ax25_dev = NULL;
- release_sock(s->sk);
ax25_disconnect(s, ENETUNREACH);
+ release_sock(s->sk);
+out:
spin_lock_bh(&ax25_list_lock);
/* The entry could have been deleted from the
Keep in mind, that in situation of s->sk == NULL
ax25_dev = NULL;
may still lead to a situation that 1ade48d0c27d5da1ccf4b583d8c5fc8b534a3ac8
tried to fix.
If we look at torwald's kernel tree (which is currently up to kernel netdev tree),
or you remember patches of jan / feb 2022 that we've seen on this list
(i.e. 4e0f718daf97), the code around lock_sock() in ax25_kill_by_device() has
changed again (and reordered the call of some functions).
-> My approach to q&d-fix is this:
--- a/af_ax25.c 2022-02-25 11:49:19.000000000 +0100
+++ b/af_ax25.c 2022-03-01 04:15:16.000000000 +0100
@@ -86,7 +86,13 @@ static void ax25_kill_by_device(struct n
again:
ax25_for_each(s, &ax25_list) {
if (s->ax25_dev == ax25_dev) {
- sk = s->sk;
+ if (!(sk = s->sk)) {
+ s->ax25_dev = NULL;
+ spin_unlock_bh(&ax25_list_lock);
+ ax25_disconnect(s, ENETUNREACH);
+ spin_lock_bh(&ax25_list_lock);
+ goto again;
+ }
sock_hold(sk);
spin_unlock_bh(&ax25_list_lock);
lock_sock(sk);
Apart from this: a new regression:
With patch d01ffb9eee4af165d83b08dd73ebdf9fe94a519b ,
"ax25: add refcount in ax25_dev to avoid UAF bugs"
new reference counters for ax25_dev came in.
If you test kernel torwalds tree, we have two problems:
1. the kernel panics, as described above (happens when
current connected ax25-sessions and you do a killall kissattach)
2. a new regression:
if you use Roland's example and do
1. killall axcall
2. netstat -an
here you see the well-known ax25-ex-connected-session-now-listening-state-bug:
Active AX.25 sockets
Dest Source Device State Vr/Vs Send-Q Recv-Q
DL9SAU-4 DL9SAU-3 ax0 LISTENING 000/000 0 0
3. Now, you do killall kissattach
-> kernel complains in intervall:
unregister_netdevice: waiting for ax1 to become free. Usage count = 2
and this situation lasts for ever.
We know, that nothing cleans up those dead ex-sessions in listening-state.
More trace: see Appendix II.
4. In such a situation, you cannot do anymore, without rebooting,
rmmod ax25 and rmmod mkiss
Final wish:
please let's talk with each other (may be first in private with someone else,
then on this list), before sending a patch to the netdev maintainers.
At least the two problems I've described took only few time of testing and
I stumbled over the problems they introduced.
Two appendixes below.
vy 73,
- Thomas dl9sau
Appendix I:
-----------
debian bullseye kernel 5.10, as well as current linux torvalds tree:
kernel panic after killall kissattach when connections are still active:
[65483.936924] BUG: kernel NULL pointer dereference, address: 0000000000000088
[65483.937138] #PF: supervisor write access in kernel mode
[65483.937249] #PF: error_code(0x0002) - not-present page
[65483.937371] PGD 0 P4D 0
[65483.937447] Oops: 0002 [#1] SMP NOPTI
[65483.937547] CPU: 0 PID: 337635 Comm: kissattach Tainted: G E 5.10.0-11-amd64 #1 Debian 5.10.92-1
[65483.937739] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.14.0-2 04/01/2014
[65483.937908] RIP: 0010:_raw_spin_lock_bh+0x17/0x30
[65483.938023] Code: 00 57 9d 0f 1f 44 00 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 65 81 05 40 65 95 54 00 02 00 00 31 c0 ba 01 00 00 00 <f0> 0f b1 17 75 01 c3 89 c6 e8 bb 14 82 ff 66 90 c3 0f 1f 84 00 00
[65483.938349] RSP: 0018:ffffac24c0c43c48 EFLAGS: 00010246
[65483.938466] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000002
[65483.938606] RDX: 0000000000000001 RSI: 0000000000000000 RDI: 0000000000000088
[65483.938755] RBP: 0000000000000088 R08: 0000000000000000 R09: 0000000000000002
[65483.938902] R10: ffff9622081b9000 R11: 0000000000000000 R12: ffff9622044be000
[65483.939049] R13: 00000000ffffffea R14: ffff9622044be078 R15: ffffac24c0c43d60
[65483.939207] FS: 00007f606b22b740(0000) GS:ffff96227dc00000(0000) knlGS:0000000000000000
[65483.939371] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[65483.939497] CR2: 0000000000000088 CR3: 0000000014344000 CR4: 00000000000006f0
[65483.939648] Call Trace:
[65483.939732] lock_sock_nested+0x1e/0x60
[65483.939856] ax25_device_event+0x89/0xe0 [ax25]
[65483.939969] raw_notifier_call_chain+0x44/0x60
[65483.940078] dev_close_many+0xef/0x150
[65483.940175] rollback_registered_many+0x152/0x6c0
[65483.940337] ? __schedule+0x28a/0x870
[65483.940450] unregister_netdevice_queue+0xcf/0x180
[65483.940571] unregister_netdev+0x18/0x20
[65483.940680] mkiss_close+0x77/0xb0 [mkiss]
[65483.940791] tty_ldisc_release+0x8f/0x180
[65483.940896] tty_release_struct+0x13/0x80
[65483.941003] tty_release+0x437/0x5d0
[65483.941105] __fput+0x95/0x240
[65483.941195] task_work_run+0x65/0xa0
[65483.941294] do_exit+0x362/0xaa0
[65483.941389] do_group_exit+0x33/0xa0
[65483.941489] __x64_sys_exit_group+0x14/0x20
[65483.941601] do_syscall_64+0x33/0x80
[65483.941700] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[65483.941820] RIP: 0033:0x7f606b2f9699
[65483.941915] Code: Unable to access opcode bytes at RIP 0x7f606b2f966f.
Appendix II:
------------
current linux torvalds tree:
killall axcall; one connection still in listening state; killall kissattach
...
[ 321.386733] unregister_netdevice: waiting for ax1 to become free. Usage count = 2
[ 331.467128] unregister_netdevice: waiting for ax1 to become free. Usage count = 2
[ 341.547385] unregister_netdevice: waiting for ax1 to become free. Usage count = 2
[ 351.627710] unregister_netdevice: waiting for ax1 to become free. Usage count = 2
[ 361.707951] unregister_netdevice: waiting for ax1 to become free. Usage count = 2
[ 363.692092] INFO: task kissattach:508 blocked for more than 120 seconds.
[ 363.692321] Tainted: G E 5.17.0-rc6+ #4
[ 363.692444] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 363.692782] task:kissattach state:D stack: 0 pid: 508 ppid: 1 flags:0x00000002
[ 363.693034] Call Trace:
[ 363.693201] <TASK>
[ 363.693451] __schedule+0x302/0x9a0
[ 363.693605] schedule+0x4e/0xc0
[ 363.693730] schedule_preempt_disabled+0x14/0x20
[ 363.693860] __mutex_lock.constprop.0+0x2b4/0x460
[ 363.694009] ? mod_objcg_state+0x107/0x300
[ 363.694134] tty_release+0x4f/0x5e0
[ 363.694217] ? memcg_slab_free_hook+0xcc/0x190
[ 363.694420] __fput+0x8c/0x240
[ 363.694575] task_work_run+0x5c/0x90
[ 363.694749] do_exit+0x331/0xae0
[ 363.694913] do_group_exit+0x2d/0x90
[ 363.697440] __x64_sys_exit_group+0x14/0x20
[ 363.699904] do_syscall_64+0x3b/0xc0
[ 363.702246] entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 363.704704] RIP: 0033:0x7f7dd46f7699
[ 363.706998] RSP: 002b:00007fff436d7088 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
[ 363.709437] RAX: ffffffffffffffda RBX: 00007f7dd47ec610 RCX: 00007f7dd46f7699
[ 363.711905] RDX: 000000000000003c RSI: 00000000000000e7 RDI: 0000000000000000
[ 363.714273] RBP: 0000000000000000 R08: ffffffffffffff80 R09: 0000000000000001
[ 363.716735] R10: 00007f7dd4825440 R11: 0000000000000246 R12: 00007f7dd47ec610
[ 363.719093] R13: 0000000000000001 R14: 00007f7dd47ecae8 R15: 0000000000000000
[ 363.721539] </TASK>
[ 371.788201] unregister_netdevice: waiting for ax1 to become free. Usage count = 2
[ 381.868436] unregister_netdevice: waiting for ax1 to become free. Usage count = 2
[ 391.948686] unregister_netdevice: waiting for ax1 to become free. Usage count = 2
...
On Sun, Mar 06, 2022 at 03:18:14PM +0100, Roland Schwarz wrote:
> Dear All,
>
> please correct me if I am wrong, but as I understand it should not be
> possible to trigger a kernel freeze by just killing user space processes.
>
> While trying to understand a certain behavior of the ax25 driver I came up
> with a small test case which I ran in a virtual machine (KVM):
>
> First I tried with a kernel from Linus tree:
>
> uname -r
> 5.17.0-rc6+
>
> cat /etc/ax25/axports
> ax0 OE1RSA-0 115200 255 7 Test A
> ax1 OE1RSA-1 115200 255 7 Test B
>
> sudo kissattach /dev/ptmx ax0
> AX.25 port ax0 bound to device ax0
> Awaiting client connects on
> /dev/pts/1
>
> sudo kissattach /dev/pts/1 ax1
> AX.25 port ax1 bound to device ax1
>
> axcall ax1 OE1RSA-0
>
> Now in a second terminal:
> sudo killall kissattach
>
> First terminal:
> GW4PTS AX.25 Connect v1.11
> Trying...
> *** Connected to OE1RSA-0
> *** Cleared
>
> ==> But: Kernel freezes
>
> I can see this behaviour also in the debian kernel:
>
> uname -r
> 5.10.0-11-amd64
>
> This kernel also freezes. I suspect this to be a bug because if I try to
> reboot the machine instead of the killall command the machine does not shut
> off and reboot which is a problem with a remotely installed system.
>
> Any ideas?
>
> 73 de Roland oe1rsa
>
> --
> __________________________________________
> _ _ | Roland Schwarz
> |_)(_ |
> | \__) | mailto:roland.schwarz@blackspace.at
> ________| http://www.blackspace.at
next prev parent reply other threads:[~2022-03-06 19:01 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-06 14:18 Kernel freeze on killall kissattach Roland Schwarz
2022-03-06 17:14 ` David Ranch
2022-03-06 18:01 ` Roland Schwarz
2022-03-06 18:05 ` David Ranch
2022-03-06 18:21 ` Roland Schwarz
2022-03-06 19:01 ` Thomas Osterried [this message]
2022-03-06 19:20 ` David Ranch
2022-03-07 10:52 ` Dan Carpenter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YiUE9XaViss5I2HR@x-berg.in-berlin.de \
--to=thomas@osterried.de \
--cc=linux-hams@vger.kernel.org \
--cc=roland.schwarz@blackspace.at \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox