Re: Using x86 segments against NULL pointer deference exploit

From: Jiri Kosina
Date: Fri Nov 06 2009 - 15:58:14 EST


On Fri, 6 Nov 2009, castet.matthieu@xxxxxxx wrote:

> I am wondering why we can't set the KERNEL_DS data segment to not
> contain the first page, ie changing it from R/W flat model to R/W expand
> down from 0xffffffff to 4096.
> The modification seems simple : change GDT_ENTRY_KERNEL_DS [1], and some
> modification for syscall entry point that doesn't support segment (sysenter).

The question is -- why bother? We already have mmap_min_addr ... does this
pontentially provide any additional advantage?

> The drawback of this it that the kernel can't access anymore data in the first
> segment. Is it needed for application like wine or dosemu ?
> Regards,
>
> Matthieu
>
> PS : why x86_64 segment got access bit set and x86_32 doesn't ?
>
> [1]
> something like
> diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
> index cc25c2b..898a569 100644
> --- a/arch/x86/kernel/cpu/common.c
> +++ b/arch/x86/kernel/cpu/common.c
> @@ -101,7 +101,7 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = {
> .gdt = {
> [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xa0fb, 0, 0xfffff),
> #else
> [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xc09a, 0, 0xfffff),
> - [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
> + [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc096, 0, 0x00001),
> [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xc0fa, 0, 0xfffff),
> [GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f2, 0, 0xfffff),
> /*

It's not that simple for various reasons ... PaX/Grsecurity people already
did this in their patchset quite some time ago.

See http://www.grsecurity.net/~spender/uderef.txt

--
Jiri Kosina
SUSE Labs, Novell Inc.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/