From 1b45996d2ebf9680ccd0db875fc668aa025f40fd Mon Sep 17 00:00:00 2001 From: David Daney Date: Tue, 17 May 2016 11:41:04 -0700 Subject: [PATCH 1/2] tty: vt: Fix soft lockup in fbcon cursor blink timer. We are getting somewhat random soft lockups with this signature: [ 86.992215] [] el1_irq+0xa0/0x10c [ 86.997082] [] cursor_timer_handler+0x30/0x54 [ 87.002991] [] call_timer_fn+0x54/0x1a8 [ 87.008378] [] run_timer_softirq+0x1c4/0x2bc [ 87.014200] [] __do_softirq+0x114/0x344 [ 87.019590] [] irq_exit+0x74/0x98 [ 87.024458] [] __handle_domain_irq+0x98/0xfc [ 87.030278] [] gic_handle_irq+0x94/0x190 This is caused by the vt visual_init() function calling into fbcon_init() with a vc_cur_blink_ms value of zero. This is a transient condition, as it is later set to a non-zero value. But, if the timer happens to expire while the blink rate is zero, it goes into an endless loop, and we get soft lockup. The fix is to initialize vc_cur_blink_ms before calling the con_init() function. Signed-off-by: David Daney Cc: stable@vger.kernel.org Acked-by: Pavel Machek Tested-by: Ming Lei Acked-by: Scot Doyle Tested-by: Henrique de Moraes Holschuh Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index dc125322f48f..5b0fe97c46ca 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -750,6 +750,7 @@ static void visual_init(struct vc_data *vc, int num, int init) vc->vc_complement_mask = 0; vc->vc_can_do_color = 0; vc->vc_panic_force_write = false; + vc->vc_cur_blink_ms = DEFAULT_CURSOR_BLINK_MS; vc->vc_sw->con_init(vc, init); if (!vc->vc_complement_mask) vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; From 5353ed8deedee9e5acb9f896e9032158f5d998de Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 20 Jun 2016 15:40:27 +0100 Subject: [PATCH 2/2] devpts: fix null pointer dereference on failed memory allocation An ENOMEM when creating a pair tty in tty_ldisc_setup causes a null pointer dereference in devpts_kill_index because tty->link->driver_data is NULL. The oops was triggered with the pty stressor in stress-ng when in a low memory condition. tty_init_dev tries to clean up a tty_ldisc_setup ENOMEM error by calling release_tty, however, this ultimately tries to clean up the NULL pair'd tty in pty_unix98_remove, triggering the Oops. Add check to pty_unix98_remove to only clean up fsi if it is not NULL. Ooops: [ 23.020961] Oops: 0000 [#1] SMP [ 23.020976] Modules linked in: ppdev snd_hda_codec_generic snd_hda_intel snd_hda_codec parport_pc snd_hda_core snd_hwdep parport snd_pcm input_leds joydev snd_timer serio_raw snd soundcore i2c_piix4 mac_hid ib_iser rdma_cm iw_cm ib_cm ib_core configfs iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi autofs4 btrfs raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq libcrc32c raid1 raid0 multipath linear crct10dif_pclmul crc32_pclmul ghash_clmulni_intel aesni_intel qxl aes_x86_64 ttm lrw gf128mul glue_helper ablk_helper drm_kms_helper cryptd syscopyarea sysfillrect psmouse sysimgblt floppy fb_sys_fops drm pata_acpi jitterentropy_rng drbg ansi_cprng [ 23.020978] CPU: 0 PID: 1452 Comm: stress-ng-pty Not tainted 4.7.0-rc4+ #2 [ 23.020978] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014 [ 23.020979] task: ffff88007ba30000 ti: ffff880078ea8000 task.ti: ffff880078ea8000 [ 23.020981] RIP: 0010:[] [] ida_remove+0x1f/0x120 [ 23.020981] RSP: 0018:ffff880078eabb60 EFLAGS: 00010a03 [ 23.020982] RAX: 4444444444444567 RBX: 0000000000000000 RCX: 000000000000001f [ 23.020982] RDX: 000000000000014c RSI: 000000000000026f RDI: 0000000000000000 [ 23.020982] RBP: ffff880078eabb70 R08: 0000000000000004 R09: 0000000000000036 [ 23.020983] R10: 000000000000026f R11: 0000000000000000 R12: 000000000000026f [ 23.020983] R13: 000000000000026f R14: ffff88007c944b40 R15: 000000000000026f [ 23.020984] FS: 00007f9a2f3cc700(0000) GS:ffff88007fc00000(0000) knlGS:0000000000000000 [ 23.020984] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 23.020985] CR2: 0000000000000010 CR3: 000000006c81b000 CR4: 00000000001406f0 [ 23.020988] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 23.020988] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 23.020988] Stack: [ 23.020989] 0000000000000000 000000000000026f ffff880078eabb90 ffffffff812a5a99 [ 23.020990] 0000000000000000 00000000fffffff4 ffff880078eabba8 ffffffff814f9cbe [ 23.020991] ffff88007965c800 ffff880078eabbc8 ffffffff814eef43 fffffffffffffff4 [ 23.020991] Call Trace: [ 23.021000] [] devpts_kill_index+0x29/0x50 [ 23.021002] [] pty_unix98_remove+0x2e/0x50 [ 23.021006] [] release_tty+0xb3/0x1b0 [ 23.021007] [] tty_init_dev+0xd4/0x1c0 [ 23.021011] [] ptmx_open+0xae/0x190 [ 23.021013] [] chrdev_open+0xbf/0x1b0 [ 23.021015] [] do_dentry_open+0x203/0x310 [ 23.021016] [] ? cdev_put+0x30/0x30 [ 23.021017] [] vfs_open+0x54/0x80 [ 23.021018] [] ? may_open+0x8c/0x100 [ 23.021019] [] path_openat+0x2eb/0x1440 [ 23.021020] [] ? putname+0x54/0x60 [ 23.021022] [] ? n_tty_ioctl_helper+0x27/0x100 [ 23.021023] [] do_filp_open+0x91/0x100 [ 23.021024] [] ? getname_flags+0x56/0x1f0 [ 23.021026] [] ? __alloc_fd+0x46/0x190 [ 23.021027] [] do_sys_open+0x124/0x210 [ 23.021028] [] SyS_open+0x1e/0x20 [ 23.021035] [] entry_SYSCALL_64_fastpath+0x1e/0xa8 [ 23.021044] Code: 63 28 45 31 e4 eb dd 0f 1f 44 00 00 55 4c 63 d6 48 ba 89 88 88 88 88 88 88 88 4c 89 d0 b9 1f 00 00 00 48 f7 e2 48 89 e5 41 54 53 <8b> 47 10 48 89 fb 8d 3c c5 00 00 00 00 48 c1 ea 09 b8 01 00 00 [ 23.021045] RIP [] ida_remove+0x1f/0x120 [ 23.021045] RSP [ 23.021046] CR2: 0000000000000010 Signed-off-by: Colin Ian King Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index f856c4544eea..51e0d32883ba 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -667,8 +667,11 @@ static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) fsi = tty->driver_data; else fsi = tty->link->driver_data; - devpts_kill_index(fsi, tty->index); - devpts_release(fsi); + + if (fsi) { + devpts_kill_index(fsi, tty->index); + devpts_release(fsi); + } } static const struct tty_operations ptm_unix98_ops = {