virtualization.lists.linux-foundation.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V2 0/2] [BUGFIX] virtio/console: Fix two bugs of splice_write
@ 2013-07-19  9:19 Yoshihiro YUNOMAE
  2013-07-19  9:19 ` [PATCH V2 1/2] [BUGFIX] virtio/console: Quit from splice_write if pipe->nrbufs is 0 Yoshihiro YUNOMAE
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Yoshihiro YUNOMAE @ 2013-07-19  9:19 UTC (permalink / raw)
  To: Amit Shah, linux-kernel
  Cc: Arnd Bergmann, Greg Kroah-Hartman, stable, virtualization,
	Masami Hiramatsu, yrl.pp-manager.tt, Hidehiro Kawai

Hi,

This patch set fixes two bugs of splice_write in the virtio-console driver.

[BUG1] Although pipe->nrbufs is empty, the driver tries to do splice_write.
       => This induces oops in sg_init_table().

[BUG2] No lock for competition of splice_write.
       => This induces oops in splice_from_pipe_feed() by bug of any user
          application.

These reports are written in each patch.

Changes in V2:
- Fix a locking problem for error

Thanks!

---

Yoshihiro YUNOMAE (2):
      [BUGFIX] virtio/console: Quit from splice_write if pipe->nrbufs is 0
      [BUGFIX] virtio/console: Add pipe_lock/unlock for splice_write


 drivers/char/virtio_console.c |   23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

-- 
Yoshihiro YUNOMAE
Software Platform Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: yoshihiro.yunomae.ez@hitachi.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH V2 1/2] [BUGFIX] virtio/console: Quit from splice_write if pipe->nrbufs is 0
  2013-07-19  9:19 [PATCH V2 0/2] [BUGFIX] virtio/console: Fix two bugs of splice_write Yoshihiro YUNOMAE
@ 2013-07-19  9:19 ` Yoshihiro YUNOMAE
  2013-07-19 12:25   ` Masami Hiramatsu
  2013-07-19  9:19 ` [PATCH V2 2/2] [BUGFIX] virtio/console: Add pipe_lock/unlock for splice_write Yoshihiro YUNOMAE
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Yoshihiro YUNOMAE @ 2013-07-19  9:19 UTC (permalink / raw)
  To: Amit Shah, linux-kernel
  Cc: Arnd Bergmann, Greg Kroah-Hartman, stable, virtualization,
	Masami Hiramatsu, yrl.pp-manager.tt, Hidehiro Kawai

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.

Signed-off-by: Yoshihiro YUNOMAE <yoshihiro.yunomae.ez@hitachi.com>
Cc: Amit Shah <amit.shah@redhat.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/char/virtio_console.c |    7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 1b456fe..8722656 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -932,6 +932,13 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
 	if (is_rproc_serial(port->out_vq->vdev))
 		return -EINVAL;
 
+	/*
+	 * pipe->nrbufs == 0 means there are no data to transfer,
+	 * so this returns just 0 for no data.
+	 */
+	if (!pipe->nrbufs)
+		return 0;
+
 	ret = wait_port_writable(port, filp->f_flags & O_NONBLOCK);
 	if (ret < 0)
 		return ret;

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH V2 2/2] [BUGFIX] virtio/console: Add pipe_lock/unlock for splice_write
  2013-07-19  9:19 [PATCH V2 0/2] [BUGFIX] virtio/console: Fix two bugs of splice_write Yoshihiro YUNOMAE
  2013-07-19  9:19 ` [PATCH V2 1/2] [BUGFIX] virtio/console: Quit from splice_write if pipe->nrbufs is 0 Yoshihiro YUNOMAE
@ 2013-07-19  9:19 ` Yoshihiro YUNOMAE
  2013-07-19 10:05 ` [PATCH V2 0/2] [BUGFIX] virtio/console: Fix two bugs of splice_write Amit Shah
       [not found] ` <20130719091956.9698.30207.stgit@yunodevel>
  3 siblings, 0 replies; 7+ messages in thread
