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

Re: CAN-2005-2617: local users can trigger a memory leak via a 32-bit application with crafted ELF headers



On Fri, Aug 26, 2005 at 07:01:51PM -0500, Micah wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Hey all,
> 
> 
> CAN-2005-2617 describes a local DOS on 64bit machines:
> 
> The syscall32_setup_pages function in syscall32.c for Linux kernel
> 2.6.12 and later, on the 64-bit x86 platform, does not check the return
> value of the insert_vm_struct function, which allows local users to
> trigger a memory leak via a 32-bit application with crafted ELF headers.
> 
> http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=9fb1759a3102c26cd8f64254a7c3e532782c2bb8
> http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=9fb1759a3102c26cd8f64254a7c3e532782c2bb8

Thanks,

I have added this to linux-2.6-sid in SVN and it should
appear in linux-2.6 2.6.12-6

According to some git-magic I pulled in my local copy of Linus's tree, 
this change is already in 2.6.13

cg diff -r 02b3e4e2d71b6058ec11cc01c72ac651eb3ded2b -r 9fb1759a3102c26cd8f64254a7c3e532782c2bb8 arch/x86_64/ia32/syscall32.c 

I have examined 2.6.8 and I do not beleive it is vulnerable as the code 
in question was introduced by the following, post 2.6.8, change.

http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=1e01441051dda3bb01c455b6e20bce6d00563d82

However, some eyes over the 2.6.8 incarnation, to see if it
is broken would be appreciated:

>From arch/x86_64/ia32/syscall32.c

/* RED-PEN: This knows too much about high level VM */ 
/* Alternative would be to generate a vma with appropriate backing
 * options
   and let it be handled by generic VM */
int map_syscall32(struct mm_struct *mm, unsigned long address)
{ 
        pte_t *pte;
        pmd_t *pmd;
        int err = 0;

        down_read(&mm->mmap_sem);
        spin_lock(&mm->page_table_lock);
        pmd = pmd_alloc(mm, pgd_offset(mm, address), address);
        if (pmd && (pte = pte_alloc_map(mm, pmd, address)) != NULL) {
                if (pte_none(*pte)) { 
                        set_pte(pte,
                                mk_pte(virt_to_page(syscall32_page),
                                       PAGE_KERNEL_VSYSCALL));
                }
                /* Flush only the local CPU. Other CPUs taking a fault
                   will just end up here again */
                __flush_tlb_one(address);
        } else
                err = -ENOMEM;
        spin_unlock(&mm->page_table_lock);
        up_read(&mm->mmap_sem);
        return err;
}       


And 2.4.27 and upstream 2.4 do not have 32 bit syscalls for AMD64.

>From arch/x86_64/ia32/sys_ia32.c

asmlinkage long sys32_ni_syscall(int call)
{
        /* Disable for now because the emulation should be pretty complete 
           and we miss some syscalls from 2.6. */
#if 0
        printk(KERN_INFO "IA32 syscall %d from %s not implemented\n", call,
               current->comm);
#endif
        return -ENOSYS;
}




-- 
Horms



Reply to: