[PATCH 8/9] LSM: Pass linux_binprm pointer to open_exec() so creds are available

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

 



Pass the exec state (struct linux_binprm) pointer to open_exec() so new creds
are available for a later patch to use.

Also:

 (1) Move the declaration of open_exec() to linux/binfmts.h.

 (2) Stick a kerneldoc banner comment on open_exec() describing it.

Signed-off-by: David Howells <dhowells@xxxxxxxxxx>
---

 arch/alpha/kernel/binfmt_loader.c |    2 +-
 fs/binfmt_elf.c                   |    2 +-
 fs/binfmt_elf_fdpic.c             |    2 +-
 fs/binfmt_em86.c                  |    2 +-
 fs/binfmt_flat.c                  |   17 ++++++-----------
 fs/binfmt_misc.c                  |    2 +-
 fs/binfmt_script.c                |    2 +-
 fs/compat.c                       |    2 +-
 fs/exec.c                         |   23 +++++++++++++++++++++--
 include/linux/binfmts.h           |    1 +
 include/linux/fs.h                |    2 --
 11 files changed, 35 insertions(+), 22 deletions(-)

diff --git a/arch/alpha/kernel/binfmt_loader.c b/arch/alpha/kernel/binfmt_loader.c
index 3fcfad4..1d19a44 100644
--- a/arch/alpha/kernel/binfmt_loader.c
+++ b/arch/alpha/kernel/binfmt_loader.c
@@ -24,7 +24,7 @@ static int load_binary(struct linux_binprm *bprm, struct pt_regs *regs)
 
 	loader = bprm->vma->vm_end - sizeof(void *);
 
-	file = open_exec("/sbin/loader");
+	file = open_exec("/sbin/loader", bprm);
 	retval = PTR_ERR(file);
 	if (IS_ERR(file))
 		return retval;
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index c8060bb..9f08098 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -660,7 +660,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
 			if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0')
 				goto out_free_interp;
 
-			interpreter = open_exec(elf_interpreter);
+			interpreter = open_exec(elf_interpreter, bprm);
 			retval = PTR_ERR(interpreter);
 			if (IS_ERR(interpreter))
 				goto out_free_interp;
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index eee4f70..a8e07b9 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -235,7 +235,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
 			kdebug("Using ELF interpreter %s", interpreter_name);
 
 			/* replace the program with the interpreter */
-			interpreter = open_exec(interpreter_name);
+			interpreter = open_exec(interpreter_name, bprm);
 			retval = PTR_ERR(interpreter);
 			if (IS_ERR(interpreter)) {
 				interpreter = NULL;
diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c
index b8e8b0a..44f3bb7 100644
--- a/fs/binfmt_em86.c
+++ b/fs/binfmt_em86.c
@@ -80,7 +80,7 @@ static int load_em86(struct linux_binprm *bprm,struct pt_regs *regs)
 	 * Note that we use open_exec() as the name is now in kernel
 	 * space, and we don't need to copy it.
 	 */
-	file = open_exec(interp);
+	file = open_exec(interp, bprm);
 	if (IS_ERR(file))
 		return PTR_ERR(file);
 
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 397d305..e9fe5bb 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -823,29 +823,24 @@ static int load_flat_shared_library(int id, struct lib_info *libs)
 	/* Create the file name */
 	sprintf(buf, "/lib/lib%d.so", id);
 
+	bprm.cred = (struct cred *)get_current_cred();
+
 	/* Open the file up */
 	bprm.filename = buf;
-	bprm.file = open_exec(bprm.filename);
+	bprm.file = open_exec(bprm.filename, bprm);
 	res = PTR_ERR(bprm.file);
 	if (IS_ERR(bprm.file))
-		return res;
-
-	bprm.cred = prepare_exec_creds();
-	res = -ENOMEM;
-	if (!bprm.cred)
-		goto out;
+		goto out_cred;
 
 	res = prepare_binprm(&bprm);
 
 	if (!IS_ERR_VALUE(res))
 		res = load_flat_file(&bprm, libs, id, NULL);
 
-	abort_creds(bprm.cred);
-
-out:
 	allow_write_access(bprm.file);
 	fput(bprm.file);
-
+out_cred:
+	put_creds(bprm.cred);
 	return(res);
 }
 
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 5209293..36a3297 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -178,7 +178,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
 
 	bprm->interp = iname;	/* for binfmt_script */
 
