diff mbox series

fs/binfmt_elf: Fix memory leak in load_elf_binary()

Message ID 20221024154421.982230-1-lizetao1@huawei.com (mailing list archive)
State New, archived
Headers show
Series fs/binfmt_elf: Fix memory leak in load_elf_binary() | expand

Commit Message

Li Zetao Oct. 24, 2022, 3:44 p.m. UTC
There is a memory leak reported by kmemleak:

  unreferenced object 0xffff88817104ef80 (size 224):
    comm "xfs_admin", pid 47165, jiffies 4298708825 (age 1333.476s)
    hex dump (first 32 bytes):
      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      60 a8 b3 00 81 88 ff ff a8 10 5a 00 81 88 ff ff  `.........Z.....
    backtrace:
      [<ffffffff819171e1>] __alloc_file+0x21/0x250
      [<ffffffff81918061>] alloc_empty_file+0x41/0xf0
      [<ffffffff81948cda>] path_openat+0xea/0x3d30
      [<ffffffff8194ec89>] do_filp_open+0x1b9/0x290
      [<ffffffff8192660e>] do_open_execat+0xce/0x5b0
      [<ffffffff81926b17>] open_exec+0x27/0x50
      [<ffffffff81a69250>] load_elf_binary+0x510/0x3ed0
      [<ffffffff81927759>] bprm_execve+0x599/0x1240
      [<ffffffff8192a997>] do_execveat_common.isra.0+0x4c7/0x680
      [<ffffffff8192b078>] __x64_sys_execve+0x88/0xb0
      [<ffffffff83bbf0a5>] do_syscall_64+0x35/0x80

If "interp_elf_ex" fails to allocate memory in load_elf_binary(),
the program will take the "out_free_ph" error handing path,
resulting in "interpreter" file resource is not released.

Fix it by adding an error handing path "out_free_file", which will
release the file resource when "interp_elf_ex" failed to allocate
memory.

Fixes: 0693ffebcfe5 ("fs/binfmt_elf.c: allocate less for static executable")
Signed-off-by: Li Zetao <lizetao1@huawei.com>
---
 fs/binfmt_elf.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Alexey Dobriyan Oct. 25, 2022, 7:02 p.m. UTC | #1
On Mon, Oct 24, 2022 at 11:44:21PM +0800, Li Zetao wrote:
> If "interp_elf_ex" fails to allocate memory in load_elf_binary(),
> the program will take the "out_free_ph" error handing path,
> resulting in "interpreter" file resource is not released.

Yes :-(

> --- a/fs/binfmt_elf.c
> +++ b/fs/binfmt_elf.c
> @@ -911,7 +911,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
>  		interp_elf_ex = kmalloc(sizeof(*interp_elf_ex), GFP_KERNEL);
>  		if (!interp_elf_ex) {
>  			retval = -ENOMEM;
> -			goto out_free_ph;
> +			goto out_free_file;

Reviewed-by: Alexey Dobriyan <adobriyan@gmail.com>
Kees Cook Oct. 25, 2022, 10:24 p.m. UTC | #2
On Mon, 24 Oct 2022 23:44:21 +0800, Li Zetao wrote:
> There is a memory leak reported by kmemleak:
> 
>   unreferenced object 0xffff88817104ef80 (size 224):
>     comm "xfs_admin", pid 47165, jiffies 4298708825 (age 1333.476s)
>     hex dump (first 32 bytes):
>       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
>       60 a8 b3 00 81 88 ff ff a8 10 5a 00 81 88 ff ff  `.........Z.....
>     backtrace:
>       [<ffffffff819171e1>] __alloc_file+0x21/0x250
>       [<ffffffff81918061>] alloc_empty_file+0x41/0xf0
>       [<ffffffff81948cda>] path_openat+0xea/0x3d30
>       [<ffffffff8194ec89>] do_filp_open+0x1b9/0x290
>       [<ffffffff8192660e>] do_open_execat+0xce/0x5b0
>       [<ffffffff81926b17>] open_exec+0x27/0x50
>       [<ffffffff81a69250>] load_elf_binary+0x510/0x3ed0
>       [<ffffffff81927759>] bprm_execve+0x599/0x1240
>       [<ffffffff8192a997>] do_execveat_common.isra.0+0x4c7/0x680
>       [<ffffffff8192b078>] __x64_sys_execve+0x88/0xb0
>       [<ffffffff83bbf0a5>] do_syscall_64+0x35/0x80
> 
> [...]

Applied to for-next/execve, thanks!

[1/1] fs/binfmt_elf: Fix memory leak in load_elf_binary()
      https://git.kernel.org/kees/c/594d2a14f216
diff mbox series

Patch

diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 63c7ebb0da89..6a11025e5850 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -911,7 +911,7 @@  static int load_elf_binary(struct linux_binprm *bprm)
 		interp_elf_ex = kmalloc(sizeof(*interp_elf_ex), GFP_KERNEL);
 		if (!interp_elf_ex) {
 			retval = -ENOMEM;
-			goto out_free_ph;
+			goto out_free_file;
 		}
 
 		/* Get the exec headers */
@@ -1354,6 +1354,7 @@  static int load_elf_binary(struct linux_binprm *bprm)
 out_free_dentry:
 	kfree(interp_elf_ex);
 	kfree(interp_elf_phdata);
+out_free_file:
 	allow_write_access(interpreter);
 	if (interpreter)
 		fput(interpreter);