X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fexec.c;h=284207a1f1c7d8021d591bbbc0391b60a0b88335;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=c10a7d9c6c43159c8af548b60b3d97d641c858aa;hpb=a8e794ca871505c8ea96cc102f4ad555c5231d7f;p=linux-2.6.git diff --git a/fs/exec.c b/fs/exec.c index c10a7d9c6..284207a1f 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -46,9 +46,9 @@ #include #include #include +#include #include -#include #include #ifdef CONFIG_KMOD @@ -293,54 +293,49 @@ EXPORT_SYMBOL(copy_strings_kernel); * This routine is used to map in a page into an address space: needed by * execve() for the initial stack and environment pages. * - * tsk->mmap_sem is held for writing. + * vma->vm_mm->mmap_sem is held for writing. */ -void put_dirty_page(struct task_struct *tsk, struct page *page, - unsigned long address, pgprot_t prot) +void install_arg_page(struct vm_area_struct *vma, + struct page *page, unsigned long address) { + struct mm_struct *mm = vma->vm_mm; pgd_t * pgd; pmd_t * pmd; pte_t * pte; - struct pte_chain *pte_chain; - if (page_count(page) != 1) - printk(KERN_ERR "mem_map disagrees with %p at %08lx\n", - page, address); - - pgd = pgd_offset(tsk->mm, address); - pte_chain = pte_chain_alloc(GFP_KERNEL); - if (!pte_chain) + if (unlikely(anon_vma_prepare(vma))) goto out_sig; - spin_lock(&tsk->mm->page_table_lock); - pmd = pmd_alloc(tsk->mm, pgd, address); + + flush_dcache_page(page); + pgd = pgd_offset(mm, address); + + spin_lock(&mm->page_table_lock); + pmd = pmd_alloc(mm, pgd, address); if (!pmd) goto out; - pte = pte_alloc_map(tsk->mm, pmd, address); + pte = pte_alloc_map(mm, pmd, address); if (!pte) goto out; if (!pte_none(*pte)) { pte_unmap(pte); goto out; } + // mm->rss++; + vx_rsspages_inc(mm); lru_cache_add_active(page); - flush_dcache_page(page); - set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, prot)))); - pte_chain = page_add_rmap(page, pte, pte_chain); + set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte( + page, vma->vm_page_prot)))); + page_add_anon_rmap(page, vma, address); pte_unmap(pte); - // tsk->mm->rss++; - vx_rsspages_inc(tsk->mm); - spin_unlock(&tsk->mm->page_table_lock); + spin_unlock(&mm->page_table_lock); /* no need for flush_tlb */ - pte_chain_free(pte_chain); return; out: - spin_unlock(&tsk->mm->page_table_lock); + spin_unlock(&mm->page_table_lock); out_sig: __free_page(page); - force_sig(SIGKILL, tsk); - pte_chain_free(pte_chain); - return; + force_sig(SIGKILL, current); } int setup_arg_pages(struct linux_binprm *bprm, int executable_stack) @@ -416,6 +411,8 @@ int setup_arg_pages(struct linux_binprm *bprm, int executable_stack) return -ENOMEM; } + memset(mpnt, 0, sizeof(*mpnt)); + down_write(&mm->mmap_sem); { mpnt->vm_mm = mm; @@ -436,12 +433,8 @@ int setup_arg_pages(struct linux_binprm *bprm, int executable_stack) mpnt->vm_flags = VM_STACK_FLAGS & ~VM_EXEC; else mpnt->vm_flags = VM_STACK_FLAGS; + mpnt->vm_flags |= mm->def_flags; mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7]; - mpnt->vm_ops = NULL; - mpnt->vm_pgoff = 0; - mpnt->vm_file = NULL; - INIT_LIST_HEAD(&mpnt->shared); - mpnt->vm_private_data = (void *) 0; insert_vm_struct(mm, mpnt); // mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; vx_vmpages_sub(mm, mm->total_vm - @@ -452,8 +445,7 @@ int setup_arg_pages(struct linux_binprm *bprm, int executable_stack) struct page *page = bprm->page[i]; if (page) { bprm->page[i] = NULL; - put_dirty_page(current, page, stack_base, - mpnt->vm_page_prot); + install_arg_page(mpnt, page, stack_base); } stack_base += PAGE_SIZE; } @@ -852,7 +844,8 @@ int flush_old_exec(struct linux_binprm * bprm) flush_thread(); if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || - permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL)) + permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL) || + (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) current->mm->dumpable = 0; /* An exec changes our domain. We are no longer part of the thread @@ -899,8 +892,10 @@ int prepare_binprm(struct linux_binprm *bprm) if(!(bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)) { /* Set-uid? */ - if (mode & S_ISUID) + if (mode & S_ISUID) { + current->personality &= ~PER_CLEAR_ON_SETID; bprm->e_uid = inode->i_uid; + } /* Set-gid? */ /* @@ -908,8 +903,10 @@ int prepare_binprm(struct linux_binprm *bprm) * is a candidate for mandatory locking, not a setgid * executable. */ - if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) + if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { + current->personality &= ~PER_CLEAR_ON_SETID; bprm->e_gid = inode->i_gid; + } } /* fill in binprm security blob */ @@ -1007,7 +1004,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) return retval; /* Remember if the application is TASO. */ - bprm->sh_bang = eh->ah.entry < 0x100000000; + bprm->sh_bang = eh->ah.entry < 0x100000000UL; bprm->file = file; bprm->loader = loader; @@ -1087,20 +1084,22 @@ int do_execve(char * filename, int retval; int i; - sched_balance_exec(); - file = open_exec(filename); retval = PTR_ERR(file); if (IS_ERR(file)) return retval; + sched_balance_exec(); + bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); bprm.file = file; bprm.filename = filename; bprm.interp = filename; + bprm.interp_flags = 0; + bprm.interp_data = 0; bprm.sh_bang = 0; bprm.loader = 0; bprm.exec = 0;