-	interp_file = open_exec (iname);
+	interp_file = open_exec (iname, bprm);
 	retval = PTR_ERR (interp_file);
 	if (IS_ERR (interp_file))
 		goto _error;
diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c
index 396a988..78d7d47 100644
--- a/fs/binfmt_script.c
+++ b/fs/binfmt_script.c
@@ -87,7 +87,7 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
 	/*
 	 * OK, now restart the process with the interpreter's dentry.
 	 */
-	file = open_exec(interp);
+	file = open_exec(interp, bprm);
 	if (IS_ERR(file))
 		return PTR_ERR(file);
 
diff --git a/fs/compat.c b/fs/compat.c
index 72fe6cd..4b10306 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1461,7 +1461,7 @@ int compat_do_execve(char * filename,
 	clear_in_exec = retval;
 	current->in_execve = 1;
 
-	file = open_exec(filename);
+	file = open_exec(filename, bprm);
 	retval = PTR_ERR(file);
 	if (IS_ERR(file))
 		goto out_unmark;
diff --git a/fs/exec.c b/fs/exec.c
index 4c47395..e1584c6 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -720,7 +720,26 @@ EXPORT_SYMBOL(setup_arg_pages);
 
 #endif /* CONFIG_MMU */
 
-struct file *open_exec(const char *name)
+/**
+ * open_exec - Open an executable binary, loader, script or interpreter file
+ * @name: The path of the file to open
+ * @bprm: The exec state
+ *
+ * Open an executable binary, loader, script or interpreter file for program
+ * execution to process.
+ *
+ * The file is opened with the currently proposed credentials for execution.
+ * This means that the file specified to execve() is opened with the caller's
+ * current credentials, but files opened after that - such as binary loaders
+ * (e.g. ld-config.so) and script interpreters (e.g. /bin/sh) - will be opened
+ * with the credentials that will be installed if that executable is the thing
+ * actually run.
+ *
+ * Note that each iteration through prepare_binprm() may further modify the
+ * credentials to be.  The credentials at the time the returned file is opened
+ * will remain attached to file->f_cred until the file is closed.
+ */
+struct file *open_exec(const char *name, struct linux_binprm *bprm)
 {
 	struct file *file;
 	int err;
@@ -1440,7 +1459,7 @@ int do_execve(const char * filename,
 	clear_in_exec = retval;
 	current->in_execve = 1;
 
-	file = open_exec(filename);
+	file = open_exec(filename, bprm);
 	retval = PTR_ERR(file);
 	if (IS_ERR(file))
 		goto out_unmark;
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 82577f7..57ea660 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -133,6 +133,7 @@ extern int bprm_mm_init(struct linux_binprm *bprm);
 extern int copy_strings_kernel(int argc, const char *const *argv,
 			       struct linux_binprm *bprm);
 extern int prepare_bprm_creds(struct linux_binprm *bprm);
+extern struct file *open_exec(const char *filename, struct linux_binprm *bprm);
 extern void install_exec_creds(struct linux_binprm *bprm);
 extern int kernel_read(struct linux_binprm *, struct file *,
 		       loff_t, void *, unsigned long);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 74543c9..e1a44a9 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2224,8 +2224,6 @@ extern struct file *create_read_pipe(struct file *f, int flags);
 extern struct file *create_write_pipe(int flags);
 extern void free_write_pipe(struct file *);
 
-extern struct file * open_exec(const char *);
- 
 /* fs/dcache.c -- generic fs support functions */
 extern int is_subdir(struct dentry *, struct dentry *);
 extern int path_is_under(struct path *, struct path *);


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with
the words "unsubscribe selinux" without quotes as the message.


[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux