Skip to content

Commit

Permalink
fs/binfmt_flat.c: make load_flat_shared_library() work
Browse files Browse the repository at this point in the history
load_flat_shared_library() is broken: It only calls load_flat_file() if
prepare_binprm() returns zero, but prepare_binprm() returns the number of
bytes read - so this only happens if the file is empty.

Instead, call into load_flat_file() if the number of bytes read is
non-negative. (Even if the number of bytes is zero - in that case,
load_flat_file() will see nullbytes and return a nice -ENOEXEC.)

In addition, remove the code related to bprm creds and stop using
prepare_binprm() - this code is loading a library, not a main executable,
and it only actually uses the members "buf", "file" and "filename" of the
linux_binprm struct. Instead, call kernel_read() directly.

Link: http://lkml.kernel.org/r/[email protected]
Fixes: 287980e ("remove lots of IS_ERR_VALUE abuses")
Signed-off-by: Jann Horn <[email protected]>
Cc: Alexander Viro <[email protected]>
Cc: Kees Cook <[email protected]>
Cc: Nicolas Pitre <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Geert Uytterhoeven <[email protected]>
Cc: Russell King <[email protected]>
Cc: Greg Ungerer <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
thejh authored and torvalds committed Jun 29, 2019
1 parent 29b190f commit 867bfa4
Showing 1 changed file with 7 additions and 16 deletions.
23 changes: 7 additions & 16 deletions fs/binfmt_flat.c
Original file line number Diff line number Diff line change
Expand Up @@ -856,9 +856,14 @@ static int load_flat_file(struct linux_binprm *bprm,

static int load_flat_shared_library(int id, struct lib_info *libs)
{
/*
* This is a fake bprm struct; only the members "buf", "file" and
* "filename" are actually used.
*/
struct linux_binprm bprm;
int res;
char buf[16];
loff_t pos = 0;

memset(&bprm, 0, sizeof(bprm));

Expand All @@ -872,25 +877,11 @@ static int load_flat_shared_library(int id, struct lib_info *libs)
if (IS_ERR(bprm.file))
return res;

bprm.cred = prepare_exec_creds();
res = -ENOMEM;
if (!bprm.cred)
goto out;

/* We don't really care about recalculating credentials at this point
* as we're past the point of no return and are dealing with shared
* libraries.
*/
bprm.called_set_creds = 1;
res = kernel_read(bprm.file, bprm.buf, BINPRM_BUF_SIZE, &pos);

res = prepare_binprm(&bprm);

if (!res)
if (res >= 0)
res = load_flat_file(&bprm, libs, id, NULL);

abort_creds(bprm.cred);

out:
allow_write_access(bprm.file);
fput(bprm.file);

Expand Down

0 comments on commit 867bfa4

Please sign in to comment.