diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2001-01-10 17:17:53 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2001-01-10 17:17:53 +0000 |
commit | b2ad5f821b1381492d792ca10b1eb7a107b48f14 (patch) | |
tree | 954a648692e7da983db1d2470953705f6a729264 /fs/exec.c | |
parent | c9c06167e7933d93a6e396174c68abf242294abb (diff) |
Merge with Linux 2.4.0-prerelease. Big Makefile rewrite, test your
Makefiles.
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 108 |
1 files changed, 43 insertions, 65 deletions
@@ -223,8 +223,6 @@ int copy_strings(int argc,char ** argv, struct linux_binprm *bprm) memset(kaddr+offset+len, 0, PAGE_SIZE-offset-len); } err = copy_from_user(kaddr + offset, str, bytes_to_copy); - flush_dcache_page(page); - flush_page_to_ram(page); kunmap(page); if (err) @@ -281,6 +279,7 @@ void put_dirty_page(struct task_struct * tsk, struct page *page, unsigned long a __free_page(page); return; } + flush_dcache_page(page); flush_page_to_ram(page); set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, PAGE_COPY)))); /* no need for flush_tlb */ @@ -314,9 +313,7 @@ int setup_arg_pages(struct linux_binprm *bprm) mpnt->vm_pgoff = 0; mpnt->vm_file = NULL; mpnt->vm_private_data = (void *) 0; - spin_lock(¤t->mm->page_table_lock); insert_vm_struct(current->mm, mpnt); - spin_unlock(¤t->mm->page_table_lock); current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; } @@ -597,7 +594,6 @@ static inline int must_not_trace_exec(struct task_struct * p) int prepare_binprm(struct linux_binprm *bprm) { int mode; - int id_change,cap_raised; struct inode * inode = bprm->file->f_dentry->d_inode; mode = inode->i_mode; @@ -609,25 +605,20 @@ int prepare_binprm(struct linux_binprm *bprm) bprm->e_uid = current->euid; bprm->e_gid = current->egid; - id_change = cap_raised = 0; - /* Set-uid? */ - if (mode & S_ISUID) { - bprm->e_uid = inode->i_uid; - if (bprm->e_uid != current->euid) - id_change = 1; - } - - /* Set-gid? */ - /* - * If setgid is set but no group execute bit then this - * is a candidate for mandatory locking, not a setgid - * executable. - */ - if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { - bprm->e_gid = inode->i_gid; - if (!in_group_p(bprm->e_gid)) - id_change = 1; + if(!IS_NOSUID(inode)) { + /* Set-uid? */ + if (mode & S_ISUID) + bprm->e_uid = inode->i_uid; + + /* Set-gid? */ + /* + * If setgid is set but no group execute bit then this + * is a candidate for mandatory locking, not a setgid + * executable. + */ + if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) + bprm->e_gid = inode->i_gid; } /* We don't have VFS support for capabilities yet */ @@ -652,39 +643,6 @@ int prepare_binprm(struct linux_binprm *bprm) cap_set_full(bprm->cap_effective); } - /* Only if pP' is _not_ a subset of pP, do we consider there - * has been a capability related "change of capability". In - * such cases, we need to check that the elevation of - * privilege does not go against other system constraints. - * The new Permitted set is defined below -- see (***). */ - { - kernel_cap_t permitted, working; - - permitted = cap_intersect(bprm->cap_permitted, cap_bset); - working = cap_intersect(bprm->cap_inheritable, - current->cap_inheritable); - working = cap_combine(permitted, working); - if (!cap_issubset(working, current->cap_permitted)) { - cap_raised = 1; - } - } - - if (id_change || cap_raised) { - /* We can't suid-execute if we're sharing parts of the executable */ - /* or if we're being traced (or if suid execs are not allowed) */ - /* (current->mm->mm_users > 1 is ok, as we'll get a new mm anyway) */ - if (IS_NOSUID(inode) - || must_not_trace_exec(current) - || (atomic_read(¤t->fs->count) > 1) - || (atomic_read(¤t->sig->count) > 1) - || (atomic_read(¤t->files->count) > 1)) { - if (id_change && !capable(CAP_SETUID)) - return -EPERM; - if (cap_raised && !capable(CAP_SETPCAP)) - return -EPERM; - } - } - memset(bprm->buf,0,BINPRM_BUF_SIZE); return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE); } @@ -701,17 +659,41 @@ int prepare_binprm(struct linux_binprm *bprm) * * I=Inheritable, P=Permitted, E=Effective // p=process, f=file * ' indicates post-exec(), and X is the global 'cap_bset'. + * */ void compute_creds(struct linux_binprm *bprm) { kernel_cap_t new_permitted, working; + int do_unlock = 0; new_permitted = cap_intersect(bprm->cap_permitted, cap_bset); working = cap_intersect(bprm->cap_inheritable, current->cap_inheritable); new_permitted = cap_combine(new_permitted, working); + if (bprm->e_uid != current->uid || bprm->e_gid != current->gid || + !cap_issubset(new_permitted, current->cap_permitted)) { + current->dumpable = 0; + + lock_kernel(); + if (must_not_trace_exec(current) + || atomic_read(¤t->fs->count) > 1 + || atomic_read(¤t->files->count) > 1 + || atomic_read(¤t->sig->count) > 1) { + if(!capable(CAP_SETUID)) { + bprm->e_uid = current->uid; + bprm->e_gid = current->gid; + } + if(!capable(CAP_SETPCAP)) { + new_permitted = cap_intersect(new_permitted, + current->cap_permitted); + } + } + do_unlock = 1; + } + + /* For init, we want to retain the capabilities set * in the init_task struct. Thus we skip the usual * capability rules */ @@ -725,10 +707,9 @@ void compute_creds(struct linux_binprm *bprm) current->suid = current->euid = current->fsuid = bprm->e_uid; current->sgid = current->egid = current->fsgid = bprm->e_gid; - if (current->euid != current->uid || current->egid != current->gid || - !cap_issubset(new_permitted, current->cap_permitted)) - current->dumpable = 0; + if(do_unlock) + unlock_kernel(); current->keep_capabilities = 0; } @@ -768,29 +749,26 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) /* handle /sbin/loader.. */ { struct exec * eh = (struct exec *) bprm->buf; - struct linux_binprm bprm_loader; if (!bprm->loader && eh->fh.f_magic == 0x183 && (eh->fh.f_flags & 0x3000) == 0x3000) { - int i; char * dynloader[] = { "/sbin/loader" }; struct file * file; + unsigned long loader; allow_write_access(bprm->file); fput(bprm->file); bprm->file = NULL; - bprm_loader.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); - for (i = 0 ; i < MAX_ARG_PAGES ; i++) /* clear page-table */ - bprm_loader.page[i] = NULL; + loader = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); file = open_exec(dynloader[0]); retval = PTR_ERR(file); if (IS_ERR(file)) return retval; bprm->file = file; - bprm->loader = bprm_loader.p; + bprm->loader = loader; retval = prepare_binprm(bprm); if (retval<0) return retval; |