aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Arcangeli <andrea@cpushare.com>2017-07-25 22:22:45 +0200
committerMoyster <oysterized@gmail.com>2017-08-05 13:52:44 +0200
commit10c8ca605b0d293aeee50326cc4119dbb5b5393d (patch)
tree70796ea6a50dee256b909bd619ffd48b6c8532f6
parent4bf1ddff1f44d3dbf8aa138eb4d6d01ec29428ff (diff)
fs/exec: fix use after free in execve
"file" can be already freed if bprm->file is NULL after search_binary_handler() return. binfmt_script will do exactly that for example. If the VM reuses the file after fput run(), this will result in a use ater free. So obtain d_is_su before search_binary_handler() runs. This should explain this crash: [25333.009554] Unable to handle kernel NULL pointer dereference at virtual address 00000185 [..] [25333.009918] [2: am:21861] PC is at do_execve+0x354/0x474 Change-Id: I2a8a814d1c0aa75625be83cb30432cf13f1a0681 Signed-off-by: Kevin F. Haggerty <haggertk@lineageos.org>
-rw-r--r--fs/exec.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/exec.c b/fs/exec.c
index ccca70247..e2923fcfc 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1517,6 +1517,7 @@ static int do_execve_common(const char *filename,
bool clear_in_exec;
int retval;
const struct cred *cred = current_cred();
+ bool is_su;
/*
* We move the actual failure in case of RLIMIT_NPROC excess from
@@ -1593,11 +1594,14 @@ static int do_execve_common(const char *filename,
if (retval < 0)
goto out;
+ /* search_binary_handler can release file and it may be freed */
+ is_su = d_is_su(file->f_dentry);
+
retval = search_binary_handler(bprm);
if (retval < 0)
goto out;
- if (d_is_su(file->f_dentry) && capable(CAP_SYS_ADMIN)) {
+ if (is_su && capable(CAP_SYS_ADMIN)) {
current->flags |= PF_SU;
su_exec();
}