From: Yoshihiro YUNOMAE @ 2013-07-19  9:19 UTC (permalink / raw)
  To: Amit Shah, linux-kernel
  Cc: Arnd Bergmann, Greg Kroah-Hartman, stable, virtualization,
	Masami Hiramatsu, yrl.pp-manager.tt, Hidehiro Kawai

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

Signed-off-by: Yoshihiro YUNOMAE <yoshihiro.yunomae.ez@hitachi.com>
Cc: Amit Shah <amit.shah@redhat.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/char/virtio_console.c |   20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 8722656..8a15af3 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -936,16 +936,21 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
 	 * pipe->nrbufs == 0 means there are no data to transfer,
 	 * so this returns just 0 for no data.
 	 */
-	if (!pipe->nrbufs)
-		return 0;
+	pipe_lock(pipe);
+	if (!pipe->nrbufs) {
+		ret = 0;
+		goto error_out;
+	}
 
 	ret = wait_port_writable(port, filp->f_flags & O_NONBLOCK);
 	if (ret < 0)
-		return ret;
+		goto error_out;
 
 	buf = alloc_buf(port->out_vq, 0, pipe->nrbufs);
-	if (!buf)
-		return -ENOMEM;
+	if (!buf) {
+		ret = -ENOMEM;
+		goto error_out;
+	}
 
 	sgl.n = 0;
 	sgl.len = 0;
@@ -953,12 +958,17 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
 	sgl.sg = buf->sg;
 	sg_init_table(sgl.sg, sgl.size);
 	ret = __splice_from_pipe(pipe, &sd, pipe_to_sg);
+	pipe_unlock(pipe);
 	if (likely(ret > 0))
 		ret = __send_to_port(port, buf->sg, sgl.n, sgl.len, buf, true);
 
 	if (unlikely(ret <= 0))
 		free_buf(buf, true);
 	return ret;
+
+error_out:
+	pipe_unlock(pipe);
+	return ret;
 }
 
 static unsigned int port_fops_poll(struct file *filp, poll_table *wait)

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH V2 0/2] [BUGFIX] virtio/console: Fix two bugs of splice_write
  2013-07-19  9:19 [PATCH V2 0/2] [BUGFIX] virtio/console: Fix two bugs of splice_write Yoshihiro YUNOMAE
  2013-07-19  9:19 ` [PATCH V2 1/2] [BUGFIX] virtio/console: Quit from splice_write if pipe->nrbufs is 0 Yoshihiro YUNOMAE
  2013-07-19  9:19 ` [PATCH V2 2/2] [BUGFIX] virtio/console: Add pipe_lock/unlock for splice_write Yoshihiro YUNOMAE
@ 2013-07-19 10:05 ` Amit Shah
  2013-07-22  1:05   ` Yoshihiro YUNOMAE
       [not found] ` <20130719091956.9698.30207.stgit@yunodevel>
  3 siblings, 1 reply; 7+ messages in thread
From: Amit Shah @ 2013-07-19 10:05 UTC (permalink / raw)
  To: Yoshihiro YUNOMAE
  Cc: Arnd Bergmann, Greg Kroah-Hartman, linux-kernel, stable,
	virtualization, Masami Hiramatsu, yrl.pp-manager.tt,
	Hidehiro Kawai

On (Fri) 19 Jul 2013 [18:19:51], Yoshihiro YUNOMAE wrote:
> Hi,
> 
> This patch set fixes two bugs of splice_write in the virtio-console driver.
> 
> [BUG1] Although pipe->nrbufs is empty, the driver tries to do splice_write.
>        => This induces oops in sg_init_table().
> 
> [BUG2] No lock for competition of splice_write.
>        => This induces oops in splice_from_pipe_feed() by bug of any user
>           application.
> 
> These reports are written in each patch.
> 
> Changes in V2:
> - Fix a locking problem for error
> 
> Thanks!

Reviewed-by: Amit Shah <amit.shah@redhat.com>

For the patches to be picked up in the stable trees, you need to
include CC: <stable@vger.kernel.org> in the sign-off area of the
patches, just cc'ing in the patch posting doesn't help.  See
Documentation/stable_kernel_rules.txt.

Can you submit a v3 with that change, and also add my reviewed-by
line?

		Amit

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH V2 1/2] [BUGFIX] virtio/console: Quit from splice_write if pipe->nrbufs is 0
  2013-07-19  9:19 ` [PATCH V2 1/2] [BUGFIX] virtio/console: Quit from splice_write if pipe->nrbufs is 0 Yoshihiro YUNOMAE
