Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <c5a31b68-1c86-b820-e4b3-716161da0a59@virtuozzo.com>
Date: Wed, 4 Jul 2018 14:23:26 +0300
From: Vasily Averin <vvs@...tuozzo.com>
To: Pavel Kankovsky <peak@...o.troja.mff.cuni.cz>,
 owl-dev@...ts.openwall.com, Solar Designer <solar@...nwall.com>
Subject: Re: 32-bit syscall breakage in -431 kernel with KAISER



On 06/26/2018 09:00 PM, Pavel Kankovsky wrote:
> On Mon, 25 Jun 2018, Pavel Kankovsky wrote:
> 
>> (I know I should learn how to use builtin GDB server in Qemu but...)
> 
> I have figured how to do some basic machine-code-level debugging of ia32_syscall (the int 0x80 handler) using Qemu:
> 
> 1. Make sure Qemu is running with -gdb tcp:127.0.0.1:X (or -s).
> 2. Get vmlinux for the running kernel.
> 3. Run the debugger:
> 
> $ gdb vmlinux
> (gdb) target remote tcp:127.0.0.1:X
> (gdb) set disassemble-next-line on
> (gdb) b ia32_syscall
> (gdb) c
> 
> 4. Run a 32-bit binary in the vm.
> 5. Use "si" to step through the debugged function.
> 
> It turns out the handler is invoked with an unexpected stack frame in the "trampoline stack" (the top of the "trampoline stack", as stored in TSS.rsp0, is 0xffff810001a36278 in this example):
> 
> (gdb) x/6g $rsp
> 0xffff810001a36248:     0x00000000b7f81ea1      0x0000000000000073
> 0xffff810001a36258:     0x0000000000000246      0x00000000bfa78274
> 0xffff810001a36268:     0x000000000000007b      0x000000000000007b
> 
> There should be five entries (rip at the bottom, cs, eflags, rsp, and ss at the top) only but the actual stack contains one mysterious and bogus extra entry (the other 0x000000000000007b) at the top, shifting everything else down by 8 bytes.
> 
> This stack frame (including the bogus extra entry) is copied to the regular kernel stack. As far as I can tell, the same extra entry appears in other interrupt handlers, e.g. common_interrupt.
> 
> Functions that get an explicit pointer to struct pt_regs are not affected but anything that expects to find pt_regs at the top of the stack (e.g. compat_alloc_user_space via task_pt_regs(current)) breaks.
> 
> It seems the extra entry is added because the top of the trampoline stack is not aligned to 16 bytes and the CPU does not like it and enforces the alignment, shifting the whole stack down wrt. the expected layout as a result.
> 
> I have modified struct tss_struct in include/asm-x86_64/processor.h to
> include an extra "unsigned long stack_padding" between stack_canary and stack to make stack 16-byte aligned...
> 
> ---snip---
> --- include/asm-x86_64/processor.h.orig    2018-06-26 12:11:17 +0000
> +++ include/asm-x86_64/processor.h    2018-06-26 16:50:55 +0000
> @@ -269,6 +269,7 @@
>       */
>  #ifndef __GENKSYMS__
>      unsigned long        stack_canary;
> +    unsigned long        stack_padding;
>      unsigned long           stack[64];
>  #endif
>  } __attribute__((packed, __aligned__(PAGE_SIZE)));
> ---snip---
> 
> ...and lo! 32-bit ifconfig works as expected.
I've reported  it to Red Hat, Solar was added in cc
https://bugzilla.redhat.com/show_bug.cgi?id=1598108

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.