• Yoshihiro YUNOMAE's avatar
    virtio/console: Quit from splice_write if pipe->nrbufs is 0 · 68c034fe
    Yoshihiro YUNOMAE authored
    Quit from splice_write if pipe->nrbufs is 0 for avoiding oops in virtio-serial.
    
    When an application was doing splice from a kernel buffer to virtio-serial on
    a guest, the application received signal(SIGINT). This situation will normally
    happen, but the kernel executed a kernel panic by oops as follows:
    
     BUG: unable to handle kernel paging request at ffff882071c8ef28
     IP: [<ffffffff812de48f>] sg_init_table+0x2f/0x50
     PGD 1fac067 PUD 0
     Oops: 0000 [#1] SMP
     Modules linked in: lockd sunrpc bnep bluetooth rfkill ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables snd_hda_intel snd_hda_codec snd_hwdep snd_pcm snd_page_alloc snd_timer snd microcode virtio_balloon virtio_net pcspkr soundcore i2c_piix4 i2c_core uinput floppy
     CPU: 1 PID: 908 Comm: trace-cmd Not tainted 3.10.0+ #49
     Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007
     task: ffff880071c64650 ti: ffff88007bf24000 task.ti: ffff88007bf24000
     RIP: 0010:[<ffffffff812de48f>]  [<ffffffff812de48f>] sg_init_table+0x2f/0x50
     RSP: 0018:ffff88007bf25dd8  EFLAGS: 00010286
     RAX: 0000001fffffffe0 RBX: ffff882071c8ef28 RCX: 0000000000000000
     RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff880071c8ef48
     RBP: ffff88007bf25de8 R08: ffff88007fd15d40 R09: ffff880071c8ef48
     R10: ffffea0001c71040 R11: ffffffff8139c555 R12: 0000000000000000
     R13: ffff88007506a3c0 R14: ffff88007c862500 R15: ffff880071c8ef00
     FS:  00007f0a3646c740(0000) GS:ffff88007fd00000(0000) knlGS:0000000000000000
     CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
     CR2: ffff882071c8ef28 CR3: 000000007acbb000 CR4: 00000000000006e0
     DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
     DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
     Stack:
      ffff880071c8ef48 ffff88007bf25e20 ffff88007bf25e88 ffffffff8139d6fa
      ffff88007bf25e28 ffffffff8127a3f4 0000000000000000 0000000000000000
      ffff880071c8ef48 0000100000000000 0000000000000003 ffff88007bf25e08
     Call Trace:
      [<ffffffff8139d6fa>] port_fops_splice_write+0xaa/0x130
      [<ffffffff8127a3f4>] ? selinux_file_permission+0xc4/0x120
      [<ffffffff8139d650>] ? wait_port_writable+0x1b0/0x1b0
      [<ffffffff811a6fe0>] do_splice_from+0xa0/0x110
      [<ffffffff811a951f>] SyS_splice+0x5ff/0x6b0
      [<ffffffff8161f8c2>] system_call_fastpath+0x16/0x1b
     Code: c1 e2 05 48 89 e5 48 83 ec 10 4c 89 65 f8 41 89 f4 31 f6 48 89 5d f0 48 89 fb e8 8d ce ff ff 41 8d 44 24 ff 48 c1 e0 05 48 01 c3 <48> 8b 03 48 83 e0 fe 48 83 c8 02 48 89 03 48 8b 5d f0 4c 8b 65
     RIP  [<ffffffff812de48f>] sg_init_table+0x2f/0x50
      RSP <ffff88007bf25dd8>
     CR2: ffff882071c8ef28
     ---[ end trace 86323505eb42ea8f ]---
    
    It seems to induce pagefault in sg_init_tabel() when pipe->nrbufs is equal to
    zero. This may happen in a following situation:
    
    (1) The application normally does splice(read) from a kernel buffer, then does
        splice(write) to virtio-serial.
    (2) The application receives SIGINT when is doing splice(read), so splice(read)
        is failed by EINTR. However, the application does not finish the operation.
    (3) The application tries to do splice(write) without pipe->nrbufs.
    (4) The virtio-console driver tries to touch scatterlist structure sgl in
        sg_init_table(), but the region is out of bound.
    
    To avoid the case, a kernel should check whether pipe->nrbufs is empty or not
    when splice_write is executed in the virtio-console driver.
    
    V3: Add Reviewed-by lines and stable@ line in sign-off area.
    Signed-off-by: default avatarYoshihiro YUNOMAE <yoshihiro.yunomae.ez@hitachi.com>
    Reviewed-by: default avatarAmit Shah <amit.shah@redhat.com>
    Reviewed-by: default avatarMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
    Cc: Amit Shah <amit.shah@redhat.com>
    Cc: Arnd Bergmann <arnd@arndb.de>
    Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
    68c034fe
virtio_console.c 54.6 KB