Re: Crash when specifying non-existent serial port in speakup / tty_kopen
On Wed, Nov 04, 2020 at 10:30:05PM +0100, Samuel Thibault wrote: > Matthias Reichl, le mer. 04 nov. 2020 22:15:05 +0100, a ecrit: > > > This looks like only a warning, did it actually crash? > > > > Yes, scroll down a bit, the null pointer oops followed almost > > immediately after that > > > > [ 49.979043] BUG: kernel NULL pointer dereference, address: > > 0090 > > Ah, [ 50.102938] tty_init_dev+0xb5/0x1d0 > > probably the trailing release_tty call that does > > tty->port->itty = NULL; > (itty is after a struct tty_bufhead + the tty pointer, that looks > plausible). > > so probably an if (tty->port) in release_tty could help? Thanks a lot, good catch! This is indeed where the crash happens and checking for tty->port in release_tty() prevents that. I'll send a patch. so long, Hias
Re: Crash when specifying non-existent serial port in speakup / tty_kopen
Matthias Reichl, le mer. 04 nov. 2020 22:15:05 +0100, a ecrit: > > This looks like only a warning, did it actually crash? > > Yes, scroll down a bit, the null pointer oops followed almost > immediately after that > > [ 49.979043] BUG: kernel NULL pointer dereference, address: 0090 Ah, [ 50.102938] tty_init_dev+0xb5/0x1d0 probably the trailing release_tty call that does tty->port->itty = NULL; (itty is after a struct tty_bufhead + the tty pointer, that looks plausible). so probably an if (tty->port) in release_tty could help? Samuel
Re: Crash when specifying non-existent serial port in speakup / tty_kopen
Hi Samuel, On Wed, Nov 04, 2020 at 09:13:23PM +0100, Samuel Thibault wrote: > Hello, > > Matthias Reichl, le mer. 04 nov. 2020 15:57:37 +0100, a ecrit: > > I initially noticed this oops on x86_64 running kernel 5.4.59 when > > I accidentally mistyped "ttyS0" as "ttyS9": > > > > modprobe speakup_dummy dev=ttyS9 > > > [ 49.978481] tty_init_dev: ttyS driver does not set tty->port. This would > > crash the kernel. Fix the driver! > > This looks like only a warning, did it actually crash? Yes, scroll down a bit, the null pointer oops followed almost immediately after that [ 49.979043] BUG: kernel NULL pointer dereference, address: 0090 > > the missing tty->port is quite fatal. > > It is fatal for module insertion yes (EINVAL) but IIRC that should be > getting handled properly, making modprobe return the error? When I did that on my desktop the tty system was pretty screwed. Mouse still worked in X but no keyboard input possible. > > It looks like spk_ttyio or tty_dev_name_to_number() / tty_kopen() > > should perform some additional validation, > > spk_ttyio_initialise_ldisc only has a dev_t so can't do much beyond > calling tty_kopen. > > tty_kopen is getting the index from the tty_lookup_driver call (actually > get_tty_driver which uses p->minor_start and p->num) and passes it to > tty_driver_lookup_tty. Perhaps in addition of p->num the driver should > have another field to set, that tty_init_dev could use to reject with > ENODEV indexes beyond what the driver actually provides? It might be a bit more involved than a simple max port check, think about hotplug (I have 16C950 ExpressCard devices I occansionally use on one of my laptops) so there may be holes in the allocation numbers. Not sure how/where to best solve this. > > I couldn't make the kernel warn/crash yet by specifying non-existent > > ttyUSB ports yet though. > > That's probably because in the ttyUSB case the device allocation is > dynamic and made exactly according to the number of actual devices, > while for ttyS* there is a large overcommit of minor values. Yes, that sounds reasonable (haven't looked at ttyUSB details, only checked serial core devices yet). so long, Hias
Re: Crash when specifying non-existent serial port in speakup / tty_kopen
Hello, Matthias Reichl, le mer. 04 nov. 2020 15:57:37 +0100, a ecrit: > I initially noticed this oops on x86_64 running kernel 5.4.59 when > I accidentally mistyped "ttyS0" as "ttyS9": > > modprobe speakup_dummy dev=ttyS9 > [ 49.978481] tty_init_dev: ttyS driver does not set tty->port. This would > crash the kernel. Fix the driver! This looks like only a warning, did it actually crash? > the missing tty->port is quite fatal. It is fatal for module insertion yes (EINVAL) but IIRC that should be getting handled properly, making modprobe return the error? > It looks like spk_ttyio or tty_dev_name_to_number() / tty_kopen() > should perform some additional validation, spk_ttyio_initialise_ldisc only has a dev_t so can't do much beyond calling tty_kopen. tty_kopen is getting the index from the tty_lookup_driver call (actually get_tty_driver which uses p->minor_start and p->num) and passes it to tty_driver_lookup_tty. Perhaps in addition of p->num the driver should have another field to set, that tty_init_dev could use to reject with ENODEV indexes beyond what the driver actually provides? > I couldn't make the kernel warn/crash yet by specifying non-existent > ttyUSB ports yet though. That's probably because in the ttyUSB case the device allocation is dynamic and made exactly according to the number of actual devices, while for ttyS* there is a large overcommit of minor values. Samuel
Crash when specifying non-existent serial port in speakup / tty_kopen
I initially noticed this oops on x86_64 running kernel 5.4.59 when I accidentally mistyped "ttyS0" as "ttyS9": modprobe speakup_dummy dev=ttyS9 x86_64/5.10-rc2 showed the same behaviour (see below), also 5.9.3 on RPi with the ttyAMA driver. I couldn't make the kernel warn/crash yet by specifying non-existent ttyUSB ports yet though. It looks like spk_ttyio or tty_dev_name_to_number() / tty_kopen() should perform some additional validation, as the missing tty->port is quite fatal. Here's the I got on 5.10-rc2: [ 49.967409] input: Speakup as /devices/virtual/input/input10 [ 49.967731] initialized device: /dev/synth, node (MAJOR 10, MINOR 61) [ 49.968848] speakup 3.1.6: initialized [ 49.968852] synth name on entry is: (null) [ 49.978421] synth probe [ 49.978477] [ cut here ] [ 49.978481] tty_init_dev: ttyS driver does not set tty->port. This would crash the kernel. Fix the driver! [ 49.978522] WARNING: CPU: 1 PID: 283 at drivers/tty/tty_io.c:1351 tty_init_dev+0x17a/0x1d0 [ 49.978525] Modules linked in: speakup_dummy(+) speakup [ 49.978538] CPU: 1 PID: 283 Comm: modprobe Not tainted 5.10.0-rc2 #5 [ 49.978541] Hardware name: /8IPE775/-G, BIOS F5 08/31/2006 [ 49.978580] RIP: 0010:tty_init_dev+0x17a/0x1d0 [ 49.978586] Code: ff ff e8 f9 a6 f5 ff 85 c0 0f 84 43 ff ff ff 49 8b 46 10 48 c7 c6 98 30 07 82 48 c7 c7 b0 c0 26 82 48 8b 50 20 e8 95 37 69 00 <0f> 0b e9 21 ff ff ff e8 da da ff ff e9 ed fe ff ff 4c 89 f7 89 45 [ 49.978591] RSP: 0018:c929bb88 EFLAGS: 00010282 [ 49.978596] RAX: RBX: ffea RCX: 0027 [ 49.978599] RDX: 0027 RSI: 88807dc97820 RDI: 88807dc97828 [ 49.978603] RBP: c929bbb0 R08: R09: c000dfff [ 49.978605] R10: 0001 R11: c929b958 R12: 88800386df00 [ 49.978608] R13: 0009 R14: 88800514c000 R15: a001e500 [ 49.978613] FS: 7faebf8ae540() GS:88807dc8() knlGS: [ 49.978617] CS: 0010 DS: ES: CR0: 80050033 [ 49.978621] CR2: 7fff4ff25ff8 CR3: 0529a000 CR4: 06e0 [ 49.978624] Call Trace: [ 49.978635] tty_kopen+0x101/0x150 [ 49.978651] spk_ttyio_synth_probe+0xd5/0x230 [speakup] [ 49.978661] ? _cond_resched+0x14/0x30 [ 49.978669] ? do_init_module+0x22/0x200 [ 49.978678] do_synth_init.cold.11+0x2d/0x15f [speakup] [ 49.978686] synth_add+0x95/0xa0 [speakup] [ 49.978689] ? 0xa0021000 [ 49.978696] synth_dummy_init+0x10/0x1000 [speakup_dummy] [ 49.978702] do_one_initcall+0x45/0x1d0 [ 49.978707] ? _cond_resched+0x14/0x30 [ 49.978714] ? kmem_cache_alloc_trace+0x39/0x1b0 [ 49.978720] do_init_module+0x5b/0x200 [ 49.978726] load_module+0x25e6/0x2830 [ 49.978733] __do_sys_finit_module+0xc1/0x120 [ 49.978737] ? __do_sys_finit_module+0xc1/0x120 [ 49.978744] __x64_sys_finit_module+0x15/0x20 [ 49.978750] do_syscall_64+0x37/0x50 [ 49.978757] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 49.978762] RIP: 0033:0x7faebf9cf919 [ 49.978767] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 47 55 0c 00 f7 d8 64 89 01 48 [ 49.978771] RSP: 002b:7fffb3a03018 EFLAGS: 0246 ORIG_RAX: 0139 [ 49.978777] RAX: ffda RBX: 5620ea9c58f0 RCX: 7faebf9cf919 [ 49.978780] RDX: RSI: 5620ea9c5e10 RDI: 0004 [ 49.978783] RBP: 0004 R08: R09: [ 49.978785] R10: 0004 R11: 0246 R12: 5620ea9c5e10 [ 49.978788] R13: R14: 5620ea9c5ab0 R15: 5620ea9c58f0 [ 49.978795] CPU: 1 PID: 283 Comm: modprobe Not tainted 5.10.0-rc2 #5 [ 49.978798] Hardware name: /8IPE775/-G, BIOS F5 08/31/2006 [ 49.978800] Call Trace: [ 49.978806] dump_stack+0x5e/0x74 [ 49.978813] __warn.cold.13+0xe/0x3f [ 49.978819] ? tty_init_dev+0x17a/0x1d0 [ 49.978826] report_bug+0xc5/0x100 [ 49.978831] handle_bug+0x48/0x90 [ 49.978835] exc_invalid_op+0x18/0x70 [ 49.978839] asm_exc_invalid_op+0x12/0x20 [ 49.978844] RIP: 0010:tty_init_dev+0x17a/0x1d0 [ 49.978849] Code: ff ff e8 f9 a6 f5 ff 85 c0 0f 84 43 ff ff ff 49 8b 46 10 48 c7 c6 98 30 07 82 48 c7 c7 b0 c0 26 82 48 8b 50 20 e8 95 37 69 00 <0f> 0b e9 21 ff ff ff e8 da da ff ff e9 ed fe ff ff 4c 89 f7 89 45 [ 49.978852] RSP: 0018:c929bb88 EFLAGS: 00010282 [ 49.978857] RAX: RBX: ffea RCX: 0027 [ 49.978860] RDX: 0027 RSI: 88807dc97820 RDI: 88807dc97828 [ 49.978863] RBP: c929bbb0 R08: R09: c000dfff [ 49.978865] R10: 0001 R11: c929b958 R12: 88800386df00 [ 49.978868] R13: 0009 R14: 88800514c000 R15: a001e500 [