]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/exec.c
arm: use kbuild.h instead of macros in asm-offsets.c
[linux-2.6-omap-h63xx.git] / fs / exec.c
index be923e4bc38972954325aee09363cb38bff60884..a13883903ee98587951681e143c36d9712460515 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -112,14 +112,14 @@ asmlinkage long sys_uselib(const char __user * library)
                goto out;
 
        error = -EINVAL;
-       if (!S_ISREG(nd.dentry->d_inode->i_mode))
+       if (!S_ISREG(nd.path.dentry->d_inode->i_mode))
                goto exit;
 
        error = vfs_permission(&nd, MAY_READ | MAY_EXEC);
        if (error)
                goto exit;
 
-       file = nameidata_to_filp(&nd, O_RDONLY);
+       file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
        error = PTR_ERR(file);
        if (IS_ERR(file))
                goto out;
@@ -148,7 +148,7 @@ out:
        return error;
 exit:
        release_open_intent(&nd);
-       path_release(&nd);
+       path_put(&nd.path);
        goto out;
 }
 
@@ -173,8 +173,15 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
                return NULL;
 
        if (write) {
-               struct rlimit *rlim = current->signal->rlim;
                unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start;
+               struct rlimit *rlim;
+
+               /*
+                * We've historically supported up to 32 pages (ARG_MAX)
+                * of argument strings even with small stacks
+                */
+               if (size <= ARG_MAX)
+                       return page;
 
                /*
                 * Limit to 1/4-th the stack size for the argv+env strings.
@@ -183,6 +190,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
                 *  - the program will have a reasonable amount of stack left
                 *    to work from.
                 */
+               rlim = current->signal->rlim;
                if (size > rlim[RLIMIT_STACK].rlim_cur / 4) {
                        put_page(page);
                        return NULL;
@@ -652,13 +660,14 @@ struct file *open_exec(const char *name)
        file = ERR_PTR(err);
 
        if (!err) {
-               struct inode *inode = nd.dentry->d_inode;
+               struct inode *inode = nd.path.dentry->d_inode;
                file = ERR_PTR(-EACCES);
                if (S_ISREG(inode->i_mode)) {
                        int err = vfs_permission(&nd, MAY_EXEC);
                        file = ERR_PTR(err);
                        if (!err) {
-                               file = nameidata_to_filp(&nd, O_RDONLY);
+                               file = nameidata_to_filp(&nd,
+                                                       O_RDONLY|O_LARGEFILE);
                                if (!IS_ERR(file)) {
                                        err = deny_write_access(file);
                                        if (err) {
@@ -671,7 +680,7 @@ out:
                        }
                }
                release_open_intent(&nd);
-               path_release(&nd);
+               path_put(&nd.path);
        }
        goto out;
 }
@@ -726,6 +735,7 @@ static int exec_mmap(struct mm_struct *mm)
        tsk->active_mm = mm;
        activate_mm(active_mm, mm);
        task_unlock(tsk);
+       mm_update_next_owner(mm);
        arch_pick_mmap_layout(mm);
        if (old_mm) {
                up_read(&old_mm->mmap_sem);
@@ -782,26 +792,8 @@ static int de_thread(struct task_struct *tsk)
        zap_other_threads(tsk);
        read_unlock(&tasklist_lock);
 
-       /*
-        * Account for the thread group leader hanging around:
-        */
-       count = 1;
-       if (!thread_group_leader(tsk)) {
-               count = 2;
-               /*
-                * The SIGALRM timer survives the exec, but needs to point
-                * at us as the new group leader now.  We have a race with
-                * a timer firing now getting the old leader, so we need to
-                * synchronize with any firing (by calling del_timer_sync)
-                * before we can safely let the old group leader die.
-                */
-               sig->tsk = tsk;
-               spin_unlock_irq(lock);
-               if (hrtimer_cancel(&sig->real_timer))
-                       hrtimer_restart(&sig->real_timer);
-               spin_lock_irq(lock);
-       }
-
+       /* Account for the thread group leader hanging around: */
+       count = thread_group_leader(tsk) ? 1 : 2;
        sig->notify_count = count;
        while (atomic_read(&sig->count) > count) {
                __set_current_state(TASK_UNINTERRUPTIBLE);
@@ -962,7 +954,6 @@ int flush_old_exec(struct linux_binprm * bprm)
 {
        char * name;
        int i, ch, retval;
-       struct files_struct *files;
        char tcomm[sizeof(current->comm)];
 
        /*
@@ -973,27 +964,18 @@ int flush_old_exec(struct linux_binprm * bprm)
        if (retval)
                goto out;
 
-       /*
-        * Make sure we have private file handles. Ask the
-        * fork helper to do the work for us and the exit
-        * helper to do the cleanup of the old one.
-        */
-       files = current->files;         /* refcounted so safe to hold */
-       retval = unshare_files();
-       if (retval)
-               goto out;
+       set_mm_exe_file(bprm->mm, bprm->file);
+
        /*
         * Release all of the old mmap stuff
         */
        retval = exec_mmap(bprm->mm);
        if (retval)
-               goto mmap_failed;
+               goto out;
 
        bprm->mm = NULL;                /* We're using it now */
 
        /* This is the point of no return */
-       put_files_struct(files);
-
        current->sas_ss_sp = current->sas_ss_size = 0;
 
        if (current->euid == current->uid && current->egid == current->gid)
@@ -1043,8 +1025,6 @@ int flush_old_exec(struct linux_binprm * bprm)
 
        return 0;
 
-mmap_failed:
-       reset_files_struct(current, files);
 out:
        return retval;
 }
@@ -1184,7 +1164,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
 {
        int try,retval;
        struct linux_binfmt *fmt;
-#ifdef __alpha__
+#if defined(__alpha__) && defined(CONFIG_ARCH_SUPPORTS_AOUT)
        /* handle /sbin/loader.. */
        {
            struct exec * eh = (struct exec *) bprm->buf;
@@ -1291,13 +1271,17 @@ int do_execve(char * filename,
 {
        struct linux_binprm *bprm;
        struct file *file;
-       unsigned long env_p;
+       struct files_struct *displaced;
        int retval;
 
+       retval = unshare_files(&displaced);
+       if (retval)
+               goto out_ret;
+
        retval = -ENOMEM;
        bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
        if (!bprm)
-               goto out_ret;
+               goto out_files;
 
        file = open_exec(filename);
        retval = PTR_ERR(file);
@@ -1339,11 +1323,9 @@ int do_execve(char * filename,
        if (retval < 0)
                goto out;
 
-       env_p = bprm->p;
        retval = copy_strings(bprm->argc, argv, bprm);
        if (retval < 0)
                goto out;
-       bprm->argv_len = env_p - bprm->p;
 
        retval = search_binary_handler(bprm,regs);
        if (retval >= 0) {
@@ -1352,6 +1334,8 @@ int do_execve(char * filename,
                security_bprm_free(bprm);
                acct_update_integrals(current);
                kfree(bprm);
+               if (displaced)
+                       put_files_struct(displaced);
                return retval;
        }
 
@@ -1372,6 +1356,9 @@ out_file:
 out_kfree:
        kfree(bprm);
 
+out_files:
+       if (displaced)
+               reset_files_struct(displaced);
 out_ret:
        return retval;
 }