Skip to content

Commit bdd8f62

Browse files
committed
exec: Add do_close_execat() helper
Consolidate the calls to allow_write_access()/fput() into a single place, since we repeat this code pattern. Add comments around the callers for the details on it. Link: https://lore.kernel.org/r/202209161637.9EDAF6B18@keescook Signed-off-by: Kees Cook <keescook@chromium.org>
1 parent 8788a17 commit bdd8f62

1 file changed

Lines changed: 26 additions & 6 deletions

File tree

fs/exec.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,10 @@ EXPORT_SYMBOL(transfer_args_to_stack);
904904

905905
#endif /* CONFIG_MMU */
906906

907+
/*
908+
* On success, caller must call do_close_execat() on the returned
909+
* struct file to close it.
910+
*/
907911
static struct file *do_open_execat(int fd, struct filename *name, int flags)
908912
{
909913
struct file *file;
@@ -948,6 +952,17 @@ static struct file *do_open_execat(int fd, struct filename *name, int flags)
948952
return ERR_PTR(err);
949953
}
950954

955+
/**
956+
* open_exec - Open a path name for execution
957+
*
958+
* @name: path name to open with the intent of executing it.
959+
*
960+
* Returns ERR_PTR on failure or allocated struct file on success.
961+
*
962+
* As this is a wrapper for the internal do_open_execat(), callers
963+
* must call allow_write_access() before fput() on release. Also see
964+
* do_close_execat().
965+
*/
951966
struct file *open_exec(const char *name)
952967
{
953968
struct filename *filename = getname_kernel(name);
@@ -1484,6 +1499,15 @@ static int prepare_bprm_creds(struct linux_binprm *bprm)
14841499
return -ENOMEM;
14851500
}
14861501

1502+
/* Matches do_open_execat() */
1503+
static void do_close_execat(struct file *file)
1504+
{
1505+
if (!file)
1506+
return;
1507+
allow_write_access(file);
1508+
fput(file);
1509+
}
1510+
14871511
static void free_bprm(struct linux_binprm *bprm)
14881512
{
14891513
if (bprm->mm) {
@@ -1495,10 +1519,7 @@ static void free_bprm(struct linux_binprm *bprm)
14951519
mutex_unlock(&current->signal->cred_guard_mutex);
14961520
abort_creds(bprm->cred);
14971521
}
1498-
if (bprm->file) {
1499-
allow_write_access(bprm->file);
1500-
fput(bprm->file);
1501-
}
1522+
do_close_execat(bprm->file);
15021523
if (bprm->executable)
15031524
fput(bprm->executable);
15041525
/* If a binfmt changed the interp, free it. */
@@ -1520,8 +1541,7 @@ static struct linux_binprm *alloc_bprm(int fd, struct filename *filename, int fl
15201541

15211542
bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
15221543
if (!bprm) {
1523-
allow_write_access(file);
1524-
fput(file);
1544+
do_close_execat(file);
15251545
return ERR_PTR(-ENOMEM);
15261546
}
15271547

0 commit comments

Comments
 (0)