@ 2013-07-19 12:25   ` Masami Hiramatsu
  0 siblings, 0 replies; 7+ messages in thread
From: Masami Hiramatsu @ 2013-07-19 12:25 UTC (permalink / raw)
  To: Yoshihiro YUNOMAE
  Cc: Arnd Bergmann, Greg Kroah-Hartman, linux-kernel, stable,
	virtualization, Hidehiro Kawai, yrl.pp-manager.tt, Amit Shah

(2013/07/19 18:19), Yoshihiro YUNOMAE wrote:
> 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.

Thank you for fixing it :)

Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>

> 
> Signed-off-by: Yoshihiro YUNOMAE <yoshihiro.yunomae.ez@hitachi.com>
> Cc: Amit Shah <amit.shah@redhat.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
>  drivers/char/virtio_console.c |    7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
> index 1b456fe..8722656 100644
> --- a/drivers/char/virtio_console.c
> +++ b/drivers/char/virtio_console.c
> @@ -932,6 +932,13 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
>  	if (is_rproc_serial(port->out_vq->vdev))
>  		return -EINVAL;
>  
> +	/*
> +	 * pipe->nrbufs == 0 means there are no data to transfer,
> +	 * so this returns just 0 for no data.
> +	 */
> +	if (!pipe->nrbufs)
> +		return 0;
> +
>  	ret = wait_port_writable(port, filp->f_flags & O_NONBLOCK);
>  	if (ret < 0)
>  		return ret;
> 
> 


-- 
Masami HIRAMATSU
IT Management Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: masami.hiramatsu.pt@hitachi.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH V2 2/2] [BUGFIX] virtio/console: Add pipe_lock/unlock for splice_write
       [not found] ` <20130719091956.9698.30207.stgit@yunodevel>
@ 2013-07-19 12:26   ` Masami Hiramatsu
  0 siblings, 0 replies; 7+ messages in thread
From: Masami Hiramatsu @ 2013-07-19 12:26 UTC (permalink / raw)
  To: Yoshihiro YUNOMAE
  Cc: Arnd Bergmann, Greg Kroah-Hartman, linux-kernel, stable,
	virtualization, Hidehiro Kawai, yrl.pp-manager.tt, Amit Shah

(2013/07/19 18:19), Yoshihiro YUNOMAE wrote:
> 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

Thanks, this looks good for me.

Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>

> 
> Signed-off-by: Yoshihiro YUNOMAE <yoshihiro.yunomae.ez@hitachi.com>
> Cc: Amit Shah <amit.shah@redhat.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
>  drivers/char/virtio_console.c |   20 +++++++++++++++-----
>  1 file changed, 15 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
> index 8722656..8a15af3 100644
> --- a/drivers/char/virtio_console.c
> +++ b/drivers/char/virtio_console.c
> @@ -936,16 +936,21 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
>  	 * pipe->nrbufs == 0 means there are no data to transfer,
>  	 * so this returns just 0 for no data.
>  	 */
> -	if (!pipe->nrbufs)
> -		return 0;
> +	pipe_lock(pipe);
> +	if (!pipe->nrbufs) {
> +		ret = 0;
> +		goto error_out;
> +	}
>  
>  	ret = wait_port_writable(port, filp->f_flags & O_NONBLOCK);
>  	if (ret < 0)
> -		return ret;
> +		goto error_out;
>  
>  	buf = alloc_buf(port->out_vq, 0, pipe->nrbufs);
> -	if (!buf)
> -		return -ENOMEM;
> +	if (!buf) {
> +		ret = -ENOMEM;
> +		goto error_out;
> +	}
>  
>  	sgl.n = 0;
>  	sgl.len = 0;
> @@ -953,12 +958,17 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
>  	sgl.sg = buf->sg;
>  	sg_init_table(sgl.sg, sgl.size);
>  	ret = __splice_from_pipe(pipe, &sd, pipe_to_sg);
> +	pipe_unlock(pipe);
>  	if (likely(ret > 0))
>  		ret = __send_to_port(port, buf->sg, sgl.n, sgl.len, buf, true);
>  
>  	if (unlikely(ret <= 0))
>  		free_buf(buf, true);
>  	return ret;
> +
> +error_out:
> +	pipe_unlock(pipe);
> +	return ret;
>  }
>  
>  static unsigned int port_fops_poll(struct file *filp, poll_table *wait)
> 
> 


-- 
Masami HIRAMATSU
IT Management Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: masami.hiramatsu.pt@hitachi.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Re: [PATCH V2 0/2] [BUGFIX] virtio/console: Fix two bugs of splice_write
  2013-07-19 10:05 ` [PATCH V2 0/2] [BUGFIX] virtio/console: Fix two bugs of splice_write Amit Shah
