[RFC PATCH] fs: remove uselib() system call

Christian Brauner posted 1 patch 9 months, 4 weeks ago
arch/m68k/configs/amcore_defconfig         |  1 -
arch/x86/configs/i386_defconfig            |  1 -
arch/xtensa/configs/cadence_csp_defconfig  |  1 -
fs/binfmt_elf.c                            | 76 ----------------------
fs/exec.c                                  | 60 -----------------
include/linux/binfmts.h                    |  1 -
init/Kconfig                               | 10 ---
tools/testing/selftests/bpf/config.aarch64 |  1 -
tools/testing/selftests/bpf/config.s390x   |  1 -
9 files changed, 152 deletions(-)
[RFC PATCH] fs: remove uselib() system call
Posted by Christian Brauner 9 months, 4 weeks ago
This system call has been deprecated for quite a while now.
Let's try and remove it from the kernel completely.

Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 arch/m68k/configs/amcore_defconfig         |  1 -
 arch/x86/configs/i386_defconfig            |  1 -
 arch/xtensa/configs/cadence_csp_defconfig  |  1 -
 fs/binfmt_elf.c                            | 76 ----------------------
 fs/exec.c                                  | 60 -----------------
 include/linux/binfmts.h                    |  1 -
 init/Kconfig                               | 10 ---
 tools/testing/selftests/bpf/config.aarch64 |  1 -
 tools/testing/selftests/bpf/config.s390x   |  1 -
 9 files changed, 152 deletions(-)

diff --git a/arch/m68k/configs/amcore_defconfig b/arch/m68k/configs/amcore_defconfig
index 110279a64aa4..60767811e34a 100644
--- a/arch/m68k/configs/amcore_defconfig
+++ b/arch/m68k/configs/amcore_defconfig
@@ -2,7 +2,6 @@ CONFIG_LOCALVERSION="amcore-002"
 CONFIG_DEFAULT_HOSTNAME="amcore"
 CONFIG_SYSVIPC=y
 # CONFIG_FHANDLE is not set
-# CONFIG_USELIB is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_AIO is not set
diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig
index 91801138b10b..7cd2f395f301 100644
--- a/arch/x86/configs/i386_defconfig
+++ b/arch/x86/configs/i386_defconfig
@@ -1,7 +1,6 @@
 CONFIG_WERROR=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_USELIB=y
 CONFIG_AUDIT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
diff --git a/arch/xtensa/configs/cadence_csp_defconfig b/arch/xtensa/configs/cadence_csp_defconfig
index 91c4c4cae8a7..49f50d1bd724 100644
--- a/arch/xtensa/configs/cadence_csp_defconfig
+++ b/arch/xtensa/configs/cadence_csp_defconfig
@@ -1,6 +1,5 @@
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_USELIB=y
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IRQ_TIME_ACCOUNTING=y
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 584fa89bc877..7e2afe3220f7 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -68,12 +68,6 @@
 
 static int load_elf_binary(struct linux_binprm *bprm);
 
