2020-04-05 20:14:59

by Andrew Melnichenko

[permalink] [raw]
Subject: [PATCH] Fix: buffer overflow during hvc_alloc().

From: Andrew Melnychenko <[email protected]>

If there is a lot(more then 16) of virtio-console devices
or virtio_console module is reloaded
- buffers 'vtermnos' and 'cons_ops' are overflowed.
In older kernels it overruns spinlock which leads to kernel freezing:
https://bugzilla.redhat.com/show_bug.cgi?id=1786239

Signed-off-by: Andrew Melnychenko <[email protected]>
---
drivers/tty/hvc/hvc_console.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index 27284a2dcd2b..436cc51c92c3 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -302,10 +302,6 @@ int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops)
vtermnos[index] = vtermno;
cons_ops[index] = ops;

- /* reserve all indices up to and including this index */
- if (last_hvc < index)
- last_hvc = index;
-
/* check if we need to re-register the kernel console */
hvc_check_console(index);

@@ -960,13 +956,22 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
cons_ops[i] == hp->ops)
break;

- /* no matching slot, just use a counter */
- if (i >= MAX_NR_HVC_CONSOLES)
- i = ++last_hvc;
+ if (i >= MAX_NR_HVC_CONSOLES) {
+
+ /* find 'empty' slot for console */
+ for (i = 0; i < MAX_NR_HVC_CONSOLES && vtermnos[i] != -1; i++) {
+ }
+
+ /* no matching slot, just use a counter */
+ if (i == MAX_NR_HVC_CONSOLES)
+ i = ++last_hvc + MAX_NR_HVC_CONSOLES;
+ }

hp->index = i;
- cons_ops[i] = ops;
- vtermnos[i] = vtermno;
+ if (i < MAX_NR_HVC_CONSOLES) {
+ cons_ops[i] = ops;
+ vtermnos[i] = vtermno;
+ }

list_add_tail(&(hp->next), &hvc_structs);
mutex_unlock(&hvc_structs_mutex);
--
2.24.1


2020-04-06 00:35:59

by Andrew Donnellan

[permalink] [raw]
Subject: Re: [PATCH] Fix: buffer overflow during hvc_alloc().

On 6/4/20 6:40 am, [email protected] wrote:
> From: Andrew Melnychenko <[email protected]>
>
> If there is a lot(more then 16) of virtio-console devices
> or virtio_console module is reloaded
> - buffers 'vtermnos' and 'cons_ops' are overflowed.
> In older kernels it overruns spinlock which leads to kernel freezing:
> https://bugzilla.redhat.com/show_bug.cgi?id=1786239
>

This Bugzilla report isn't publicly accessible. Can you include a
relevant summary here and/or make the report publicly viewable?

If it does indeed lead to a kernel freeze, this should be tagged with a
Fixes: and a Cc: [email protected].

--
Andrew Donnellan OzLabs, ADL Canberra
[email protected] IBM Australia Limited

2020-04-07 06:25:43

by Andrew Donnellan

[permalink] [raw]
Subject: Re: [PATCH] Fix: buffer overflow during hvc_alloc().

On 6/4/20 6:05 pm, Andrew Melnichenko wrote:
>
> Steps to Reproduce:
>
> 1. boot guest with command [1]
> 2. load and unload virtio_console inside guest with loop.sh
>    # cat loop.sh
>     while [ 1 ]
>     do
> modprobe virtio_console
> lsmod | grep virt
> modprobe -r virtio_console
> lsmod | grep virt
>     done
>
>
>
> Actual results:
> Guest reboot and can get vmcore-dmesg.txt file
>
>
> Expected results:
> Guest works well without error
>
>
> Additional info:
> The whole log will attach to the attachments.
>
> Call Trace:
> [   22.974500] fuse: init (API version 7.31)
> [   81.498208] ------------[ cut here ]------------
> [   81.499263] pvqspinlock: lock 0xffffffff92080020 has corrupted
> value 0xc0774ca0!
> [   81.501000] WARNING: CPU: 0 PID: 785 at
> kernel/locking/qspinlock_paravirt.h:500

[snip]

Thanks!

You should include an appropriate excerpt from this - the WARNING
message and stack trace, and the steps to reproduce - in the commit
message of the patch.


--
Andrew Donnellan OzLabs, ADL Canberra
[email protected] IBM Australia Limited