@ 2013-07-22  1:05   ` Yoshihiro YUNOMAE
  0 siblings, 0 replies; 7+ messages in thread
From: Yoshihiro YUNOMAE @ 2013-07-22  1:05 UTC (permalink / raw)
  To: Amit Shah
  Cc: Arnd Bergmann, Greg Kroah-Hartman, linux-kernel, stable,
	virtualization, Masami Hiramatsu, yrl.pp-manager.tt,
	Hidehiro Kawai

Hi Amit,

Sorry for the late reply.

(2013/07/19 19:05), Amit Shah wrote:
> On (Fri) 19 Jul 2013 [18:19:51], Yoshihiro YUNOMAE wrote:
>> Hi,
>>
>> This patch set fixes two bugs of splice_write in the virtio-console driver.
>>
>> [BUG1] Although pipe->nrbufs is empty, the driver tries to do splice_write.
>>         => This induces oops in sg_init_table().
>>
>> [BUG2] No lock for competition of splice_write.
>>         => This induces oops in splice_from_pipe_feed() by bug of any user
>>            application.
>>
>> These reports are written in each patch.
>>
>> Changes in V2:
>> - Fix a locking problem for error
>>
>> Thanks!
>
> Reviewed-by: Amit Shah <amit.shah@redhat.com>

Thank you for reviewing this patch set.

> For the patches to be picked up in the stable trees, you need to
> include CC: <stable@vger.kernel.org> in the sign-off area of the
> patches, just cc'ing in the patch posting doesn't help.  See
> Documentation/stable_kernel_rules.txt.
>
> Can you submit a v3 with that change, and also add my reviewed-by
> line?

Sure. I'll add stable@ line, your reviewed-by line, and Masami's
reviewed-by line in sign-off area for each patch.

Thanks,
Yoshihiro YUNOMAE

-- 
Yoshihiro YUNOMAE
Software Platform Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: yoshihiro.yunomae.ez@hitachi.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2013-07-22  1:05 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-19  9:19 [PATCH V2 0/2] [BUGFIX] virtio/console: Fix two bugs of splice_write Yoshihiro YUNOMAE
2013-07-19  9:19 ` [PATCH V2 1/2] [BUGFIX] virtio/console: Quit from splice_write if pipe->nrbufs is 0 Yoshihiro YUNOMAE
2013-07-19 12:25   ` Masami Hiramatsu
2013-07-19  9:19 ` [PATCH V2 2/2] [BUGFIX] virtio/console: Add pipe_lock/unlock for splice_write Yoshihiro YUNOMAE
2013-07-19 10:05 ` [PATCH V2 0/2] [BUGFIX] virtio/console: Fix two bugs of splice_write Amit Shah
2013-07-22  1:05   ` Yoshihiro YUNOMAE
     [not found] ` <20130719091956.9698.30207.stgit@yunodevel>
2013-07-19 12:26   ` [PATCH V2 2/2] [BUGFIX] virtio/console: Add pipe_lock/unlock for splice_write Masami Hiramatsu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).