linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH] vgacon: fix out of bounds write to the scrollback buffer
       [not found] ` <b764c575-70be-80dd-6718-e84370a7b2b3@nsfocus.com>
@ 2020-07-30  6:46   ` Jiri Slaby
  2020-07-30  7:38     ` Jiri Slaby
  2020-07-30 10:39     ` 张云海
  0 siblings, 2 replies; 16+ messages in thread
From: Jiri Slaby @ 2020-07-30  6:46 UTC (permalink / raw)
  To: 张云海, Solar Designer
  Cc: b.zolnierkie, Yang Yingliang, Kyungtae Kim, Linus Torvalds,
	Greg KH, Srivatsa S. Bhat, Anthony Liguori, xiao.zhang,
	DRI devel, Linux Fbdev development list,
	Linux kernel mailing list

Hi, OTOH, you should have CCed all the (public) lists.

On 30. 07. 20, 4:50, 张云海 wrote:
> Zhang Xiao points out that the check should use > instead of >=,
> otherwise the last line will be skip.
> I agree with that, so I modify the patch.
> Could you please verify that it is still correct and sufficient?

IMO, yes, correct -- I was thinking about this yesterday too. Just an
example: hypothetically, if we had:
size_row = 1
tail = 29
size = 30

data[29] would be the last accessible member. Writing to data + tail (as
"29 + 1 > 30" doesn't hold, so the modified check would pass), i.e.
data[29] is still OK. So yes, > is OK, >= would waste space and would be
actually incorrect.

> BTW, Zhang Xiao also points out that the check after the memcpy can be
> remove.
> I also think that was right, but vgacon_scrollback_cur->tail may keep
> the value vgacon_scrollback_cur->size in some case. That is not a
> problem in vgacon_scrollback_update because of the check before the
> memcpy. However, that may break some other code which assumes that
> vgacon_scrollback_cur->tail won't be vgacon_scrollback_cur->size. I do
> not know if there are such code, and if it is the code actually  should
> check it too. But I still not remove the check in the patch to make sure
> it won't breaks other code.

As I wrote about this yesterday:
===
I am also not sure the test I was pointing out on the top of this
message would be of any use after the change. But maybe leave the code
rest in peace.
===

I would let it as is in this particular code. Especially because
vgacon_scrolldelta takes ->tail into consideration and I was too lazy to
study the code there. But if you are willing to study the code there and
confirm the check is superfluous, feel free to remove it. Perhaps in a
separate patch. I was actually testing with the check removed and didn't
hit any issue (which means, in fact, exactly nothing).

> From ad143ede24ff4e61292cc9c96000100aacd97259 Mon Sep 17 00:00:00 2001
> From: Yunhai Zhang <zhangyunhai@nsfocus.com>
> Date: Tue, 28 Jul 2020 09:58:03 +0800
> Subject: [PATCH] Fix for missing check in vgacon scrollback handling
> 
> vgacon_scrollback_update() always left enbough room in the scrollback

"leaves enough"

> buffer for the next call, but if the console size changed that room
> might not actually be enough, and so we need to re-check.

Also, could you add reasoning why you are adding the check to the loop
and not outside (for instance, use your reasoning with numbers or CSI M
as an example).

Could you add a sample output here, something like I had:
===
    This leads to random crashes or KASAN reports like:
    BUG: KASAN: slab-out-of-bounds in vgacon_scroll+0x57a/0x8ed
===

It's then easier to google for when this happens to someone who runs
non-patched kernels.

> This fixes CVE-2020-14331.
> 
> Reported-and-debugged-by: 张云海 <zhangyunhai@nsfocus.com>
> Reported-and-debugged-by: Yang Yingliang <yangyingliang@huawei.com>
> Reported-by: Kyungtae Kim <kt0755@gmail.com>
> Fixes: 15bdab959c9b ([PATCH] vgacon: Add support for soft scrollback)
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Cc: Greg KH <greg@kroah.com>
> Cc: Solar Designer <solar@openwall.com>
> Cc: "Srivatsa S. Bhat" <srivatsa@csail.mit.edu>
> Cc: Anthony Liguori <aliguori@amazon.com>
> Cc: Yang Yingliang <yangyingliang@huawei.com>
> Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>

Oh, and we should:
Cc: stable@vger.kernel.org

> Signed-off-by: Yunhai Zhang <zhangyunhai@nsfocus.com>
> ---
>  drivers/video/console/vgacon.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
> index 998b0de1812f..37b5711cd958 100644
> --- a/drivers/video/console/vgacon.c
> +++ b/drivers/video/console/vgacon.c
> @@ -251,6 +251,10 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
>  	p = (void *) (c->vc_origin + t * c->vc_size_row);
>  
>  	while (count--) {
> +		if ((vgacon_scrollback_cur->tail + c->vc_size_row) > 
> +		    vgacon_scrollback_cur->size)
> +			vgacon_scrollback_cur->tail = 0;
> +
>  		scr_memcpyw(vgacon_scrollback_cur->data +
>  			    vgacon_scrollback_cur->tail,
>  			    p, c->vc_size_row);

thanks,
-- 
js
suse labs

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

* Re: [PATCH] vgacon: fix out of bounds write to the scrollback buffer
  2020-07-30  6:46   ` [PATCH] vgacon: fix out of bounds write to the scrollback buffer Jiri Slaby
@ 2020-07-30  7:38     ` Jiri Slaby
  2020-07-30 10:39     ` 张云海
  1 sibling, 0 replies; 16+ messages in thread
From: Jiri Slaby @ 2020-07-30  7:38 UTC (permalink / raw)
  To: 张云海, Solar Designer
  Cc: b.zolnierkie, Yang Yingliang, Kyungtae Kim, Linus Torvalds,
	Greg KH, Srivatsa S. Bhat, Anthony Liguori, xiao.zhang,
	DRI devel, Linux Fbdev development list,
	Linux kernel mailing list

On 30. 07. 20, 8:46, Jiri Slaby wrote:
> Hi, OTOH, you should have CCed all the (public) lists.
> 
> On 30. 07. 20, 4:50, 张云海 wrote:
>> Zhang Xiao points out that the check should use > instead of >=,
>> otherwise the last line will be skip.
>> I agree with that, so I modify the patch.
>> Could you please verify that it is still correct and sufficient?
> 
> IMO, yes, correct -- I was thinking about this yesterday too. Just an
> example: hypothetically, if we had:
> size_row = 1
> tail = 29
> size = 30
> 
> data[29] would be the last accessible member. Writing to data + tail (as
> "29 + 1 > 30" doesn't hold, so the modified check would pass), i.e.
> data[29] is still OK. So yes, > is OK, >= would waste space and would be
> actually incorrect.
> 
>> BTW, Zhang Xiao also points out that the check after the memcpy can be
>> remove.
>> I also think that was right, but vgacon_scrollback_cur->tail may keep
>> the value vgacon_scrollback_cur->size in some case. That is not a
>> problem in vgacon_scrollback_update because of the check before the
>> memcpy. However, that may break some other code which assumes that
>> vgacon_scrollback_cur->tail won't be vgacon_scrollback_cur->size. I do
>> not know if there are such code, and if it is the code actually  should
>> check it too. But I still not remove the check in the patch to make sure
>> it won't breaks other code.
> 
> As I wrote about this yesterday:
> ===
> I am also not sure the test I was pointing out on the top of this
> message would be of any use after the change. But maybe leave the code
> rest in peace.
> ===
> 
> I would let it as is in this particular code. Especially because
> vgacon_scrolldelta takes ->tail into consideration and I was too lazy to
> study the code there. But if you are willing to study the code there and
> confirm the check is superfluous, feel free to remove it. Perhaps in a
> separate patch. I was actually testing with the check removed and didn't
> hit any issue (which means, in fact, exactly nothing).
> 
>> From ad143ede24ff4e61292cc9c96000100aacd97259 Mon Sep 17 00:00:00 2001
>> From: Yunhai Zhang <zhangyunhai@nsfocus.com>
>> Date: Tue, 28 Jul 2020 09:58:03 +0800
>> Subject: [PATCH] Fix for missing check in vgacon scrollback handling
>>
>> vgacon_scrollback_update() always left enbough room in the scrollback
> 
> "leaves enough"
> 
>> buffer for the next call, but if the console size changed that room
>> might not actually be enough, and so we need to re-check.
> 
> Also, could you add reasoning why you are adding the check to the loop
> and not outside (for instance, use your reasoning with numbers or CSI M
> as an example).
> 
> Could you add a sample output here, something like I had:
> ===
>     This leads to random crashes or KASAN reports like:
>     BUG: KASAN: slab-out-of-bounds in vgacon_scroll+0x57a/0x8ed
> ===
> 
> It's then easier to google for when this happens to someone who runs
> non-patched kernels.
> 
>> This fixes CVE-2020-14331.
>>
>> Reported-and-debugged-by: 张云海 <zhangyunhai@nsfocus.com>
>> Reported-and-debugged-by: Yang Yingliang <yangyingliang@huawei.com>
>> Reported-by: Kyungtae Kim <kt0755@gmail.com>
>> Fixes: 15bdab959c9b ([PATCH] vgacon: Add support for soft scrollback)
>> Cc: Linus Torvalds <torvalds@linux-foundation.org>
>> Cc: Greg KH <greg@kroah.com>
>> Cc: Solar Designer <solar@openwall.com>
>> Cc: "Srivatsa S. Bhat" <srivatsa@csail.mit.edu>
>> Cc: Anthony Liguori <aliguori@amazon.com>
>> Cc: Yang Yingliang <yangyingliang@huawei.com>
>> Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> 
> Oh, and we should:
> Cc: stable@vger.kernel.org
> 
>> Signed-off-by: Yunhai Zhang <zhangyunhai@nsfocus.com>
>> ---
>>  drivers/video/console/vgacon.c | 4 ++++
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
>> index 998b0de1812f..37b5711cd958 100644
>> --- a/drivers/video/console/vgacon.c
>> +++ b/drivers/video/console/vgacon.c
>> @@ -251,6 +251,10 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
>>  	p = (void *) (c->vc_origin + t * c->vc_size_row);
>>  
>>  	while (count--) {
>> +		if ((vgacon_scrollback_cur->tail + c->vc_size_row) > 

And git complains here:
.git/rebase-apply/patch:13: trailing whitespace.
                if ((vgacon_scrollback_cur->tail + c->vc_size_row) >
warning: 1 line adds whitespace errors.

There is a space at the EOL.

>> +		    vgacon_scrollback_cur->size)
>> +			vgacon_scrollback_cur->tail = 0;
>> +
>>  		scr_memcpyw(vgacon_scrollback_cur->data +
>>  			    vgacon_scrollback_cur->tail,
>>  			    p, c->vc_size_row);
> 
> thanks,
> 


-- 
js

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

* Re: [PATCH] vgacon: fix out of bounds write to the scrollback buffer
  2020-07-30  6:46   ` [PATCH] vgacon: fix out of bounds write to the scrollback buffer Jiri Slaby
  2020-07-30  7:38     ` Jiri Slaby
@ 2020-07-30 10:39     ` 张云海
  2020-07-31  5:22       ` 张云海
  1 sibling, 1 reply; 16+ messages in thread
From: 张云海 @ 2020-07-30 10:39 UTC (permalink / raw)
  To: Jiri Slaby, Solar Designer
  Cc: b.zolnierkie, Yang Yingliang, Kyungtae Kim, Linus Torvalds,
	Greg KH, Srivatsa S. Bhat, Anthony Liguori, xiao.zhang,
	DRI devel, Linux Fbdev development list,
	Linux kernel mailing list

[-- Attachment #1: Type: text/plain, Size: 159 bytes --]

Update the patch, add CC list, sample output, and Jiri's PoC.

On 2020/7/30 14:46, Jiri Slaby wrote:
> Hi, OTOH, you should have CCed all the (public) lists.


[-- Attachment #2: 0001-Fix-for-missing-check-in-vgacon-scrollback-handling.patch --]
[-- Type: text/plain, Size: 2823 bytes --]

From ad143ede24ff4e61292cc9c96000100aacd97259 Mon Sep 17 00:00:00 2001
From: Yunhai Zhang <zhangyunhai@nsfocus.com>
Date: Tue, 28 Jul 2020 09:58:03 +0800
Subject: [PATCH] Fix for missing check in vgacon scrollback handling

vgacon_scrollback_update() always leaves enbough room in the scrollback
buffer for the next call, but if the console size changed that room
might not actually be enough, and so we need to re-check.

The check should be in the loop since vgacon_scrollback_cur->tail is
updated in the loop and count may be more than 1 when triggered by CSI M,
as Jiri's PoC:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>

int main(int argc, char** argv)
{
        int fd = open("/dev/tty1", O_RDWR);
        unsigned short size[3] = {25, 200, 0};
        ioctl(fd, 0x5609, size); // VT_RESIZE

        write(fd, "\e[1;1H", 6);
        for (int i = 0; i < 30; i++)
                write(fd, "\e[10M", 5);
}

It leads to various crashes as vgacon_scrollback_update writes out of
the buffer:
 BUG: unable to handle page fault for address: ffffc900001752a0
 #PF: supervisor write access in kernel mode
 #PF: error_code(0x0002) - not-present page
 RIP: 0010:mutex_unlock+0x13/0x30
...
 Call Trace:
  n_tty_write+0x1a0/0x4d0
  tty_write+0x1a0/0x2e0

Or to KASAN reports:
BUG: KASAN: slab-out-of-bounds in vgacon_scroll+0x57a/0x8ed

This fixes CVE-2020-14331.

Reported-and-debugged-by: 张云海 <zhangyunhai@nsfocus.com>
Reported-and-debugged-by: Yang Yingliang <yangyingliang@huawei.com>
Reported-by: Kyungtae Kim <kt0755@gmail.com>
Fixes: 15bdab959c9b ([PATCH] vgacon: Add support for soft scrollback)
Cc: stable@vger.kernel.org
Cc: linux-fbdev@vger.kernel.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Greg KH <greg@kroah.com>
Cc: Solar Designer <solar@openwall.com>
Cc: "Srivatsa S. Bhat" <srivatsa@csail.mit.edu>
Cc: Anthony Liguori <aliguori@amazon.com>
Cc: Yang Yingliang <yangyingliang@huawei.com>
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Signed-off-by: Yunhai Zhang <zhangyunhai@nsfocus.com>
---
 drivers/video/console/vgacon.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 998b0de1812f..37b5711cd958 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -251,6 +251,10 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
 	p = (void *) (c->vc_origin + t * c->vc_size_row);
 
 	while (count--) {
+		if ((vgacon_scrollback_cur->tail + c->vc_size_row) > 
+		    vgacon_scrollback_cur->size)
+			vgacon_scrollback_cur->tail = 0;
+
 		scr_memcpyw(vgacon_scrollback_cur->data +
 			    vgacon_scrollback_cur->tail,
 			    p, c->vc_size_row);
-- 
2.25.1

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

* Re: [PATCH] vgacon: fix out of bounds write to the scrollback buffer
  2020-07-30 10:39     ` 张云海
@ 2020-07-31  5:22       ` 张云海
  2020-08-03  8:08         ` Jiri Slaby
  0 siblings, 1 reply; 16+ messages in thread
From: 张云海 @ 2020-07-31  5:22 UTC (permalink / raw)
  To: Jiri Slaby, Solar Designer
  Cc: b.zolnierkie, Yang Yingliang, Kyungtae Kim, Linus Torvalds,
	Greg KH, Srivatsa S. Bhat, Anthony Liguori, xiao.zhang,
	DRI devel, Linux Fbdev development list,
	Linux kernel mailing list

[-- Attachment #1: Type: text/plain, Size: 229 bytes --]

Remove whitespace at EOL

On 2020/7/30 18:39, 张云海 wrote:
> Update the patch, add CC list, sample output, and Jiri's PoC.
> 
> On 2020/7/30 14:46, Jiri Slaby wrote:
>> Hi, OTOH, you should have CCed all the (public) lists.
> 


[-- Attachment #2: 0001-Fix-for-missing-check-in-vgacon-scrollback-handling.patch --]
[-- Type: text/plain, Size: 2823 bytes --]

From ad143ede24ff4e61292cc9c96000100aacd97259 Mon Sep 17 00:00:00 2001
From: Yunhai Zhang <zhangyunhai@nsfocus.com>
Date: Tue, 28 Jul 2020 09:58:03 +0800
Subject: [PATCH] Fix for missing check in vgacon scrollback handling

vgacon_scrollback_update() always leaves enbough room in the scrollback
buffer for the next call, but if the console size changed that room
might not actually be enough, and so we need to re-check.

The check should be in the loop since vgacon_scrollback_cur->tail is
updated in the loop and count may be more than 1 when triggered by CSI M,
as Jiri's PoC:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>

int main(int argc, char** argv)
{
        int fd = open("/dev/tty1", O_RDWR);
        unsigned short size[3] = {25, 200, 0};
        ioctl(fd, 0x5609, size); // VT_RESIZE

        write(fd, "\e[1;1H", 6);
        for (int i = 0; i < 30; i++)
                write(fd, "\e[10M", 5);
}

It leads to various crashes as vgacon_scrollback_update writes out of
the buffer:
 BUG: unable to handle page fault for address: ffffc900001752a0
 #PF: supervisor write access in kernel mode
 #PF: error_code(0x0002) - not-present page
 RIP: 0010:mutex_unlock+0x13/0x30
...
 Call Trace:
  n_tty_write+0x1a0/0x4d0
  tty_write+0x1a0/0x2e0

Or to KASAN reports:
BUG: KASAN: slab-out-of-bounds in vgacon_scroll+0x57a/0x8ed

This fixes CVE-2020-14331.

Reported-and-debugged-by: 张云海 <zhangyunhai@nsfocus.com>
Reported-and-debugged-by: Yang Yingliang <yangyingliang@huawei.com>
Reported-by: Kyungtae Kim <kt0755@gmail.com>
Fixes: 15bdab959c9b ([PATCH] vgacon: Add support for soft scrollback)
Cc: stable@vger.kernel.org
Cc: linux-fbdev@vger.kernel.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Greg KH <greg@kroah.com>
Cc: Solar Designer <solar@openwall.com>
Cc: "Srivatsa S. Bhat" <srivatsa@csail.mit.edu>
Cc: Anthony Liguori <aliguori@amazon.com>
Cc: Yang Yingliang <yangyingliang@huawei.com>
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Signed-off-by: Yunhai Zhang <zhangyunhai@nsfocus.com>
---
 drivers/video/console/vgacon.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 998b0de1812f..37b5711cd958 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -251,6 +251,10 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
 	p = (void *) (c->vc_origin + t * c->vc_size_row);
 
 	while (count--) {
+		if ((vgacon_scrollback_cur->tail + c->vc_size_row) >
+		    vgacon_scrollback_cur->size)
+			vgacon_scrollback_cur->tail = 0;
+
 		scr_memcpyw(vgacon_scrollback_cur->data +
 			    vgacon_scrollback_cur->tail,
 			    p, c->vc_size_row);
-- 
2.25.1


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

* Re: [PATCH] vgacon: fix out of bounds write to the scrollback buffer
  2020-07-31  5:22       ` 张云海
@ 2020-08-03  8:08         ` Jiri Slaby
  2020-08-03  8:18           ` Greg KH
  2020-08-04  7:37           ` Greg KH
  0 siblings, 2 replies; 16+ messages in thread
From: Jiri Slaby @ 2020-08-03  8:08 UTC (permalink / raw)
  To: 张云海, Solar Designer
  Cc: b.zolnierkie, Yang Yingliang, Kyungtae Kim, Linus Torvalds,
	Greg KH, Srivatsa S. Bhat, Anthony Liguori, xiao.zhang,
	DRI devel, Linux Fbdev development list,
	Linux kernel mailing list

Hi,

On 31. 07. 20, 7:22, 张云海 wrote:
> Remove whitespace at EOL

I am fine with the patch. However it should be sent properly (inline
mail, having a PATCH subject etc. -- see
Documentation/process/submitting-patches.rst). git send-email after git
format-patch handles most of it.

There is also question who is willing to take it?

Bart? Greg? Should we route it via akpm, or will you Linus directly? (I
can sign off and resend the patch which was attached to the mail I am
replying to too, if need be.)

thanks,
-- 
js
suse labs

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

* Re: [PATCH] vgacon: fix out of bounds write to the scrollback buffer
  2020-08-03  8:08         ` Jiri Slaby
@ 2020-08-03  8:18           ` Greg KH
  2020-08-03  8:45             ` Daniel Vetter
  2020-08-04  7:37           ` Greg KH
  1 sibling, 1 reply; 16+ messages in thread
From: Greg KH @ 2020-08-03  8:18 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: 张云海,
	Solar Designer, b.zolnierkie, Yang Yingliang, Kyungtae Kim,
	Linus Torvalds, Srivatsa S. Bhat, Anthony Liguori, xiao.zhang,
	DRI devel, Linux Fbdev development list,
	Linux kernel mailing list

On Mon, Aug 03, 2020 at 10:08:43AM +0200, Jiri Slaby wrote:
> Hi,
> 
> On 31. 07. 20, 7:22, 张云海 wrote:
> > Remove whitespace at EOL
> 
> I am fine with the patch. However it should be sent properly (inline
> mail, having a PATCH subject etc. -- see
> Documentation/process/submitting-patches.rst). git send-email after git
> format-patch handles most of it.
> 
> There is also question who is willing to take it?
> 
> Bart? Greg? Should we route it via akpm, or will you Linus directly? (I
> can sign off and resend the patch which was attached to the mail I am
> replying to too, if need be.)

I can take it, if Bart can't, just let me know.

thanks,

greg k-h

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

* Re: [PATCH] vgacon: fix out of bounds write to the scrollback buffer
  2020-08-03  8:18           ` Greg KH
@ 2020-08-03  8:45             ` Daniel Vetter
  2020-08-03  9:47               ` Greg KH
  0 siblings, 1 reply; 16+ messages in thread
From: Daniel Vetter @ 2020-08-03  8:45 UTC (permalink / raw)
  To: Greg KH
  Cc: Jiri Slaby, Linux Fbdev development list, Kyungtae Kim,
	Anthony Liguori, Bartlomiej Zolnierkiewicz,
	Linux kernel mailing list, DRI devel, Srivatsa S. Bhat,
	Solar Designer, Yang Yingliang, xiao.zhang, Linus Torvalds,
	张云海

On Mon, Aug 3, 2020 at 10:26 AM Greg KH <greg@kroah.com> wrote:
>
> On Mon, Aug 03, 2020 at 10:08:43AM +0200, Jiri Slaby wrote:
> > Hi,
> >
> > On 31. 07. 20, 7:22, 张云海 wrote:
> > > Remove whitespace at EOL
> >
> > I am fine with the patch. However it should be sent properly (inline
> > mail, having a PATCH subject etc. -- see
> > Documentation/process/submitting-patches.rst). git send-email after git
> > format-patch handles most of it.
> >
> > There is also question who is willing to take it?
> >
> > Bart? Greg? Should we route it via akpm, or will you Linus directly? (I
> > can sign off and resend the patch which was attached to the mail I am
> > replying to too, if need be.)
>
> I can take it, if Bart can't, just let me know.

Yeah vt stuff and console drivers != fbcon go through Greg's tree past
few years ...

Greg, should we maybe add a MAINTAINERS entry that matches on all
things console? With tty/vt you definitely have the other side of that
coin already :-)
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

* Re: [PATCH] vgacon: fix out of bounds write to the scrollback buffer
  2020-08-03  8:45             ` Daniel Vetter
@ 2020-08-03  9:47               ` Greg KH
  2020-08-03 11:07                 ` Bartlomiej Zolnierkiewicz
  0 siblings, 1 reply; 16+ messages in thread
From: Greg KH @ 2020-08-03  9:47 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Jiri Slaby, Linux Fbdev development list, Kyungtae Kim,
	Anthony Liguori, Bartlomiej Zolnierkiewicz,
	Linux kernel mailing list, DRI devel, Srivatsa S. Bhat,
	Solar Designer, Yang Yingliang, xiao.zhang, Linus Torvalds,
	张云海

On Mon, Aug 03, 2020 at 10:45:07AM +0200, Daniel Vetter wrote:
> On Mon, Aug 3, 2020 at 10:26 AM Greg KH <greg@kroah.com> wrote:
> >
> > On Mon, Aug 03, 2020 at 10:08:43AM +0200, Jiri Slaby wrote:
> > > Hi,
> > >
> > > On 31. 07. 20, 7:22, 张云海 wrote:
> > > > Remove whitespace at EOL
> > >
> > > I am fine with the patch. However it should be sent properly (inline
> > > mail, having a PATCH subject etc. -- see
> > > Documentation/process/submitting-patches.rst). git send-email after git
> > > format-patch handles most of it.
> > >
> > > There is also question who is willing to take it?
> > >
> > > Bart? Greg? Should we route it via akpm, or will you Linus directly? (I
> > > can sign off and resend the patch which was attached to the mail I am
> > > replying to too, if need be.)
> >
> > I can take it, if Bart can't, just let me know.
> 
> Yeah vt stuff and console drivers != fbcon go through Greg's tree past
> few years ...
> 
> Greg, should we maybe add a MAINTAINERS entry that matches on all
> things console? With tty/vt you definitely have the other side of that
> coin already :-)

Sure, that would be good as things do fall through the cracks at times.

If you write the patch, I'll merge it :)

greg k-h

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

* Re: [PATCH] vgacon: fix out of bounds write to the scrollback buffer
  2020-08-03  9:47               ` Greg KH
@ 2020-08-03 11:07                 ` Bartlomiej Zolnierkiewicz
  0 siblings, 0 replies; 16+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2020-08-03 11:07 UTC (permalink / raw)
  To: Greg KH
  Cc: Daniel Vetter, Jiri Slaby, Linux Fbdev development list,
	Kyungtae Kim, Anthony Liguori, Linux kernel mailing list,
	DRI devel, Srivatsa S. Bhat, Solar Designer, Yang Yingliang,
	xiao.zhang, Linus Torvalds, 张云海


On 8/3/20 11:47 AM, Greg KH wrote:
> On Mon, Aug 03, 2020 at 10:45:07AM +0200, Daniel Vetter wrote:
>> On Mon, Aug 3, 2020 at 10:26 AM Greg KH <greg@kroah.com> wrote:
>>>
>>> On Mon, Aug 03, 2020 at 10:08:43AM +0200, Jiri Slaby wrote:
>>>> Hi,
>>>>
>>>> On 31. 07. 20, 7:22, 张云海 wrote:
>>>>> Remove whitespace at EOL
>>>>
>>>> I am fine with the patch. However it should be sent properly (inline
>>>> mail, having a PATCH subject etc. -- see
>>>> Documentation/process/submitting-patches.rst). git send-email after git
>>>> format-patch handles most of it.
>>>>
>>>> There is also question who is willing to take it?
>>>>
>>>> Bart? Greg? Should we route it via akpm, or will you Linus directly? (I
>>>> can sign off and resend the patch which was attached to the mail I am
>>>> replying to too, if need be.)
>>>
>>> I can take it, if Bart can't, just let me know.
>>
>> Yeah vt stuff and console drivers != fbcon go through Greg's tree past
>> few years ...
>>
>> Greg, should we maybe add a MAINTAINERS entry that matches on all
>> things console? With tty/vt you definitely have the other side of that
>> coin already :-)
> 
> Sure, that would be good as things do fall through the cracks at times.

Since taking over fbdev in 2017 I've tried to act as the last resort
Maintainer for console stuff (AFAIK there are no "lost" patches) but
it really deserves its own entry.

Also most console patches make it through you nowadays anyway:

$ git log --pretty=fuller --since=2017 drivers/video/console/|grep "Commit\:"|sort|uniq -cd
      2 Commit:     Arnd Bergmann <arnd@arndb.de>
     11 Commit:     Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
      2 Commit:     Daniel Vetter <daniel.vetter@ffwll.ch>
      3 Commit:     Dave Airlie <airlied@redhat.com>
     12 Commit:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      7 Commit:     Linus Torvalds <torvalds@linux-foundation.org>
      2 Commit:     Martin Schwidefsky <schwidefsky@de.ibm.com>

> If you write the patch, I'll merge it :)
ACK from me. :)

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics

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

* Re: [PATCH] vgacon: fix out of bounds write to the scrollback buffer
  2020-08-03  8:08         ` Jiri Slaby
  2020-08-03  8:18           ` Greg KH
@ 2020-08-04  7:37           ` Greg KH
  1 sibling, 0 replies; 16+ messages in thread
From: Greg KH @ 2020-08-04  7:37 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: 张云海,
	Solar Designer, b.zolnierkie, Yang Yingliang, Kyungtae Kim,
	Linus Torvalds, Srivatsa S. Bhat, Anthony Liguori, xiao.zhang,
	DRI devel, Linux Fbdev development list,
	Linux kernel mailing list

On Mon, Aug 03, 2020 at 10:08:43AM +0200, Jiri Slaby wrote:
> Hi,
> 
> On 31. 07. 20, 7:22, 张云海 wrote:
> > Remove whitespace at EOL
> 
> I am fine with the patch. However it should be sent properly (inline
> mail, having a PATCH subject etc. -- see
> Documentation/process/submitting-patches.rst). git send-email after git
> format-patch handles most of it.

I'll go fix this all up now "by hand" :(


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

* Re: [PATCH] vgacon: fix out of bounds write to the scrollback buffer
  2020-07-29  7:02 ` Jiri Slaby
  2020-07-29  7:53   ` 张云海
@ 2020-07-29 13:37   ` Bartlomiej Zolnierkiewicz
  1 sibling, 0 replies; 16+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2020-07-29 13:37 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: linux-kernel, 张云海,
	Yang Yingliang, Kyungtae Kim, Linus Torvalds, Greg KH,
	Solar Designer, Srivatsa S. Bhat, Anthony Liguori,
	Security Officers, linux-distros, dri-devel, linux-fbdev


Hi Jiri,

On 7/29/20 9:02 AM, Jiri Slaby wrote:
> The current vgacon's scroll up implementation uses a circural buffer
> in vgacon_scrollback_cur. It always advances tail to prepare it for the
> next write and caps it to zero if the next ->vc_size_row bytes won't fit.
> 
> But when we change the VT size (e.g. by VT_RESIZE) in the meantime, the new
> line might not fit to the end of the scrollback buffer in the next
> attempt to scroll. This leads to various crashes as
> vgacon_scrollback_update writes out of the buffer:
>  BUG: unable to handle page fault for address: ffffc900001752a0
>  #PF: supervisor write access in kernel mode
>  #PF: error_code(0x0002) - not-present page
>  RIP: 0010:mutex_unlock+0x13/0x30
> ...
>  Call Trace:
>   n_tty_write+0x1a0/0x4d0
>   tty_write+0x1a0/0x2e0
> 
> Or to KASAN reports:
> BUG: KASAN: slab-out-of-bounds in vgacon_scroll+0x57a/0x8ed
> 
> So check whether the line fits in the buffer and wrap if needed. Do it
> before the loop as console_sem is held and ->vc_size_row cannot change
> during the execution of vgacon_scrollback_cur. If it does change, we
> need to ensure it does not change elsewhere, not here.
> 
> Also, we do not split the write of a line into chunks as that would
> break the consumers of the buffer. They expect ->cnt, ->tail and ->size
> to be in harmony and advanced by ->vc_size_row.
> 
> I found few reports of this in the past, some with patches included,
> some even 2 years old:
> https://lore.kernel.org/lkml/CAEAjamsJnG-=TSOwgRbbb3B9Z-PA63oWmNPoKYWQ=Z=+X49akg@mail.gmail.com/

Sorry but I don't work on fixing fbdev/console KASAN/syzbot/etc.
reports (-ENORESOURCES).  This has been made official in the past.

I'm happy to review/apply patches though.

> https://lore.kernel.org/lkml/1589336932-35508-1-git-send-email-yangyingliang@huawei.com/

This was the first time the patch for issue was submitted.

I tried to apply it to drm-misc but then I have noticed that
it has not been posted to linux-fbdev / dri-devel MLs (so it
was not possible to merge it using dim tool) and thus I've
requested the author to resend it:

https://lore.kernel.org/lkml/62544bd9-e47d-e7f9-92f2-49b8dbb132c1@samsung.com/

which he did:

https://lore.kernel.org/lkml/20200713105730.550334-1-yangyingliang@huawei.com/

and the patch is currently under review period (to give people
chance to comment on it) and in my "to apply if no objections"
folder.

I see that your/Yunhai patch addresses the root source of
the issue so I'll be happy to apply/ACK it instead of Yang's
patch once the final version is posted.

Thank you for working on this.

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics

> This fixes CVE-2020-14331.
> 
> Big thanks to guys mentioned in the Reported-and-debugged-by lines below
> who actually found the root cause.
> 
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> Reported-and-debugged-by: 张云海 <zhangyunhai@nsfocus.com>
> Reported-and-debugged-by: Yang Yingliang <yangyingliang@huawei.com>
> Reported-by: Kyungtae Kim <kt0755@gmail.com>
> Fixes: 15bdab959c9b ([PATCH] vgacon: Add support for soft scrollback)
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Cc: Greg KH <greg@kroah.com>
> Cc: Solar Designer <solar@openwall.com>
> Cc: "Srivatsa S. Bhat" <srivatsa@csail.mit.edu>
> Cc: Anthony Liguori <aliguori@amazon.com>
> Cc: Security Officers <security@kernel.org>
> Cc: linux-distros@vs.openwall.org
> Cc: Yang Yingliang <yangyingliang@huawei.com>
> Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-fbdev@vger.kernel.org
> ---
>  drivers/video/console/vgacon.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
> index f0f3d573f848..13194bb246f8 100644
> --- a/drivers/video/console/vgacon.c
> +++ b/drivers/video/console/vgacon.c
> @@ -250,6 +250,11 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
>  
>  	p = (void *) (c->vc_origin + t * c->vc_size_row);
>  
> +	/* vc_size_row might have changed by VT_RESIZE in the meantime */
> +	if ((vgacon_scrollback_cur->tail + c->vc_size_row) >=
> +			vgacon_scrollback_cur->size)
> +		vgacon_scrollback_cur->tail = 0;
> +
>  	while (count--) {
>  		scr_memcpyw(vgacon_scrollback_cur->data +
>  			    vgacon_scrollback_cur->tail,
> 

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

* Re: [PATCH] vgacon: fix out of bounds write to the scrollback buffer
  2020-07-29  8:19       ` 张云海
@ 2020-07-29 11:20         ` Jiri Slaby
  0 siblings, 0 replies; 16+ messages in thread
From: Jiri Slaby @ 2020-07-29 11:20 UTC (permalink / raw)
  To: 张云海, b.zolnierkie
  Cc: linux-kernel, Yang Yingliang, Kyungtae Kim, Linus Torvalds,
	Greg KH, Solar Designer, Srivatsa S. Bhat, Anthony Liguori,
	Security Officers, linux-distros, dri-devel, linux-fbdev

On 29. 07. 20, 10:19, 张云海 wrote:
> On 2020/7/29 16:11, Jiri Slaby wrote:
>> But the loop checks for the overflow:
>>   if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size)
>>         vgacon_scrollback_cur->tail = 0;
>>
>> So the first 2 iterations would write to the end of the buffer and this
>> 3rd one should have zeroed ->tail.
> 
> In the 2nd  iteration before the check:
> vgacon_scrollback_cur->tail is 65360 which is still less then
> vgacon_scrollback_cur->size(65440), so the ->tail won't be zeroed.
> 
> Then it gose to the 3rd  iteration, overflow occurs.

Ahh, I see now! So it must be triggered by CSI M instead. It allows for
more than 1 in count. So this is PoC for this case:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>

int main(int argc, char** argv)
{
        int fd = open("/dev/tty1", O_RDWR);
        unsigned short size[3] = {25, 200, 0};
        ioctl(fd, 0x5609, size); // VT_RESIZE

        write(fd, "\e[1;1H", 6);
        for (int i = 0; i < 30; i++)
                write(fd, "\e[10M", 5);
}

It corrupts memory, so it crashes the kernel randomly. Even with my
before-loop patch.

So now: could you resend your patch with improved commit message, add
all those Ccs etc.? You can copy most of the Ccs from my patch verbatim.

I am also not sure the test I was pointing out on the top of this
message would be of any use after the change. But maybe leave the code
rest in peace.

thanks,
-- 
js
suse labs

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

* Re: [PATCH] vgacon: fix out of bounds write to the scrollback buffer
  2020-07-29  8:11     ` Jiri Slaby
@ 2020-07-29  8:19       ` 张云海
  2020-07-29 11:20         ` Jiri Slaby
  0 siblings, 1 reply; 16+ messages in thread
From: 张云海 @ 2020-07-29  8:19 UTC (permalink / raw)
  To: Jiri Slaby, b.zolnierkie
  Cc: linux-kernel, Yang Yingliang, Kyungtae Kim, Linus Torvalds,
	Greg KH, Solar Designer, Srivatsa S. Bhat, Anthony Liguori,
	Security Officers, linux-distros, dri-devel, linux-fbdev

On 2020/7/29 16:11, Jiri Slaby wrote:
> But the loop checks for the overflow:
>   if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size)
>         vgacon_scrollback_cur->tail = 0;
> 
> So the first 2 iterations would write to the end of the buffer and this
> 3rd one should have zeroed ->tail.

In the 2nd  iteration before the check:
vgacon_scrollback_cur->tail is 65360 which is still less then
vgacon_scrollback_cur->size(65440), so the ->tail won't be zeroed.

Then it gose to the 3rd  iteration, overflow occurs.

Regards,
Yunhai Zhang / NSFOCUS Security Team





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

* Re: [PATCH] vgacon: fix out of bounds write to the scrollback buffer
  2020-07-29  7:53   ` 张云海
@ 2020-07-29  8:11     ` Jiri Slaby
  2020-07-29  8:19       ` 张云海
  0 siblings, 1 reply; 16+ messages in thread
From: Jiri Slaby @ 2020-07-29  8:11 UTC (permalink / raw)
  To: 张云海, b.zolnierkie
  Cc: linux-kernel, Yang Yingliang, Kyungtae Kim, Linus Torvalds,
	Greg KH, Solar Designer, Srivatsa S. Bhat, Anthony Liguori,
	Security Officers, linux-distros, dri-devel, linux-fbdev

Hi,

On 29. 07. 20, 9:53, 张云海 wrote:
> This patch dosen't fix the issue, the check should be in the loop.
> 
> The change of the VT sze is before vgacon_scrollback_update, not in the
> meantime.
> 
> Let's consider the following situation:
> 	suppose:
> 		vgacon_scrollback_cur->size is 65440
> 		vgacon_scrollback_cur->tail is 64960
> 		c->vc_size_row is 160
> 		count is 5
> 	
> 	Reset c->vc_size_row to 200 by VT_RESIZE, then call
> vgacon_scrollback_update.
> 	
> 	This will pass the check, since (vgacon_scrollback_cur->tail +
> c->vc_size_row)
> 	is 65160 which is less then vgacon_scrollback_cur->size(65440).
> 
> 	However, in the 3rd iteration of the loop, vgacon_scrollback_cur->tail
> is update
> 	to 65360, the memcpy will overflow.

But the loop checks for the overflow:
  if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size)
        vgacon_scrollback_cur->tail = 0;

So the first 2 iterations would write to the end of the buffer and this
3rd one should have zeroed ->tail.

thanks,
-- 
js
suse labs

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

* Re: [PATCH] vgacon: fix out of bounds write to the scrollback buffer
  2020-07-29  7:02 ` Jiri Slaby
@ 2020-07-29  7:53   ` 张云海
  2020-07-29  8:11     ` Jiri Slaby
  2020-07-29 13:37   ` Bartlomiej Zolnierkiewicz
  1 sibling, 1 reply; 16+ messages in thread
From: 张云海 @ 2020-07-29  7:53 UTC (permalink / raw)
  To: Jiri Slaby, b.zolnierkie
  Cc: linux-kernel, Yang Yingliang, Kyungtae Kim, Linus Torvalds,
	Greg KH, Solar Designer, Srivatsa S. Bhat, Anthony Liguori,
	Security Officers, linux-distros, dri-devel, linux-fbdev

Hi All,

This patch dosen't fix the issue, the check should be in the loop.

The change of the VT sze is before vgacon_scrollback_update, not in the
meantime.

Let's consider the following situation:
	suppose:
		vgacon_scrollback_cur->size is 65440
		vgacon_scrollback_cur->tail is 64960
		c->vc_size_row is 160
		count is 5
	
	Reset c->vc_size_row to 200 by VT_RESIZE, then call
vgacon_scrollback_update.
	
	This will pass the check, since (vgacon_scrollback_cur->tail +
c->vc_size_row)
	is 65160 which is less then vgacon_scrollback_cur->size(65440).

	However, in the 3rd iteration of the loop, vgacon_scrollback_cur->tail
is update
	to 65360, the memcpy will overflow.

To avoid overflow, the check should be
           if ((vgacon_scrollback_cur->tail + c->vc_size_row * count) >=

However, this will break the circular of the buffer, since all 5 lines
will be copy at the beginning.

To avoid break circular, we have to detect if wrap occurs, use a loop to
copy lines before
wrap, reset vgacon_scrollback_cur->tail to 0, then use another loop to
copy lines after wrap.
Of course the 2 loop can be combine into 2 memcpy, that will be similar
to Linus's patch.

Thus, I think the check should be in the loop.
The 2 check in the loop seems to be redundancy, Zhang Xiao from
Windriver suggest that the check after the memcpy can be remove.
I think he was right, but not very sure.
Thus, I suggest we discuss that too.

Regards,
Yunhai Zhang / NSFOCUS Security Team


On 2020/7/29 15:02, Jiri Slaby wrote:
> The current vgacon's scroll up implementation uses a circural buffer
> in vgacon_scrollback_cur. It always advances tail to prepare it for the
> next write and caps it to zero if the next ->vc_size_row bytes won't fit.
> 
> But when we change the VT size (e.g. by VT_RESIZE) in the meantime, the new
> line might not fit to the end of the scrollback buffer in the next
> attempt to scroll. This leads to various crashes as
> vgacon_scrollback_update writes out of the buffer:
>  BUG: unable to handle page fault for address: ffffc900001752a0
>  #PF: supervisor write access in kernel mode
>  #PF: error_code(0x0002) - not-present page
>  RIP: 0010:mutex_unlock+0x13/0x30
> ...
>  Call Trace:
>   n_tty_write+0x1a0/0x4d0
>   tty_write+0x1a0/0x2e0
> 
> Or to KASAN reports:
> BUG: KASAN: slab-out-of-bounds in vgacon_scroll+0x57a/0x8ed
> 
> So check whether the line fits in the buffer and wrap if needed. Do it
> before the loop as console_sem is held and ->vc_size_row cannot change
> during the execution of vgacon_scrollback_cur. If it does change, we
> need to ensure it does not change elsewhere, not here.
> 
> Also, we do not split the write of a line into chunks as that would
> break the consumers of the buffer. They expect ->cnt, ->tail and ->size
> to be in harmony and advanced by ->vc_size_row.
> 
> I found few reports of this in the past, some with patches included,
> some even 2 years old:
> https://lore.kernel.org/lkml/CAEAjamsJnG-=TSOwgRbbb3B9Z-PA63oWmNPoKYWQ=Z=+X49akg@mail.gmail.com/
> https://lore.kernel.org/lkml/1589336932-35508-1-git-send-email-yangyingliang@huawei.com/
> 
> This fixes CVE-2020-14331.
> 
> Big thanks to guys mentioned in the Reported-and-debugged-by lines below
> who actually found the root cause.
> 
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> Reported-and-debugged-by: 张云海 <zhangyunhai@nsfocus.com>
> Reported-and-debugged-by: Yang Yingliang <yangyingliang@huawei.com>
> Reported-by: Kyungtae Kim <kt0755@gmail.com>
> Fixes: 15bdab959c9b ([PATCH] vgacon: Add support for soft scrollback)
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Cc: Greg KH <greg@kroah.com>
> Cc: Solar Designer <solar@openwall.com>
> Cc: "Srivatsa S. Bhat" <srivatsa@csail.mit.edu>
> Cc: Anthony Liguori <aliguori@amazon.com>
> Cc: Security Officers <security@kernel.org>
> Cc: linux-distros@vs.openwall.org
> Cc: Yang Yingliang <yangyingliang@huawei.com>
> Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-fbdev@vger.kernel.org
> ---
>  drivers/video/console/vgacon.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
> index f0f3d573f848..13194bb246f8 100644
> --- a/drivers/video/console/vgacon.c
> +++ b/drivers/video/console/vgacon.c
> @@ -250,6 +250,11 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
>  
>  	p = (void *) (c->vc_origin + t * c->vc_size_row);
>  
> +	/* vc_size_row might have changed by VT_RESIZE in the meantime */
> +	if ((vgacon_scrollback_cur->tail + c->vc_size_row) >=
> +			vgacon_scrollback_cur->size)
> +		vgacon_scrollback_cur->tail = 0;
> +
>  	while (count--) {
>  		scr_memcpyw(vgacon_scrollback_cur->data +
>  			    vgacon_scrollback_cur->tail,
> 

-- 
张云海
绿盟科技 安全研究部 研究员
地址:北京市海淀区北洼路4号益泰大厦三层
邮编:100089
电话:(010)68438880-8510
传真:(010)68437328
手机:13691192782
邮箱:zhangyunhai@nsfocus.com
网站:http://www.nsfocus.com

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

* [PATCH] vgacon: fix out of bounds write to the scrollback buffer
@ 2020-07-29  7:02 ` Jiri Slaby
  2020-07-29  7:53   ` 张云海
  2020-07-29 13:37   ` Bartlomiej Zolnierkiewicz
  0 siblings, 2 replies; 16+ messages in thread
From: Jiri Slaby @ 2020-07-29  7:02 UTC (permalink / raw)
  To: b.zolnierkie
  Cc: linux-kernel, Jiri Slaby, 张云海,
	Yang Yingliang, Kyungtae Kim, Linus Torvalds, Greg KH,
	Solar Designer, Srivatsa S. Bhat, Anthony Liguori,
	Security Officers, linux-distros, dri-devel, linux-fbdev

The current vgacon's scroll up implementation uses a circural buffer
in vgacon_scrollback_cur. It always advances tail to prepare it for the
next write and caps it to zero if the next ->vc_size_row bytes won't fit.

But when we change the VT size (e.g. by VT_RESIZE) in the meantime, the new
line might not fit to the end of the scrollback buffer in the next
attempt to scroll. This leads to various crashes as
vgacon_scrollback_update writes out of the buffer:
 BUG: unable to handle page fault for address: ffffc900001752a0
 #PF: supervisor write access in kernel mode
 #PF: error_code(0x0002) - not-present page
 RIP: 0010:mutex_unlock+0x13/0x30
...
 Call Trace:
  n_tty_write+0x1a0/0x4d0
  tty_write+0x1a0/0x2e0

Or to KASAN reports:
BUG: KASAN: slab-out-of-bounds in vgacon_scroll+0x57a/0x8ed

So check whether the line fits in the buffer and wrap if needed. Do it
before the loop as console_sem is held and ->vc_size_row cannot change
during the execution of vgacon_scrollback_cur. If it does change, we
need to ensure it does not change elsewhere, not here.

Also, we do not split the write of a line into chunks as that would
break the consumers of the buffer. They expect ->cnt, ->tail and ->size
to be in harmony and advanced by ->vc_size_row.

I found few reports of this in the past, some with patches included,
some even 2 years old:
https://lore.kernel.org/lkml/CAEAjamsJnG-=TSOwgRbbb3B9Z-PA63oWmNPoKYWQ=Z=+X49akg@mail.gmail.com/
https://lore.kernel.org/lkml/1589336932-35508-1-git-send-email-yangyingliang@huawei.com/

This fixes CVE-2020-14331.

Big thanks to guys mentioned in the Reported-and-debugged-by lines below
who actually found the root cause.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Reported-and-debugged-by: 张云海 <zhangyunhai@nsfocus.com>
Reported-and-debugged-by: Yang Yingliang <yangyingliang@huawei.com>
Reported-by: Kyungtae Kim <kt0755@gmail.com>
Fixes: 15bdab959c9b ([PATCH] vgacon: Add support for soft scrollback)
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Greg KH <greg@kroah.com>
Cc: Solar Designer <solar@openwall.com>
Cc: "Srivatsa S. Bhat" <srivatsa@csail.mit.edu>
Cc: Anthony Liguori <aliguori@amazon.com>
Cc: Security Officers <security@kernel.org>
Cc: linux-distros@vs.openwall.org
Cc: Yang Yingliang <yangyingliang@huawei.com>
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-fbdev@vger.kernel.org
---
 drivers/video/console/vgacon.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index f0f3d573f848..13194bb246f8 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -250,6 +250,11 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
 
 	p = (void *) (c->vc_origin + t * c->vc_size_row);
 
+	/* vc_size_row might have changed by VT_RESIZE in the meantime */
+	if ((vgacon_scrollback_cur->tail + c->vc_size_row) >=
+			vgacon_scrollback_cur->size)
+		vgacon_scrollback_cur->tail = 0;
+
 	while (count--) {
 		scr_memcpyw(vgacon_scrollback_cur->data +
 			    vgacon_scrollback_cur->tail,
-- 
2.28.0


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

end of thread, other threads:[~2020-08-04  7:37 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20200729130710.GA13262@openwall.com>
     [not found] ` <b764c575-70be-80dd-6718-e84370a7b2b3@nsfocus.com>
2020-07-30  6:46   ` [PATCH] vgacon: fix out of bounds write to the scrollback buffer Jiri Slaby
2020-07-30  7:38     ` Jiri Slaby
2020-07-30 10:39     ` 张云海
2020-07-31  5:22       ` 张云海
2020-08-03  8:08         ` Jiri Slaby
2020-08-03  8:18           ` Greg KH
2020-08-03  8:45             ` Daniel Vetter
2020-08-03  9:47               ` Greg KH
2020-08-03 11:07                 ` Bartlomiej Zolnierkiewicz
2020-08-04  7:37           ` Greg KH
     [not found] <CGME20200729070257eucas1p1f5841756104301e67907136e45d6e9f5@eucas1p1.samsung.com>
2020-07-29  7:02 ` Jiri Slaby
2020-07-29  7:53   ` 张云海
2020-07-29  8:11     ` Jiri Slaby
2020-07-29  8:19       ` 张云海
2020-07-29 11:20         ` Jiri Slaby
2020-07-29 13:37   ` Bartlomiej Zolnierkiewicz

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).