lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20241119104922.2772571-3-roberto.sassu@huaweicloud.com>
Date: Tue, 19 Nov 2024 11:49:09 +0100
From: Roberto Sassu <roberto.sassu@...weicloud.com>
To: zohar@...ux.ibm.com,
	dmitry.kasatkin@...il.com,
	eric.snowberg@...cle.com,
	corbet@....net,
	mcgrof@...nel.org,
	petr.pavlu@...e.com,
	samitolvanen@...gle.com,
	da.gomez@...sung.com,
	akpm@...ux-foundation.org,
	paul@...l-moore.com,
	jmorris@...ei.org,
	serge@...lyn.com,
	shuah@...nel.org,
	mcoquelin.stm32@...il.com,
	alexandre.torgue@...s.st.com
Cc: linux-integrity@...r.kernel.org,
	linux-doc@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	linux-api@...r.kernel.org,
	linux-modules@...r.kernel.org,
	linux-security-module@...r.kernel.org,
	linux-kselftest@...r.kernel.org,
	wufan@...ux.microsoft.com,
	pbrobinson@...il.com,
	zbyszek@...waw.pl,
	hch@....de,
	mjg59@...f.ucam.org,
	pmatilai@...hat.com,
	jannh@...gle.com,
	dhowells@...hat.com,
	jikos@...nel.org,
	mkoutny@...e.com,
	ppavlu@...e.com,
	petr.vorel@...il.com,
	mzerqung@...inter.de,
	kgold@...ux.ibm.com,
	Roberto Sassu <roberto.sassu@...wei.com>
Subject: [PATCH v6 02/15] module: Introduce ksys_finit_module()

From: Roberto Sassu <roberto.sassu@...wei.com>

Introduce ksys_finit_module() to let kernel components request a kernel
module without requiring running modprobe.

Signed-off-by: Roberto Sassu <roberto.sassu@...wei.com>
---
 include/linux/syscalls.h | 10 ++++++++++
 kernel/module/main.c     | 43 ++++++++++++++++++++++++++++++----------
 2 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 5758104921e6..18bb346bb793 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1233,6 +1233,16 @@ int ksys_ipc(unsigned int call, int first, unsigned long second,
 int compat_ksys_ipc(u32 call, int first, int second,
 	u32 third, u32 ptr, u32 fifth);
 
+#ifdef CONFIG_MODULES
+int ksys_finit_module(struct file *f, const char *kargs, int flags);
+#else
+static inline int ksys_finit_module(struct file *f, const char *kargs,
+				    int flags)
+{
+	return -EOPNOTSUPP;
+}
+#endif
+
 /*
  * The following kernel syscall equivalents are just wrappers to fs-internal
  * functions. Therefore, provide stubs to be inlined at the callsites.
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 49b9bca9de12..81f79c9ea637 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -2852,7 +2852,7 @@ static int early_mod_check(struct load_info *info, int flags)
  * zero, and we rely on this for optional sections.
  */
 static int load_module(struct load_info *info, const char __user *uargs,
-		       int flags)
+		       const char *kargs, int flags)
 {
 	struct module *mod;
 	bool module_allocated = false;
@@ -2953,7 +2953,13 @@ static int load_module(struct load_info *info, const char __user *uargs,
 	flush_module_icache(mod);
 
 	/* Now copy in args */
-	mod->args = strndup_user(uargs, ~0UL >> 1);
+	if (kargs) {
+		mod->args = kstrndup(kargs, ~0UL >> 1, GFP_KERNEL);
+		if (!mod->args)
+			mod->args = ERR_PTR(-ENOMEM);
+	} else {
+		mod->args = strndup_user(uargs, ~0UL >> 1);
+	}
 	if (IS_ERR(mod->args)) {
 		err = PTR_ERR(mod->args);
 		goto free_arch_cleanup;
@@ -3083,7 +3089,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
 		return err;
 	}
 
-	return load_module(&info, uargs, 0);
+	return load_module(&info, uargs, NULL, 0);
 }
 
 struct idempotent {
@@ -3170,7 +3176,8 @@ static int idempotent_wait_for_completion(struct idempotent *u)
 	return u->ret;
 }
 
-static int init_module_from_file(struct file *f, const char __user * uargs, int flags)
+static int init_module_from_file(struct file *f, const char __user * uargs,
+				 const char *kargs, int flags)
 {
 	struct load_info info = { };
 	void *buf = NULL;
@@ -3195,10 +3202,11 @@ static int init_module_from_file(struct file *f, const char __user * uargs, int
 		info.len = len;
 	}
 
-	return load_module(&info, uargs, flags);
+	return load_module(&info, uargs, kargs, flags);
 }
 
-static int idempotent_init_module(struct file *f, const char __user * uargs, int flags)
+static int idempotent_init_module(struct file *f, const char __user * uargs,
+				  const char *kargs, int flags)
 {
 	struct idempotent idem;
 
@@ -3207,7 +3215,7 @@ static int idempotent_init_module(struct file *f, const char __user * uargs, int
 
 	/* Are we the winners of the race and get to do this? */
 	if (!idempotent(&idem, file_inode(f))) {
-		int ret = init_module_from_file(f, uargs, flags);
+		int ret = init_module_from_file(f, uargs, kargs, flags);
 		return idempotent_complete(&idem, ret);
 	}
 
@@ -3217,15 +3225,16 @@ static int idempotent_init_module(struct file *f, const char __user * uargs, int
 	return idempotent_wait_for_completion(&idem);
 }
 
-SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
+static int _ksys_finit_module(struct file *f, int fd, const char __user * uargs,
+			      const char *kargs, int flags)
 {
 	int err;
-	struct fd f;
 
 	err = may_init_module();
 	if (err)
 		return err;
 
+	/* fd = -1 if called from the kernel. */
 	pr_debug("finit_module: fd=%d, uargs=%p, flags=%i\n", fd, uargs, flags);
 
 	if (flags & ~(MODULE_INIT_IGNORE_MODVERSIONS
@@ -3233,8 +3242,22 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
 		      |MODULE_INIT_COMPRESSED_FILE))
 		return -EINVAL;
 
+	err = idempotent_init_module(f, uargs, kargs, flags);
+	return err;
+}
+
+int ksys_finit_module(struct file *f, const char *kargs, int flags)
+{
+	return _ksys_finit_module(f, -1, NULL, kargs, flags);
+}
+
+SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
+{
+	int err;
+	struct fd f;
+
 	f = fdget(fd);
-	err = idempotent_init_module(fd_file(f), uargs, flags);
+	err = _ksys_finit_module(fd_file(f), fd, uargs, NULL, flags);
 	fdput(f);
 	return err;
 }
-- 
2.47.0.118.gfd3785337b


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