From 15fd1dc3dadb4268207fa6797e753541aca09a2a Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 18 Jan 2024 07:06:37 -0800 Subject: [PATCH 1/4] fs: binfmt_elf_efpic: don't use missing interpreter's properties Static FDPIC executable may get an executable stack even when it has non-executable GNU_STACK segment. This happens when STACK segment has rw permissions, but does not specify stack size. In that case FDPIC loader uses permissions of the interpreter's stack, and for static executables with no interpreter it results in choosing the arch-default permissions for the stack. Fix that by using the interpreter's properties only when the interpreter is actually used. Signed-off-by: Max Filippov Link: https://lore.kernel.org/r/20240118150637.660461-1-jcmvbkbc@gmail.com Signed-off-by: Kees Cook --- fs/binfmt_elf_fdpic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index fefc642541cb..1920ed69279b 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -320,7 +320,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) else executable_stack = EXSTACK_DEFAULT; - if (stack_size == 0) { + if (stack_size == 0 && interp_params.flags & ELF_FDPIC_FLAG_PRESENT) { stack_size = interp_params.stack_size; if (interp_params.flags & ELF_FDPIC_FLAG_EXEC_STACK) executable_stack = EXSTACK_ENABLE_X; From d3f0d7bbaefd3465e95da2500640732a5cc8bedf Mon Sep 17 00:00:00 2001 From: Li kunyu Date: Tue, 20 Feb 2024 13:24:26 +0800 Subject: [PATCH 2/4] exec: Delete unnecessary statements in remove_arg_zero() 'ret=0; ' In actual operation, the ret was not modified, so this sentence can be removed. Signed-off-by: Li kunyu Link: https://lore.kernel.org/r/20240220052426.62018-1-kunyu@nfschina.com Signed-off-by: Kees Cook --- fs/exec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/exec.c b/fs/exec.c index af4fbb61cd53..715e1a8aa4f0 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1747,7 +1747,6 @@ int remove_arg_zero(struct linux_binprm *bprm) bprm->p++; bprm->argc--; - ret = 0; out: return ret; From 17107429947b5d8a15f6dcef15c287eeade97258 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 5 Mar 2024 16:06:01 -0800 Subject: [PATCH 3/4] selftests/exec: Perform script checks with /bin/bash It seems some shells linked to /bin/sh don't have consistent behavior with error codes on execution failures. Explicitly use /bin/bash so that "not found" errors are correctly generated. Repeating the comment from the test: /* * Execute as a long pathname relative to "/". If this is a script, * the interpreter will launch but fail to open the script because its * name ("/dev/fd/5/xxx....") is bigger than PATH_MAX. * * The failure code is usually 127 (POSIX: "If a command is not found, * the exit status shall be 127."), but some systems give 126 (POSIX: * "If the command name is found, but it is not an executable utility, * the exit status shall be 126."), so allow either. */ Reported-by: Muhammad Usama Anjum Closes: https://lore.kernel.org/lkml/02c8bf8e-1934-44ab-a886-e065b37366a7@collabora.com/ Signed-off-by: Kees Cook --- Cc: Eric Biederman Cc: Shuah Khan Cc: Mark Brown Cc: linux-mm@kvack.org Cc: linux-kselftest@vger.kernel.org --- tools/testing/selftests/exec/execveat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/exec/execveat.c b/tools/testing/selftests/exec/execveat.c index bf79d664c8e6..0546ca24f2b2 100644 --- a/tools/testing/selftests/exec/execveat.c +++ b/tools/testing/selftests/exec/execveat.c @@ -393,7 +393,7 @@ static int run_tests(void) static void prerequisites(void) { int fd; - const char *script = "#!/bin/sh\nexit $*\n"; + const char *script = "#!/bin/bash\nexit $*\n"; /* Create ephemeral copies of files */ exe_cp("execveat", "execveat.ephemeral"); From 725d50261285ccf02501f2a1a6d10b31ce014597 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sat, 9 Mar 2024 13:46:30 -0800 Subject: [PATCH 4/4] exec: Simplify remove_arg_zero() error path We don't need the "out" label any more, so remove "ret" and return directly on error. Reviewed-by: Jan Kara Signed-off-by: Kees Cook --- Cc: Eric Biederman Cc: Alexander Viro Cc: Christian Brauner Cc: Jan Kara Cc: linux-mm@kvack.org Cc: linux-fsdevel@vger.kernel.org --- fs/exec.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index 715e1a8aa4f0..e7d9d6ad980b 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1720,7 +1720,6 @@ static int prepare_binprm(struct linux_binprm *bprm) */ int remove_arg_zero(struct linux_binprm *bprm) { - int ret = 0; unsigned long offset; char *kaddr; struct page *page; @@ -1731,10 +1730,8 @@ int remove_arg_zero(struct linux_binprm *bprm) do { offset = bprm->p & ~PAGE_MASK; page = get_arg_page(bprm, bprm->p, 0); - if (!page) { - ret = -EFAULT; - goto out; - } + if (!page) + return -EFAULT; kaddr = kmap_local_page(page); for (; offset < PAGE_SIZE && kaddr[offset]; @@ -1748,8 +1745,7 @@ int remove_arg_zero(struct linux_binprm *bprm) bprm->p++; bprm->argc--; -out: - return ret; + return 0; } EXPORT_SYMBOL(remove_arg_zero);