-#ifdef CONFIG_USELIB
-static int load_elf_library(struct file *);
-#else
-#define load_elf_library NULL
-#endif
-
 /*
  * If we don't support core dumping, then supply a NULL so we
  * don't even try.
@@ -101,7 +95,6 @@ static int elf_core_dump(struct coredump_params *cprm);
 static struct linux_binfmt elf_format = {
 	.module		= THIS_MODULE,
 	.load_binary	= load_elf_binary,
-	.load_shlib	= load_elf_library,
 #ifdef CONFIG_COREDUMP
 	.core_dump	= elf_core_dump,
 	.min_coredump	= ELF_EXEC_PAGESIZE,
@@ -1361,75 +1354,6 @@ static int load_elf_binary(struct linux_binprm *bprm)
 	goto out;
 }
 
-#ifdef CONFIG_USELIB
-/* This is really simpleminded and specialized - we are loading an
-   a.out library that is given an ELF header. */
-static int load_elf_library(struct file *file)
-{
-	struct elf_phdr *elf_phdata;
-	struct elf_phdr *eppnt;
-	int retval, error, i, j;
-	struct elfhdr elf_ex;
-
-	error = -ENOEXEC;
-	retval = elf_read(file, &elf_ex, sizeof(elf_ex), 0);
-	if (retval < 0)
-		goto out;
-
-	if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
-		goto out;
-
-	/* First of all, some simple consistency checks */
-	if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
-	    !elf_check_arch(&elf_ex) || !file->f_op->mmap)
-		goto out;
-	if (elf_check_fdpic(&elf_ex))
-		goto out;
-
-	/* Now read in all of the header information */
-
-	j = sizeof(struct elf_phdr) * elf_ex.e_phnum;
-	/* j < ELF_MIN_ALIGN because elf_ex.e_phnum <= 2 */
-
-	error = -ENOMEM;
-	elf_phdata = kmalloc(j, GFP_KERNEL);
-	if (!elf_phdata)
-		goto out;
-
-	eppnt = elf_phdata;
-	error = -ENOEXEC;
-	retval = elf_read(file, eppnt, j, elf_ex.e_phoff);
-	if (retval < 0)
-		goto out_free_ph;
-
-	for (j = 0, i = 0; i<elf_ex.e_phnum; i++)
-		if ((eppnt + i)->p_type == PT_LOAD)
-			j++;
-	if (j != 1)
-		goto out_free_ph;
-
-	while (eppnt->p_type != PT_LOAD)
-		eppnt++;
-
-	/* Now use mmap to map the library into memory. */
-	error = elf_load(file, ELF_PAGESTART(eppnt->p_vaddr),
-			eppnt,
-			PROT_READ | PROT_WRITE | PROT_EXEC,
-			MAP_FIXED_NOREPLACE | MAP_PRIVATE,
-			0);
-
-	if (error != ELF_PAGESTART(eppnt->p_vaddr))
-		goto out_free_ph;
-
-	error = 0;
-
-out_free_ph:
-	kfree(elf_phdata);
-out:
-	return error;
-}
-#endif /* #ifdef CONFIG_USELIB */
-
 #ifdef CONFIG_ELF_CORE
 /*
  * ELF core dumper
diff --git a/fs/exec.c b/fs/exec.c
index 8e4ea5f1e64c..cfbb2b9ee3c9 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -115,66 +115,6 @@ bool path_noexec(const struct path *path)
 	       (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC);
 }
 
-#ifdef CONFIG_USELIB
-/*
- * Note that a shared library must be both readable and executable due to
- * security reasons.
- *
- * Also note that we take the address to load from the file itself.
- */
-SYSCALL_DEFINE1(uselib, const char __user *, library)
-{
-	struct linux_binfmt *fmt;
-	struct file *file;
-	struct filename *tmp = getname(library);
-	int error = PTR_ERR(tmp);
-	static const struct open_flags uselib_flags = {
-		.open_flag = O_LARGEFILE | O_RDONLY,
-		.acc_mode = MAY_READ | MAY_EXEC,
-		.intent = LOOKUP_OPEN,
-		.lookup_flags = LOOKUP_FOLLOW,
-	};
-
-	if (IS_ERR(tmp))
-		goto out;
-
-	file = do_filp_open(AT_FDCWD, tmp, &uselib_flags);
-	putname(tmp);
-	error = PTR_ERR(file);
-	if (IS_ERR(file))
-		goto out;
-
-	/*
-	 * Check do_open_execat() for an explanation.
-	 */
-	error = -EACCES;
-	if (WARN_ON_ONCE(!S_ISREG(file_inode(file)->i_mode)) ||
-	    path_noexec(&file->f_path))
-		goto exit;
-
-	error = -ENOEXEC;
-
-	read_lock(&binfmt_lock);
-	list_for_each_entry(fmt, &formats, lh) {
-		if (!fmt->load_shlib)
-			continue;
-		if (!try_module_get(fmt->module))
-			continue;
-		read_unlock(&binfmt_lock);
-		error = fmt->load_shlib(file);
-		read_lock(&binfmt_lock);
-		put_binfmt(fmt);
-		if (error != -ENOEXEC)
-			break;
-	}
-	read_unlock(&binfmt_lock);
-exit:
-	fput(file);
-out:
-	return error;
-}
-#endif /* #ifdef CONFIG_USELIB */
-
 #ifdef CONFIG_MMU
 /*
  * The nascent bprm->mm is not visible until exec_mmap() but it can
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 1625c8529e70..65abd5ab8836 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -90,7 +90,6 @@ struct linux_binfmt {
 	struct list_head lh;
 	struct module *module;
 	int (*load_binary)(struct linux_binprm *);
-	int (*load_shlib)(struct file *);
 #ifdef CONFIG_COREDUMP
 	int (*core_dump)(struct coredump_params *cprm);
 	unsigned long min_coredump;	/* minimal dump size */
diff --git a/init/Kconfig b/init/Kconfig
index 63f5974b9fa6..b7cc7f5b2595 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -479,16 +479,6 @@ config CROSS_MEMORY_ATTACH
 	  to directly read from or write to another process' address space.
 	  See the man page for more details.
 
-config USELIB
-	bool "uselib syscall (for libc5 and earlier)"
-	default ALPHA || M68K || SPARC
-	help
-	  This option enables the uselib syscall, a system call used in the
-	  dynamic linker from libc5 and earlier.  glibc does not use this
-	  system call.  If you intend to run programs built on libc5 or
-	  earlier, you may need to enable this syscall.  Current systems
-	  running glibc can safely disable this.
-
 config AUDIT
 	bool "Auditing support"
 	depends on NET
diff --git a/tools/testing/selftests/bpf/config.aarch64 b/tools/testing/selftests/bpf/config.aarch64
index 3720b7611523..e1495a4bbc99 100644
--- a/tools/testing/selftests/bpf/config.aarch64
+++ b/tools/testing/selftests/bpf/config.aarch64
@@ -158,7 +158,6 @@ CONFIG_TRANSPARENT_HUGEPAGE=y
 CONFIG_TUN=y
 CONFIG_UNIX=y
 CONFIG_UPROBES=y
