linux/drivers/char
Yoshihiro YUNOMAE 2b4fbf029d virtio/console: Add pipe_lock/unlock for splice_write
Add pipe_lock/unlock for splice_write to avoid oops by following competition:

(1) An application gets fds of a trace buffer, virtio-serial, pipe.
(2) The application does fork()
(3) The processes execute splice_read(trace buffer) and
    splice_write(virtio-serial) via same pipe.

        <parent>                   <child>
  get fds of a trace buffer,
         virtio-serial, pipe
          |
        fork()----------create--------+
          |                           |
      splice(read)                    |           ---+
      splice(write)                   |              +-- no competition
          |                       splice(read)       |
          |                       splice(write)   ---+
          |                           |
      splice(read)                    |
      splice(write)               splice(read)    ------ competition
          |                       splice(write)

Two processes share a pipe_inode_info structure. If the child execute
splice(read) when the parent tries to execute splice(write), the
structure can be broken. Existing virtio-serial driver does not get
lock for the structure in splice_write, so this competition will induce
oops.

<oops messages>
 BUG: unable to handle kernel NULL pointer dereference at 0000000000000018
 IP: [<ffffffff811a6b5f>] splice_from_pipe_feed+0x6f/0x130
 PGD 7223e067 PUD 72391067 PMD 0
 Oops: 0000 [#1] SMP
 Modules linked in: lockd bnep bluetooth rfkill sunrpc 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 soundcore pcspkr virtio_net virtio_balloon i2c_piix4 i2c_core microcode uinput floppy
 CPU: 0 PID: 1072 Comm: compete-test Not tainted 3.10.0ws+ #55
 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007
 task: ffff880071b98000 ti: ffff88007b55e000 task.ti: ffff88007b55e000
 RIP: 0010:[<ffffffff811a6b5f>]  [<ffffffff811a6b5f>] splice_from_pipe_feed+0x6f/0x130
 RSP: 0018:ffff88007b55fd78  EFLAGS: 00010287
 RAX: 0000000000000000 RBX: ffff88007b55fe20 RCX: 0000000000000000
 RDX: 0000000000001000 RSI: ffff88007a95ba30 RDI: ffff880036f9e6c0
 RBP: ffff88007b55fda8 R08: 00000000000006ec R09: ffff880077626708
 R10: 0000000000000003 R11: ffffffff8139ca59 R12: ffff88007a95ba30
 R13: 0000000000000000 R14: ffffffff8139dd00 R15: ffff880036f9e6c0
 FS:  00007f2e2e3a0740(0000) GS:ffff88007fc00000(0000) knlGS:0000000000000000
 CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
 CR2: 0000000000000018 CR3: 0000000071bd1000 CR4: 00000000000006f0
 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
 Stack:
  ffffffff8139ca59 ffff88007b55fe20 ffff880036f9e6c0 ffffffff8139dd00
  ffff8800776266c0 ffff880077626708 ffff88007b55fde8 ffffffff811a6e8e
  ffff88007b55fde8 ffffffff8139ca59 ffff880036f9e6c0 ffff88007b55fe20
 Call Trace:
  [<ffffffff8139ca59>] ? alloc_buf.isra.13+0x39/0xb0
  [<ffffffff8139dd00>] ? virtcons_restore+0x100/0x100
  [<ffffffff811a6e8e>] __splice_from_pipe+0x7e/0x90
  [<ffffffff8139ca59>] ? alloc_buf.isra.13+0x39/0xb0
  [<ffffffff8139d739>] port_fops_splice_write+0xe9/0x140
  [<ffffffff8127a3f4>] ? selinux_file_permission+0xc4/0x120
  [<ffffffff8139d650>] ? wait_port_writable+0x1b0/0x1b0
  [<ffffffff811a6fe0>] do_splice_from+0xa0/0x110
  [<ffffffff811a951f>] SyS_splice+0x5ff/0x6b0
  [<ffffffff8161facf>] tracesys+0xdd/0xe2
 Code: 49 8b 87 80 00 00 00 4c 8d 24 d0 8b 53 04 41 8b 44 24 0c 4d 8b 6c 24 10 39 d0 89 03 76 02 89 13 49 8b 44 24 10 4c 89 e6 4c 89 ff <ff> 50 18 85 c0 0f 85 aa 00 00 00 48 89 da 4c 89 e6 4c 89 ff 41
 RIP  [<ffffffff811a6b5f>] splice_from_pipe_feed+0x6f/0x130
  RSP <ffff88007b55fd78>
 CR2: 0000000000000018
 ---[ end trace 24572beb7764de59 ]---

V2: Fix a locking problem for error
V3: Add Reviewed-by lines and stable@ line in sign-off area

Signed-off-by: Yoshihiro YUNOMAE <yoshihiro.yunomae.ez@hitachi.com>
Reviewed-by: Amit Shah <amit.shah@redhat.com>
Reviewed-by: Masami 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: Rusty Russell <rusty@rustcorp.com.au>
2013-07-23 12:15:26 +09:30
..
agp Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux 2013-07-09 16:04:31 -07:00
hw_random Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus 2013-07-13 14:52:21 -07:00
ipmi char: Convert use of typedef ctl_table to struct ctl_table 2013-06-17 16:43:08 -07:00
mwave mwave: fix info leak in mwave_ioctl() 2013-07-09 10:33:28 -07:00
pcmcia Finally eradicate CONFIG_HOTPLUG 2013-06-03 14:20:18 -07:00
tpm tpm/tpm_i2c_infineon: Remove unused header file 2013-06-28 00:47:43 +02:00
xilinx_hwicap char: xilinx_hwicap: Fix typo in comment and extend it 2013-05-30 21:46:16 +09:00
apm-emulation.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/apm 2012-04-05 17:34:30 -07:00
applicom.c applicom: use correct array offset 2013-03-15 12:23:48 -07:00
applicom.h
bfin-otp.c
bsr.c powerpc/BSR: cleanup the error path of bsr_init 2012-07-17 10:27:38 -07:00
ds1302.c Remove all #inclusions of asm/system.h 2012-03-28 18:30:03 +01:00
ds1620.c ds1620: single_open() leak 2013-05-05 00:11:29 -04:00
dsp56k.c new helper: file_inode(file) 2013-02-22 23:31:31 -05:00
dtlk.c new helper: file_inode(file) 2013-02-22 23:31:31 -05:00
efirtc.c rtc: single_open() leaks 2013-05-05 00:12:29 -04:00
generic_nvram.c drivers: fix up various ->llseek() implementations 2011-07-20 20:47:58 -04:00
genrtc.c rtc: single_open() leaks 2013-05-05 00:12:29 -04:00
hangcheck-timer.c
hpet.c char: Convert use of typedef ctl_table to struct ctl_table 2013-06-17 16:43:08 -07:00
i8k.c module_param: make bool parameters really bool (drivers & misc) 2012-01-13 09:32:20 +10:30
Kconfig stallion: final cleanup 2013-06-03 14:31:39 -07:00
lp.c Char: lp, protect LPGETSTATUS with port_mutex 2013-05-16 18:08:58 -07:00
Makefile IPMI: Change link order 2012-10-16 18:07:12 -07:00
mbcs.c char: remove use of __devinitconst 2012-11-21 12:55:19 -08:00
mbcs.h Fix common misspellings 2011-03-31 11:26:23 -03:00
mem.c /dev/oldmem: Remove the interface 2013-07-03 16:08:03 -07:00
misc.c Revert "char: misc: assign file->private_data in all cases" 2013-06-26 10:12:48 -07:00
mmtimer.c drivers/char/mmtimer.c: Remove useless kfree 2012-09-26 13:20:40 -07:00
msm_smd_pkt.c drivers/char/msm_smd_pkt.c: don't use IS_ERR() 2011-08-25 16:25:33 -07:00
mspec.c char: Use vma_pages() to replace (vm_end - vm_start) >> PAGE_SHIFT 2013-05-21 10:07:54 -07:00
nsc_gpio.c new helper: file_inode(file) 2013-02-22 23:31:31 -05:00
nvram.c Remove all #inclusions of asm/system.h 2012-03-28 18:30:03 +01:00
nwbutton.c drivers/char: removes unnecessary semicolon 2012-09-26 13:20:39 -07:00
nwbutton.h
nwflash.c Merge branch 'late/fixes' into fixes 2012-10-07 07:22:32 -07:00
pc8736x_gpio.c pc8736x_gpio: use platform_device_unregister in pc8736x_gpio_cleanup() 2012-10-24 15:52:29 -07:00
ppdev.c new helper: file_inode(file) 2013-02-22 23:31:31 -05:00
ps3flash.c ps3flash: switch to generic_file_llseek_size() 2013-06-29 12:57:33 +04:00
random.c char: Convert use of typedef ctl_table to struct ctl_table 2013-06-17 16:43:08 -07:00
raw.c new helper: file_inode(file) 2013-02-22 23:31:31 -05:00
rtc.c char: Convert use of typedef ctl_table to struct ctl_table 2013-06-17 16:43:08 -07:00
scx200_gpio.c
snsc_event.c
snsc.c
snsc.h headers: kobject.h redux 2011-01-10 08:51:44 -08:00
sonypi.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2013-02-26 20:16:07 -08:00
tb0219.c new helper: file_inode(file) 2013-02-22 23:31:31 -05:00
tile-srom.c tile-srom: switch to fixed_size_llseek() 2013-06-29 12:57:51 +04:00
tlclk.c drivers/char/tlclk.c: fix error return code 2012-08-16 10:09:15 -07:00
toshiba.c
ttyprintk.c ttyprintk: Fix NULL pointer deref by setting tty_port ops after initializing port 2013-05-21 10:13:23 -07:00
uv_mmtimer.c
virtio_console.c virtio/console: Add pipe_lock/unlock for splice_write 2013-07-23 12:15:26 +09:30