|
@@ -1275,8 +1275,22 @@ EXPORT_SYMBOL(flush_old_exec);
|
|
|
|
|
|
void would_dump(struct linux_binprm *bprm, struct file *file)
|
|
|
{
|
|
|
- if (inode_permission(file_inode(file), MAY_READ) < 0)
|
|
|
+ struct inode *inode = file_inode(file);
|
|
|
+ if (inode_permission(inode, MAY_READ) < 0) {
|
|
|
+ struct user_namespace *old, *user_ns;
|
|
|
bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
|
|
|
+
|
|
|
+ /* Ensure mm->user_ns contains the executable */
|
|
|
+ user_ns = old = bprm->mm->user_ns;
|
|
|
+ while ((user_ns != &init_user_ns) &&
|
|
|
+ !privileged_wrt_inode_uidgid(user_ns, inode))
|
|
|
+ user_ns = user_ns->parent;
|
|
|
+
|
|
|
+ if (old != user_ns) {
|
|
|
+ bprm->mm->user_ns = get_user_ns(user_ns);
|
|
|
+ put_user_ns(old);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
EXPORT_SYMBOL(would_dump);
|
|
|
|
|
@@ -1306,7 +1320,6 @@ void setup_new_exec(struct linux_binprm * bprm)
|
|
|
!gid_eq(bprm->cred->gid, current_egid())) {
|
|
|
current->pdeath_signal = 0;
|
|
|
} else {
|
|
|
- would_dump(bprm, bprm->file);
|
|
|
if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)
|
|
|
set_dumpable(current->mm, suid_dumpable);
|
|
|
}
|
|
@@ -1741,6 +1754,8 @@ static int do_execveat_common(int fd, struct filename *filename,
|
|
|
if (retval < 0)
|
|
|
goto out;
|
|
|
|
|
|
+ would_dump(bprm, bprm->file);
|
|
|
+
|
|
|
retval = exec_binprm(bprm);
|
|
|
if (retval < 0)
|
|
|
goto out;
|