-CONFIG_USELIB=y
 CONFIG_USER_NS=y
 CONFIG_VETH=y
 CONFIG_VLAN_8021Q=y
diff --git a/tools/testing/selftests/bpf/config.s390x b/tools/testing/selftests/bpf/config.s390x
index 706931a8c2c6..26c3bc2ce11d 100644
--- a/tools/testing/selftests/bpf/config.s390x
+++ b/tools/testing/selftests/bpf/config.s390x
@@ -128,7 +128,6 @@ CONFIG_TRANSPARENT_HUGEPAGE=y
 CONFIG_TUN=y
 CONFIG_UNIX=y
 CONFIG_UPROBES=y
-CONFIG_USELIB=y
 CONFIG_USER_NS=y
 CONFIG_VETH=y
 CONFIG_VLAN_8021Q=y
-- 
2.47.2
Re: [RFC PATCH] fs: remove uselib() system call
Posted by Geert Uytterhoeven 8 months, 2 weeks ago
Hi Christian,

On Tue, 15 Apr 2025 at 10:31, Christian Brauner <brauner@kernel.org> wrote:
> This system call has been deprecated for quite a while now.
> Let's try and remove it from the kernel completely.
>
> Signed-off-by: Christian Brauner <brauner@kernel.org>

Thanks for your patch, which is now commit 79beea2db0431536 ("fs:
remove uselib() system call") upstream.

> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -479,16 +479,6 @@ config CROSS_MEMORY_ATTACH
>           to directly read from or write to another process' address space.
>           See the man page for more details.
>
> -config USELIB
> -       bool "uselib syscall (for libc5 and earlier)"
> -       default ALPHA || M68K || SPARC
> -       help
> -         This option enables the uselib syscall, a system call used in the
> -         dynamic linker from libc5 and earlier.  glibc does not use this
> -         system call.  If you intend to run programs built on libc5 or
> -         earlier, you may need to enable this syscall.  Current systems
> -         running glibc can safely disable this.
> -
>  config AUDIT
>         bool "Auditing support"
>         depends on NET

FTR, after this m68k machines can still boot the good old
filesys-ELF-2.0.x-1400K-2.gz ramdisk (containing libc5 and these new
kind of binaries called "ELF" ;-) from 1996 fine.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
Re: [RFC PATCH] fs: remove uselib() system call
Posted by Christian Brauner 9 months, 3 weeks ago
On Tue, 15 Apr 2025 10:27:50 +0200, Christian Brauner wrote:
> This system call has been deprecated for quite a while now.
> Let's try and remove it from the kernel completely.
> 
> 

Applied to the vfs-6.16.misc branch of the vfs/vfs.git tree.
Patches in the vfs-6.16.misc branch should appear in linux-next soon.

Please report any outstanding bugs that were missed during review in a
new review to the original patch series allowing us to drop it.

It's encouraged to provide Acked-bys and Reviewed-bys even though the
patch has now been applied. If possible patch trailers will be updated.

Note that commit hashes shown below are subject to change due to rebase,
trailer updates or similar. If in doubt, please check the listed branch.

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
branch: vfs-6.16.misc

[1/1] fs: remove uselib() system call
      https://git.kernel.org/vfs/vfs/c/2a6ca7a03bc9
Re: [RFC PATCH] fs: remove uselib() system call
Posted by Kees Cook 9 months, 4 weeks ago
On Tue, Apr 15, 2025 at 10:27:50AM +0200, Christian Brauner wrote:
> This system call has been deprecated for quite a while now.
> Let's try and remove it from the kernel completely.
> 
> Signed-off-by: Christian Brauner <brauner@kernel.org>

Yes please. Though I see Debian still has this enabled for alpha and
m68k:
https://salsa.debian.org/kernel-team/linux/-/blob/debian/latest/debian/config/alpha/config#L779
https://salsa.debian.org/kernel-team/linux/-/blob/debian/latest/debian/config/m68k/config#L684

Acked-by: Kees Cook <kees@kernel.org>

-- 
Kees Cook
Re: [RFC PATCH] fs: remove uselib() system call
Posted by Christian Brauner 9 months, 3 weeks ago
On Tue, Apr 15, 2025 at 09:39:53AM -0700, Kees Cook wrote:
> On Tue, Apr 15, 2025 at 10:27:50AM +0200, Christian Brauner wrote:
> > This system call has been deprecated for quite a while now.
> > Let's try and remove it from the kernel completely.
> > 
> > Signed-off-by: Christian Brauner <brauner@kernel.org>
> 
> Yes please. Though I see Debian still has this enabled for alpha and
> m68k:
> https://salsa.debian.org/kernel-team/linux/-/blob/debian/latest/debian/config/alpha/config#L779
> https://salsa.debian.org/kernel-team/linux/-/blob/debian/latest/debian/config/m68k/config#L684

Let's just try it. If we fail we'll try again next year. Keeping the
pressure up. :) The reverts should all be fairly simple and I'll keep
the burden for Linus low by doing them myself if we have to.