Patch "powerpc/pseries/hvconsole: Fix stack overread via udbg" has been added to the 4.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    powerpc/pseries/hvconsole: Fix stack overread via udbg

to the 4.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     powerpc-pseries-hvconsole-fix-stack-overread-via-udb.patch
and it can be found in the queue-4.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 0cc92cb9b5cb9ccbf2c501b42270226073aaa07d
Author: Daniel Axtens <dja@xxxxxxxxxx>
Date:   Mon Jun 3 16:56:57 2019 +1000

    powerpc/pseries/hvconsole: Fix stack overread via udbg
    
    [ Upstream commit 934bda59f286d0221f1a3ebab7f5156a996cc37d ]
    
    While developing KASAN for 64-bit book3s, I hit the following stack
    over-read.
    
    It occurs because the hypercall to put characters onto the terminal
    takes 2 longs (128 bits/16 bytes) of characters at a time, and so
    hvc_put_chars() would unconditionally copy 16 bytes from the argument
    buffer, regardless of supplied length. However, udbg_hvc_putc() can
    call hvc_put_chars() with a single-byte buffer, leading to the error.
    
      ==================================================================
      BUG: KASAN: stack-out-of-bounds in hvc_put_chars+0xdc/0x110
      Read of size 8 at addr c0000000023e7a90 by task swapper/0
    
      CPU: 0 PID: 0 Comm: swapper Not tainted 5.2.0-rc2-next-20190528-02824-g048a6ab4835b #113
      Call Trace:
        dump_stack+0x104/0x154 (unreliable)
        print_address_description+0xa0/0x30c
        __kasan_report+0x20c/0x224
        kasan_report+0x18/0x30
        __asan_report_load8_noabort+0x24/0x40
        hvc_put_chars+0xdc/0x110
        hvterm_raw_put_chars+0x9c/0x110
        udbg_hvc_putc+0x154/0x200
        udbg_write+0xf0/0x240
        console_unlock+0x868/0xd30
        register_console+0x970/0xe90
        register_early_udbg_console+0xf8/0x114
        setup_arch+0x108/0x790
        start_kernel+0x104/0x784
        start_here_common+0x1c/0x534
    
      Memory state around the buggy address:
       c0000000023e7980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       c0000000023e7a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
      >c0000000023e7a80: f1 f1 01 f2 f2 f2 00 00 00 00 00 00 00 00 00 00
                               ^
       c0000000023e7b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       c0000000023e7b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      ==================================================================
    
    Document that a 16-byte buffer is requred, and provide it in udbg.
    
    Signed-off-by: Daniel Axtens <dja@xxxxxxxxxx>
    Signed-off-by: Michael Ellerman <mpe@xxxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c
index 849b29b3e9ae..954ef27128f2 100644
--- a/arch/powerpc/platforms/pseries/hvconsole.c
+++ b/arch/powerpc/platforms/pseries/hvconsole.c
@@ -62,7 +62,7 @@ EXPORT_SYMBOL(hvc_get_chars);
  * @vtermno: The vtermno or unit_address of the adapter from which the data
  *	originated.
  * @buf: The character buffer that contains the character data to send to
- *	firmware.
+ *	firmware. Must be at least 16 bytes, even if count is less than 16.
  * @count: Send this number of characters.
  */
 int hvc_put_chars(uint32_t vtermno, const char *buf, int count)
diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c
index f575a9b5ede7..1d671d058dcb 100644
--- a/drivers/tty/hvc/hvc_vio.c
+++ b/drivers/tty/hvc/hvc_vio.c
@@ -122,6 +122,14 @@ static int hvterm_raw_get_chars(uint32_t vtermno, char *buf, int count)
 	return got;
 }
 
+/**
+ * hvterm_raw_put_chars: send characters to firmware for given vterm adapter
+ * @vtermno: The virtual terminal number.
+ * @buf: The characters to send. Because of the underlying hypercall in
+ *       hvc_put_chars(), this buffer must be at least 16 bytes long, even if
+ *       you are sending fewer chars.
+ * @count: number of chars to send.
+ */
 static int hvterm_raw_put_chars(uint32_t vtermno, const char *buf, int count)
 {
 	struct hvterm_priv *pv = hvterm_privs[vtermno];
@@ -234,6 +242,7 @@ static const struct hv_ops hvterm_hvsi_ops = {
 static void udbg_hvc_putc(char c)
 {
 	int count = -1;
+	unsigned char bounce_buffer[16];
 
 	if (!hvterm_privs[0])
 		return;
@@ -244,7 +253,12 @@ static void udbg_hvc_putc(char c)
 	do {
 		switch(hvterm_privs[0]->proto) {
 		case HV_PROTOCOL_RAW:
-			count = hvterm_raw_put_chars(0, &c, 1);
+			/*
+			 * hvterm_raw_put_chars requires at least a 16-byte
+			 * buffer, so go via the bounce buffer
+			 */
+			bounce_buffer[0] = c;
+			count = hvterm_raw_put_chars(0, bounce_buffer, 1);
 			break;
 		case HV_PROTOCOL_HVSI:
 			count = hvterm_hvsi_put_chars(0, &c, 1);



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux