All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH V2 1/3] tst_module: Add separate declarations of helpers for new tests framework
@ 2020-12-17  7:27 Viresh Kumar
  2020-12-17  7:27 ` [LTP] [PATCH V2 2/3] syscalls: init_module: Add tests Viresh Kumar
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Viresh Kumar @ 2020-12-17  7:27 UTC (permalink / raw)
  To: ltp

The tests using the new test framework must not use the headers from the
old one, fix that by declaring the helpers in tst_module.h. To achieve
that rename the original routines in tst_module.c with an underscore and
use static inline wrappers to call them.

Also update the delete_module tests to use the new header.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
V2:
- New patch.

 include/old/old_module.h                      | 27 ++++++++++++---
 include/tst_module.h                          | 33 +++++++++++++++++++
 lib/tst_module.c                              |  8 ++---
 .../syscalls/delete_module/delete_module01.c  |  6 ++--
 .../syscalls/delete_module/delete_module03.c  | 12 +++----
 5 files changed, 68 insertions(+), 18 deletions(-)
 create mode 100644 include/tst_module.h

diff --git a/include/old/old_module.h b/include/old/old_module.h
index c50efec76244..1af7d1f68027 100644
--- a/include/old/old_module.h
+++ b/include/old/old_module.h
@@ -34,6 +34,14 @@
 #ifndef TST_MODULE
 #define TST_MODULE
 
+void tst_module_exist_(void (cleanup_fn)(void), const char *mod_name,
+					 char **mod_path);
+
+void tst_module_load_(void (cleanup_fn)(void), const char *mod_name,
+					char *const argv[]);
+
+void tst_module_unload_(void (cleanup_fn)(void), const char *mod_name);
+
 /*
  * Check module existence.
  *
@@ -44,8 +52,11 @@
  *
  * In case of failure, test'll call cleanup_fn and exit with TCONF return value.
  */
-void tst_module_exist(void (cleanup_fn)(void), const char *mod_name,
-	char **mod_path);
+static inline void tst_module_exist(void (cleanup_fn)(void),
+				    const char *mod_name, char **mod_path)
+{
+	tst_module_exist_(cleanup_fn, mod_name, mod_path);
+}
 
 /*
  * Load a module using insmod program.
@@ -58,8 +69,11 @@ void tst_module_exist(void (cleanup_fn)(void), const char *mod_name,
  * In case of insmod failure, test will call cleanup_fn and exit with TBROK
  * return value.
  */
-void tst_module_load(void (cleanup_fn)(void),
-	const char *mod_name, char *const argv[]);
+static inline void tst_module_load(void (cleanup_fn)(void),
+				   const char *mod_name, char *const argv[])
+{
+	tst_module_load_(cleanup_fn, mod_name, argv);
+}
 
 /*
  * Unload a module using rmmod program. In case of failure, test will call
@@ -67,6 +81,9 @@ void tst_module_load(void (cleanup_fn)(void),
  *
  * @mod_name: can be module name or module's file name.
  */
-void tst_module_unload(void (cleanup_fn)(void), const char *mod_name);
+static inline void tst_module_unload(void (cleanup_fn)(void), const char *mod_name)
+{
+	tst_module_unload_(cleanup_fn, mod_name);
+}
 
 #endif /* TST_MODULE */
diff --git a/include/tst_module.h b/include/tst_module.h
new file mode 100644
index 000000000000..637e85c0bf2f
--- /dev/null
+++ b/include/tst_module.h
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
+ * Alexey Kodanev <alexey.kodanev@oracle.com>
+ */
+
+#ifndef TST_MODULE_H
+#define TST_MODULE_H
+
+void tst_module_exist_(void (cleanup_fn)(void), const char *mod_name,
+					 char **mod_path);
+
+static inline void tst_module_exist(const char *mod_name, char **mod_path)
+{
+	tst_module_exist_(NULL, mod_name, mod_path);
+}
+
+void tst_module_load_(void (cleanup_fn)(void), const char *mod_name,
+					char *const argv[]);
+
+static inline void tst_module_load(const char *mod_name, char *const argv[])
+{
+	tst_module_load_(NULL, mod_name, argv);
+}
+
+void tst_module_unload_(void (cleanup_fn)(void), const char *mod_name);
+
+static inline void tst_module_unload(const char *mod_name)
+{
+	tst_module_unload_(NULL, mod_name);
+}
+
+#endif /* TST_MODULE_H */
diff --git a/lib/tst_module.c b/lib/tst_module.c
index eda61872fe01..9bd443623616 100644
--- a/lib/tst_module.c
+++ b/lib/tst_module.c
@@ -28,7 +28,7 @@
 #include "ltp_priv.h"
 #include "old_module.h"
 
-void tst_module_exists(void (cleanup_fn)(void),
+void tst_module_exists_(void (cleanup_fn)(void),
 	const char *mod_name, char **mod_path)
 {
 	/* check current working directory */
@@ -77,11 +77,11 @@ void tst_module_exists(void (cleanup_fn)(void),
 		free(buf);
 }
 
-void tst_module_load(void (cleanup_fn)(void),
+void tst_module_load_(void (cleanup_fn)(void),
 	const char *mod_name, char *const argv[])
 {
 	char *mod_path = NULL;
-	tst_module_exists(cleanup_fn, mod_name, &mod_path);
+	tst_module_exists_(cleanup_fn, mod_name, &mod_path);
 
 	const int offset = 2; /* command name & module path */
 	int size = 0;
@@ -101,7 +101,7 @@ void tst_module_load(void (cleanup_fn)(void),
 	free(mod_path);
 }
 
-void tst_module_unload(void (cleanup_fn)(void), const char *mod_name)
+void tst_module_unload_(void (cleanup_fn)(void), const char *mod_name)
 {
 	int i, rc;
 
diff --git a/testcases/kernel/syscalls/delete_module/delete_module01.c b/testcases/kernel/syscalls/delete_module/delete_module01.c
index e5cb53cc9ec3..8fb559f0c703 100644
--- a/testcases/kernel/syscalls/delete_module/delete_module01.c
+++ b/testcases/kernel/syscalls/delete_module/delete_module01.c
@@ -14,9 +14,9 @@
  */
 
 #include <errno.h>
-#include "old_module.h"
 #include "lapi/syscalls.h"
 #include "tst_test.h"
+#include "tst_module.h"
 
 #define MODULE_NAME	"dummy_del_mod"
 #define MODULE_NAME_KO	"dummy_del_mod.ko"
@@ -26,7 +26,7 @@ static int module_loaded;
 static void do_delete_module(void)
 {
 	if (module_loaded == 0) {
-		tst_module_load(NULL, MODULE_NAME_KO, NULL);
+		tst_module_load(MODULE_NAME_KO, NULL);
 		module_loaded = 1;
 	}
 
@@ -44,7 +44,7 @@ static void do_delete_module(void)
 static void cleanup(void)
 {
 	if (module_loaded == 1)
-		tst_module_unload(NULL, MODULE_NAME_KO);
+		tst_module_unload(MODULE_NAME_KO);
 }
 
 static struct tst_test test = {
diff --git a/testcases/kernel/syscalls/delete_module/delete_module03.c b/testcases/kernel/syscalls/delete_module/delete_module03.c
index 8bd51be07dc2..7178e8ef13b0 100644
--- a/testcases/kernel/syscalls/delete_module/delete_module03.c
+++ b/testcases/kernel/syscalls/delete_module/delete_module03.c
@@ -14,7 +14,7 @@
 
 #include <errno.h>
 #include "tst_test.h"
-#include "old_module.h"
+#include "tst_module.h"
 #include "lapi/syscalls.h"
 
 #define DUMMY_MOD		"dummy_del_mod"
@@ -43,7 +43,7 @@ static void do_delete_module(void)
 		 * insmod DUMMY_MOD_KO again in case running
 		 * with -i option
 		 */
-		tst_module_load(NULL, DUMMY_MOD_KO, NULL);
+		tst_module_load(DUMMY_MOD_KO, NULL);
 		dummy_mod_loaded = 1;
 	}
 }
@@ -51,11 +51,11 @@ static void do_delete_module(void)
 static void setup(void)
 {
 	/* Load first kernel module */
-	tst_module_load(NULL, DUMMY_MOD_KO, NULL);
+	tst_module_load(DUMMY_MOD_KO, NULL);
 	dummy_mod_loaded = 1;
 
 	/* Load dependant kernel module */
-	tst_module_load(NULL, DUMMY_MOD_DEP_KO, NULL);
+	tst_module_load(DUMMY_MOD_DEP_KO, NULL);
 	dummy_mod_dep_loaded = 1;
 }
 
@@ -63,11 +63,11 @@ static void cleanup(void)
 {
 	/* Unload dependent kernel module */
 	if (dummy_mod_dep_loaded == 1)
-		tst_module_unload(NULL, DUMMY_MOD_DEP_KO);
+		tst_module_unload(DUMMY_MOD_DEP_KO);
 
 	/* Unload first kernel module */
 	if (dummy_mod_loaded == 1)
-		tst_module_unload(NULL, DUMMY_MOD_KO);
+		tst_module_unload(DUMMY_MOD_KO);
 }
 
 static struct tst_test test = {
-- 
2.25.0.rc1.19.g042ed3e048af


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [LTP] [PATCH V2 2/3] syscalls: init_module: Add tests
  2020-12-17  7:27 [LTP] [PATCH V2 1/3] tst_module: Add separate declarations of helpers for new tests framework Viresh Kumar
@ 2020-12-17  7:27 ` Viresh Kumar
  2020-12-17 10:03   ` Cyril Hrubis
  2020-12-17  7:27 ` [LTP] [PATCH V2 3/3] syscalls: finit_module: " Viresh Kumar
  2020-12-17 10:01 ` [LTP] [PATCH V2 1/3] tst_module: Add separate declarations of helpers for new tests framework Cyril Hrubis
  2 siblings, 1 reply; 11+ messages in thread
From: Viresh Kumar @ 2020-12-17  7:27 UTC (permalink / raw)
  To: ltp

This patch adds success and failure tests for init_module() syscall.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
V2:
- Remove unwanted header
- Use TST_EXP_*() macros
- Always provide definition of init_module().
- Rename module.

 include/lapi/init_module.h                    | 19 ++++
 runtest/syscalls                              |  3 +
 .../kernel/syscalls/init_module/.gitignore    |  3 +
 .../kernel/syscalls/init_module/Makefile      | 21 ++++
 .../kernel/syscalls/init_module/init_module.c | 37 +++++++
 .../syscalls/init_module/init_module01.c      | 54 ++++++++++
 .../syscalls/init_module/init_module02.c      | 99 +++++++++++++++++++
 7 files changed, 236 insertions(+)
 create mode 100644 include/lapi/init_module.h
 create mode 100644 testcases/kernel/syscalls/init_module/.gitignore
 create mode 100644 testcases/kernel/syscalls/init_module/Makefile
 create mode 100644 testcases/kernel/syscalls/init_module/init_module.c
 create mode 100644 testcases/kernel/syscalls/init_module/init_module01.c
 create mode 100644 testcases/kernel/syscalls/init_module/init_module02.c

diff --git a/include/lapi/init_module.h b/include/lapi/init_module.h
new file mode 100644
index 000000000000..65ff70356c60
--- /dev/null
+++ b/include/lapi/init_module.h
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 Linaro Limited. All rights reserved.
+ * Author: Viresh Kumar <viresh.kumar@linaro.org>
+ */
+
+#ifndef INIT_MODULE_H__
+#define INIT_MODULE_H__
+
+#include "config.h"
+#include "lapi/syscalls.h"
+#include "tst_test.h"
+
+static inline int init_module(void *module_image, unsigned long len,
+			      const char *param_values)
+{
+	return tst_syscall(__NR_init_module, module_image, len, param_values);
+}
+#endif /* INIT_MODULE_H__ */
diff --git a/runtest/syscalls b/runtest/syscalls
index 9c328697b4a3..28174dddd716 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -517,6 +517,9 @@ getxattr03 getxattr03
 getxattr04 getxattr04
 getxattr05 getxattr05
 
+init_module01 init_module01
+init_module02 init_module02
+
 #Needs tty device.
 #ioctl01 ioctl01 -D /dev/tty0
 #ioctl02 ioctl02 -D /dev/tty0
diff --git a/testcases/kernel/syscalls/init_module/.gitignore b/testcases/kernel/syscalls/init_module/.gitignore
new file mode 100644
index 000000000000..b4d11e958544
--- /dev/null
+++ b/testcases/kernel/syscalls/init_module/.gitignore
@@ -0,0 +1,3 @@
+/init_module01
+/init_module02
+/*.ko
diff --git a/testcases/kernel/syscalls/init_module/Makefile b/testcases/kernel/syscalls/init_module/Makefile
new file mode 100644
index 000000000000..ebdca67d401d
--- /dev/null
+++ b/testcases/kernel/syscalls/init_module/Makefile
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+ifneq ($(KERNELRELEASE),)
+
+obj-m := init_module.o
+
+else
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+REQ_VERSION_MAJOR	:= 2
+REQ_VERSION_PATCH	:= 6
+
+MAKE_TARGETS		:= init_module01 init_module02 init_module.ko
+
+include $(top_srcdir)/include/mk/module.mk
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
+
+endif
diff --git a/testcases/kernel/syscalls/init_module/init_module.c b/testcases/kernel/syscalls/init_module/init_module.c
new file mode 100644
index 000000000000..78d03b899a7e
--- /dev/null
+++ b/testcases/kernel/syscalls/init_module/init_module.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org>
+ *
+ * Dummy test module.
+ *
+ * The module accepts a single argument named "status" and it fails
+ * initialization if the status is set to "invalid".
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/kernel.h>
+
+static char status[20];
+module_param_string(status, status, 20, 0444);
+
+static int dummy_init(void)
+{
+	struct proc_dir_entry *proc_dummy;
+
+	if (!strcmp(status, "invalid"))
+		return -EINVAL;
+
+	proc_dummy = proc_mkdir("dummy", 0);
+	return 0;
+}
+module_init(dummy_init);
+
+static void dummy_exit(void)
+{
+	remove_proc_entry("dummy", 0);
+}
+module_exit(dummy_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/testcases/kernel/syscalls/init_module/init_module01.c b/testcases/kernel/syscalls/init_module/init_module01.c
new file mode 100644
index 000000000000..478ccf1c5fdf
--- /dev/null
+++ b/testcases/kernel/syscalls/init_module/init_module01.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org>
+ */
+
+/*\
+ * [DESCRIPTION]
+ *
+ * Basic init_module() tests.
+ *
+ * [ALGORITHM]
+ *
+ * Inserts a simple module after opening and mmaping the module file.
+\*/
+
+#include <errno.h>
+#include "lapi/init_module.h"
+#include "tst_module.h"
+
+#define MODULE_NAME	"init_module.ko"
+
+static struct stat sb;
+static void *buf;
+
+static void setup(void)
+{
+	int fd;
+
+	fd = SAFE_OPEN(MODULE_NAME, O_RDONLY|O_CLOEXEC);
+	SAFE_FSTAT(fd, &sb);
+	buf = SAFE_MMAP(0, sb.st_size, PROT_READ|PROT_EXEC, MAP_PRIVATE, fd, 0);
+	SAFE_CLOSE(fd);
+}
+
+static void run(void)
+{
+	TST_EXP_PASS(init_module(buf, sb.st_size, "status=valid"));
+	if (!TST_PASS)
+		return;
+
+	tst_module_unload(MODULE_NAME);
+}
+
+static void cleanup(void)
+{
+	munmap(buf, sb.st_size);
+}
+
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.cleanup = cleanup,
+	.needs_root = 1,
+};
diff --git a/testcases/kernel/syscalls/init_module/init_module02.c b/testcases/kernel/syscalls/init_module/init_module02.c
new file mode 100644
index 000000000000..102242dba98d
--- /dev/null
+++ b/testcases/kernel/syscalls/init_module/init_module02.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org>
+ */
+
+/*\
+ * [DESCRIPTION]
+ *
+ * Basic init_module() failure tests.
+ *
+ * [ALGORITHM]
+ *
+ * Tests various failure scenarios for init_module().
+\*/
+
+#include <linux/capability.h>
+#include <errno.h>
+#include "lapi/init_module.h"
+#include "tst_module.h"
+#include "tst_capability.h"
+
+#define MODULE_NAME	"init_module.ko"
+
+static unsigned long size, zero_size;
+static void *buf, *faulty_buf, *null_buf;
+
+static struct tst_cap cap_req = TST_CAP(TST_CAP_REQ, CAP_SYS_MODULE);
+static struct tst_cap cap_drop = TST_CAP(TST_CAP_DROP, CAP_SYS_MODULE);
+
+static struct tcase {
+	const char *name;
+	void **buf;
+	unsigned long *size;
+	const char *param;
+	int cap;
+	int exp_errno;
+} tcases[] = {
+	{"NULL-buffer", &null_buf, &size, "", 0, EFAULT},
+	{"faulty-buffer", &faulty_buf, &size, "", 0, EFAULT},
+	{"null-param", &buf, &size, NULL, 0, EFAULT},
+	{"zero-size", &buf, &zero_size, "", 0, ENOEXEC},
+	{"invalid_param", &buf, &size, "status=invalid", 0, EINVAL},
+	{"no-perm", &buf, &size, "", 1, EPERM},
+	{"module-exists", &buf, &size, "", 0, EEXIST},
+};
+
+static void setup(void)
+{
+	struct stat sb;
+	int fd;
+
+	fd = SAFE_OPEN(MODULE_NAME, O_RDONLY|O_CLOEXEC);
+	SAFE_FSTAT(fd, &sb);
+	size = sb.st_size;
+	buf = SAFE_MMAP(0, size, PROT_READ|PROT_EXEC, MAP_PRIVATE, fd, 0);
+	SAFE_CLOSE(fd);
+
+	faulty_buf = tst_get_bad_addr(NULL);
+}
+
+static void run(unsigned int n)
+{
+	struct tcase *tc = &tcases[n];
+
+	if (tc->cap)
+		tst_cap_action(&cap_drop);
+
+	/* Insert module twice */
+	if (tc->exp_errno == EEXIST) {
+		TST_EXP_PASS(init_module(*tc->buf, *tc->size, tc->param));
+		if (!TST_PASS)
+			goto out;
+
+		TST_EXP_FAIL(init_module(*tc->buf, *tc->size, tc->param), tc->exp_errno);
+		tst_module_unload(MODULE_NAME);
+	} else {
+		TST_EXP_FAIL(init_module(*tc->buf, *tc->size, tc->param), tc->exp_errno);
+	}
+
+	if (!TST_PASS && !TST_RET)
+		tst_module_unload(MODULE_NAME);
+
+out:
+	if (tc->cap)
+		tst_cap_action(&cap_req);
+}
+
+static void cleanup(void)
+{
+	munmap(buf, size);
+}
+
+static struct tst_test test = {
+	.test = run,
+	.tcnt = ARRAY_SIZE(tcases),
+	.setup = setup,
+	.cleanup = cleanup,
+	.needs_root = 1,
+};
-- 
2.25.0.rc1.19.g042ed3e048af


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [LTP] [PATCH V2 3/3] syscalls: finit_module: Add tests
  2020-12-17  7:27 [LTP] [PATCH V2 1/3] tst_module: Add separate declarations of helpers for new tests framework Viresh Kumar
  2020-12-17  7:27 ` [LTP] [PATCH V2 2/3] syscalls: init_module: Add tests Viresh Kumar
@ 2020-12-17  7:27 ` Viresh Kumar
  2020-12-17 10:09   ` Cyril Hrubis
                     ` (2 more replies)
  2020-12-17 10:01 ` [LTP] [PATCH V2 1/3] tst_module: Add separate declarations of helpers for new tests framework Cyril Hrubis
  2 siblings, 3 replies; 11+ messages in thread
From: Viresh Kumar @ 2020-12-17  7:27 UTC (permalink / raw)
  To: ltp

This patch adds success and failure tests for finit_module() syscall.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
V2:
- Remove unwanted header
- Use TST_EXP_*() macros
- Rename module.

 include/lapi/init_module.h                    | 16 ++++
 runtest/syscalls                              |  3 +
 .../kernel/syscalls/finit_module/.gitignore   |  3 +
 .../kernel/syscalls/finit_module/Makefile     | 21 +++++
 .../syscalls/finit_module/finit_module.c      | 37 ++++++++
 .../syscalls/finit_module/finit_module01.c    | 49 +++++++++++
 .../syscalls/finit_module/finit_module02.c    | 84 +++++++++++++++++++
 7 files changed, 213 insertions(+)
 create mode 100644 testcases/kernel/syscalls/finit_module/.gitignore
 create mode 100644 testcases/kernel/syscalls/finit_module/Makefile
 create mode 100644 testcases/kernel/syscalls/finit_module/finit_module.c
 create mode 100644 testcases/kernel/syscalls/finit_module/finit_module01.c
 create mode 100644 testcases/kernel/syscalls/finit_module/finit_module02.c

diff --git a/include/lapi/init_module.h b/include/lapi/init_module.h
index 65ff70356c60..9e79e11b8557 100644
--- a/include/lapi/init_module.h
+++ b/include/lapi/init_module.h
@@ -16,4 +16,20 @@ static inline int init_module(void *module_image, unsigned long len,
 {
 	return tst_syscall(__NR_init_module, module_image, len, param_values);
 }
+
+static inline int finit_module(int fd, const char *param_values, int flags)
+{
+	return tst_syscall(__NR_finit_module, fd, param_values, flags);
+}
+
+void finit_module_supported_by_kernel(void)
+{
+       if ((tst_kvercmp(3, 8, 0)) < 0) {
+               /* Check if the syscall is backported on an older kernel */
+               TEST(syscall(__NR_finit_module, 0, "", 0));
+               if (TST_RET == -1 && TST_ERR == ENOSYS)
+                       tst_brk(TCONF, "Test not supported on kernel version < v3.8");
+       }
+}
+
 #endif /* INIT_MODULE_H__ */
diff --git a/runtest/syscalls b/runtest/syscalls
index 28174dddd716..961545e73834 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -327,6 +327,9 @@ fgetxattr01 fgetxattr01
 fgetxattr02 fgetxattr02
 fgetxattr03 fgetxattr03
 
+finit_module01 finit_module01
+finit_module02 finit_module02
+
 flistxattr01 flistxattr01
 flistxattr02 flistxattr02
 flistxattr03 flistxattr03
diff --git a/testcases/kernel/syscalls/finit_module/.gitignore b/testcases/kernel/syscalls/finit_module/.gitignore
new file mode 100644
index 000000000000..5fcafdb3736d
--- /dev/null
+++ b/testcases/kernel/syscalls/finit_module/.gitignore
@@ -0,0 +1,3 @@
+/finit_module01
+/finit_module02
+/*.ko
diff --git a/testcases/kernel/syscalls/finit_module/Makefile b/testcases/kernel/syscalls/finit_module/Makefile
new file mode 100644
index 000000000000..a529695d23cc
--- /dev/null
+++ b/testcases/kernel/syscalls/finit_module/Makefile
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+ifneq ($(KERNELRELEASE),)
+
+obj-m := finit_module.o
+
+else
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+REQ_VERSION_MAJOR	:= 3
+REQ_VERSION_PATCH	:= 8
+
+MAKE_TARGETS		:= finit_module01 finit_module02 finit_module.ko
+
+include $(top_srcdir)/include/mk/module.mk
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
+
+endif
diff --git a/testcases/kernel/syscalls/finit_module/finit_module.c b/testcases/kernel/syscalls/finit_module/finit_module.c
new file mode 100644
index 000000000000..78d03b899a7e
--- /dev/null
+++ b/testcases/kernel/syscalls/finit_module/finit_module.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org>
+ *
+ * Dummy test module.
+ *
+ * The module accepts a single argument named "status" and it fails
+ * initialization if the status is set to "invalid".
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/kernel.h>
+
+static char status[20];
+module_param_string(status, status, 20, 0444);
+
+static int dummy_init(void)
+{
+	struct proc_dir_entry *proc_dummy;
+
+	if (!strcmp(status, "invalid"))
+		return -EINVAL;
+
+	proc_dummy = proc_mkdir("dummy", 0);
+	return 0;
+}
+module_init(dummy_init);
+
+static void dummy_exit(void)
+{
+	remove_proc_entry("dummy", 0);
+}
+module_exit(dummy_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/testcases/kernel/syscalls/finit_module/finit_module01.c b/testcases/kernel/syscalls/finit_module/finit_module01.c
new file mode 100644
index 000000000000..c31c0c2dce4c
--- /dev/null
+++ b/testcases/kernel/syscalls/finit_module/finit_module01.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org>
+ */
+
+/*\
+ * [DESCRIPTION]
+ *
+ * Basic finit_module() tests.
+ *
+ * [ALGORITHM]
+ *
+ * Inserts a simple module after opening and mmaping the module file.
+\*/
+
+#include <errno.h>
+#include "lapi/init_module.h"
+#include "tst_module.h"
+
+#define MODULE_NAME	"finit_module.ko"
+
+int fd;
+
+static void setup(void)
+{
+	finit_module_supported_by_kernel();
+	fd = SAFE_OPEN(MODULE_NAME, O_RDONLY|O_CLOEXEC);
+}
+
+static void run(void)
+{
+	TST_EXP_PASS(finit_module(fd, "status=valid", 0));
+	if (!TST_PASS)
+		return;
+
+	tst_module_unload(MODULE_NAME);
+}
+
+static void cleanup(void)
+{
+	SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.cleanup = cleanup,
+	.needs_root = 1,
+};
diff --git a/testcases/kernel/syscalls/finit_module/finit_module02.c b/testcases/kernel/syscalls/finit_module/finit_module02.c
new file mode 100644
index 000000000000..220c83fd4d1c
--- /dev/null
+++ b/testcases/kernel/syscalls/finit_module/finit_module02.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org>
+ */
+
+/*\
+ * [DESCRIPTION]
+ *
+ * Basic finit_module() failure tests.
+ *
+ * [ALGORITHM]
+ *
+ * Tests various failure scenarios for finit_module().
+\*/
+
+#include <linux/capability.h>
+#include <errno.h>
+#include "lapi/init_module.h"
+#include "tst_module.h"
+#include "tst_capability.h"
+
+#define MODULE_NAME	"finit_module.ko"
+
+static int fd, fd_zero, fd_invalid = -1;
+
+static struct tst_cap cap_req = TST_CAP(TST_CAP_REQ, CAP_SYS_MODULE);
+static struct tst_cap cap_drop = TST_CAP(TST_CAP_DROP, CAP_SYS_MODULE);
+
+static struct tcase {
+	const char *name;
+	int *fd;
+	const char *param;
+	int open_flags;
+	int flags;
+	int cap;
+	int exp_errno;
+} tcases[] = {
+	{"zero-fd", &fd_zero, "", O_RDONLY | O_CLOEXEC, 0, 0, EINVAL},
+	{"invalid-fd", &fd_invalid, "", O_RDONLY | O_CLOEXEC, 0, 0, ENOEXEC},
+	{"null-param", &fd, NULL, O_RDONLY | O_CLOEXEC, 0, 0, EFAULT},
+	{"invalid-param", &fd, "status=invalid", O_RDONLY | O_CLOEXEC, 0, 0, EINVAL},
+	{"invalid-flags", &fd, "", O_RDONLY | O_CLOEXEC, -1, 0, EINVAL},
+	{"no-perm", &fd, "", O_RDONLY | O_CLOEXEC, 0, 1, EPERM},
+	{"module-exists", &fd, "", O_RDONLY | O_CLOEXEC, 0, 0, EEXIST},
+	{"file-not-readable", &fd, "", O_WRONLY | O_CLOEXEC, 0, 0, EBADF},
+};
+
+static void run(unsigned int n)
+{
+	struct tcase *tc = &tcases[n];
+
+	fd = SAFE_OPEN(MODULE_NAME, tc->open_flags);
+
+	if (tc->cap)
+		tst_cap_action(&cap_drop);
+
+	/* Insert module twice */
+	if (tc->exp_errno == EEXIST) {
+		TST_EXP_PASS(finit_module(*tc->fd, tc->param, tc->flags));
+		if (!TST_PASS)
+			goto out;
+
+		TST_EXP_FAIL(finit_module(*tc->fd, tc->param, tc->flags), tc->exp_errno);
+		tst_module_unload(MODULE_NAME);
+	} else {
+		TST_EXP_FAIL(finit_module(*tc->fd, tc->param, tc->flags), tc->exp_errno);
+	}
+
+	if (!TST_PASS && !TST_RET)
+		tst_module_unload(MODULE_NAME);
+
+out:
+	if (tc->cap)
+		tst_cap_action(&cap_req);
+
+	SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+	.test = run,
+	.tcnt = ARRAY_SIZE(tcases),
+	.setup = finit_module_supported_by_kernel,
+	.needs_root = 1,
+};
-- 
2.25.0.rc1.19.g042ed3e048af


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [LTP] [PATCH V2 1/3] tst_module: Add separate declarations of helpers for new tests framework
  2020-12-17  7:27 [LTP] [PATCH V2 1/3] tst_module: Add separate declarations of helpers for new tests framework Viresh Kumar
  2020-12-17  7:27 ` [LTP] [PATCH V2 2/3] syscalls: init_module: Add tests Viresh Kumar
  2020-12-17  7:27 ` [LTP] [PATCH V2 3/3] syscalls: finit_module: " Viresh Kumar
@ 2020-12-17 10:01 ` Cyril Hrubis
  2 siblings, 0 replies; 11+ messages in thread
From: Cyril Hrubis @ 2020-12-17 10:01 UTC (permalink / raw)
  To: ltp

Hi!
Pushed with a small fix, thanks.

It turned out that there was a typo in the old_module.h header, the
function tst_module_exist() never existed and it's supposed to be
tst_module_exists(). So I've renamed all instances accordingly.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [LTP] [PATCH V2 2/3] syscalls: init_module: Add tests
  2020-12-17  7:27 ` [LTP] [PATCH V2 2/3] syscalls: init_module: Add tests Viresh Kumar
@ 2020-12-17 10:03   ` Cyril Hrubis
  0 siblings, 0 replies; 11+ messages in thread
From: Cyril Hrubis @ 2020-12-17 10:03 UTC (permalink / raw)
  To: ltp

Hi!
Pushed with two small fixes, thanks.

* Added dummy call to tst_module_exists() to the setup()s
  which causes the test to exit with TCONF if the module wasn't build
  for example when kernel devel package wasn't installed

* Cleaned up a bit the init_module02.c run() function

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [LTP] [PATCH V2 3/3] syscalls: finit_module: Add tests
  2020-12-17  7:27 ` [LTP] [PATCH V2 3/3] syscalls: finit_module: " Viresh Kumar
@ 2020-12-17 10:09   ` Cyril Hrubis
  2020-12-17 10:24     ` Viresh Kumar
  2020-12-17 10:29   ` [LTP] [PATCH V3 " Viresh Kumar
  2020-12-18  6:55   ` [LTP] [PATCH V4 " Viresh Kumar
  2 siblings, 1 reply; 11+ messages in thread
From: Cyril Hrubis @ 2020-12-17 10:09 UTC (permalink / raw)
  To: ltp

Hi!
This finit_module02 fails for me:

tst_test.c:1261: TINFO: Timeout per run is 0h 05m 00s
finit_module02.c:66: TPASS: finit_module(*tc->fd, tc->param, tc->flags): EINVAL (22)
finit_module02.c:66: TFAIL: finit_module(*tc->fd, tc->param, tc->flags) expected ENOEXEC: EBADF (9)
finit_module02.c:66: TPASS: finit_module(*tc->fd, tc->param, tc->flags): EFAULT (14)
finit_module02.c:66: TPASS: finit_module(*tc->fd, tc->param, tc->flags): EINVAL (22)
finit_module02.c:66: TPASS: finit_module(*tc->fd, tc->param, tc->flags): EINVAL (22)
tst_capability.c:29: TINFO: Dropping CAP_SYS_MODULE(16)
finit_module02.c:66: TPASS: finit_module(*tc->fd, tc->param, tc->flags): EPERM (1)
tst_capability.c:41: TINFO: Permitting CAP_SYS_MODULE(16)
finit_module02.c:59: TPASS: finit_module(*tc->fd, tc->param, tc->flags) passed
finit_module02.c:63: TPASS: finit_module(*tc->fd, tc->param, tc->flags): EEXIST (17)
finit_module02.c:66: TFAIL: finit_module(*tc->fd, tc->param, tc->flags) expected EBADF: ETXTBSY (26)

Linux 5.9.12

Also it looks to me like EBADF is more reasonable error for fd set to -1
also ETXTBSY sounds more reasonable for a file opened for writing.

I guess that someone cleaned up the kernel implementation but forget to
update the manual pages?

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [LTP] [PATCH V2 3/3] syscalls: finit_module: Add tests
  2020-12-17 10:09   ` Cyril Hrubis
@ 2020-12-17 10:24     ` Viresh Kumar
  0 siblings, 0 replies; 11+ messages in thread
From: Viresh Kumar @ 2020-12-17 10:24 UTC (permalink / raw)
  To: ltp

On 17-12-20, 11:09, Cyril Hrubis wrote:
> Hi!
> This finit_module02 fails for me:
> 
> tst_test.c:1261: TINFO: Timeout per run is 0h 05m 00s
> finit_module02.c:66: TPASS: finit_module(*tc->fd, tc->param, tc->flags): EINVAL (22)
> finit_module02.c:66: TFAIL: finit_module(*tc->fd, tc->param, tc->flags) expected ENOEXEC: EBADF (9)
> finit_module02.c:66: TPASS: finit_module(*tc->fd, tc->param, tc->flags): EFAULT (14)
> finit_module02.c:66: TPASS: finit_module(*tc->fd, tc->param, tc->flags): EINVAL (22)
> finit_module02.c:66: TPASS: finit_module(*tc->fd, tc->param, tc->flags): EINVAL (22)
> tst_capability.c:29: TINFO: Dropping CAP_SYS_MODULE(16)
> finit_module02.c:66: TPASS: finit_module(*tc->fd, tc->param, tc->flags): EPERM (1)
> tst_capability.c:41: TINFO: Permitting CAP_SYS_MODULE(16)
> finit_module02.c:59: TPASS: finit_module(*tc->fd, tc->param, tc->flags) passed
> finit_module02.c:63: TPASS: finit_module(*tc->fd, tc->param, tc->flags): EEXIST (17)
> finit_module02.c:66: TFAIL: finit_module(*tc->fd, tc->param, tc->flags) expected EBADF: ETXTBSY (26)
> 
> Linux 5.9.12
> 
> Also it looks to me like EBADF is more reasonable error for fd set to -1
> also ETXTBSY sounds more reasonable for a file opened for writing.
> 
> I guess that someone cleaned up the kernel implementation but forget to
> update the manual pages?

Merged in v4.6 and I am on 4.4 :(

commit a1db74209483a24c861c848b4bb79a4d945ef6fa
Author: Mimi Zohar <zohar@linux.vnet.ibm.com>
Date:   Wed Dec 30 07:35:30 2015 -0500

    module: replace copy_module_from_fd with kernel version
    
    Replace copy_module_from_fd() with kernel_read_file_from_fd().
    
    Although none of the upstreamed LSMs define a kernel_module_from_file
    hook, IMA is called, based on policy, to prevent unsigned kernel modules
    from being loaded by the original kernel module syscall and to
    measure/appraise signed kernel modules.
    
    The security function security_kernel_module_from_file() was called prior
    to reading a kernel module.  Preventing unsigned kernel modules from being
    loaded by the original kernel module syscall remains on the pre-read
    kernel_read_file() security hook.  Instead of reading the kernel module
    twice, once for measuring/appraising and again for loading the kernel
    module, the signature validation is moved to the kernel_post_read_file()
    security hook.
    
    This patch removes the security_kernel_module_from_file() hook and security
    call.
    
    Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
    Acked-by: Kees Cook <keescook@chromium.org>
    Acked-by: Luis R. Rodriguez <mcgrof@kernel.org>
    Cc: Rusty Russell <rusty@rustcorp.com.au>

-- 
viresh

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [LTP] [PATCH V3 3/3] syscalls: finit_module: Add tests
  2020-12-17  7:27 ` [LTP] [PATCH V2 3/3] syscalls: finit_module: " Viresh Kumar
  2020-12-17 10:09   ` Cyril Hrubis
@ 2020-12-17 10:29   ` Viresh Kumar
  2020-12-17 12:02     ` Cyril Hrubis
  2020-12-18  6:55   ` [LTP] [PATCH V4 " Viresh Kumar
  2 siblings, 1 reply; 11+ messages in thread
From: Viresh Kumar @ 2020-12-17 10:29 UTC (permalink / raw)
  To: ltp

This patch adds success and failure tests for finit_module() syscall.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 include/lapi/init_module.h                    | 16 ++++
 runtest/syscalls                              |  3 +
 .../kernel/syscalls/finit_module/.gitignore   |  3 +
 .../kernel/syscalls/finit_module/Makefile     | 21 +++++
 .../syscalls/finit_module/finit_module.c      | 37 ++++++++
 .../syscalls/finit_module/finit_module01.c    | 49 ++++++++++
 .../syscalls/finit_module/finit_module02.c    | 89 +++++++++++++++++++
 7 files changed, 218 insertions(+)
 create mode 100644 testcases/kernel/syscalls/finit_module/.gitignore
 create mode 100644 testcases/kernel/syscalls/finit_module/Makefile
 create mode 100644 testcases/kernel/syscalls/finit_module/finit_module.c
 create mode 100644 testcases/kernel/syscalls/finit_module/finit_module01.c
 create mode 100644 testcases/kernel/syscalls/finit_module/finit_module02.c

diff --git a/include/lapi/init_module.h b/include/lapi/init_module.h
index 65ff70356c60..9e79e11b8557 100644
--- a/include/lapi/init_module.h
+++ b/include/lapi/init_module.h
@@ -16,4 +16,20 @@ static inline int init_module(void *module_image, unsigned long len,
 {
 	return tst_syscall(__NR_init_module, module_image, len, param_values);
 }
+
+static inline int finit_module(int fd, const char *param_values, int flags)
+{
+	return tst_syscall(__NR_finit_module, fd, param_values, flags);
+}
+
+void finit_module_supported_by_kernel(void)
+{
+       if ((tst_kvercmp(3, 8, 0)) < 0) {
+               /* Check if the syscall is backported on an older kernel */
+               TEST(syscall(__NR_finit_module, 0, "", 0));
+               if (TST_RET == -1 && TST_ERR == ENOSYS)
+                       tst_brk(TCONF, "Test not supported on kernel version < v3.8");
+       }
+}
+
 #endif /* INIT_MODULE_H__ */
diff --git a/runtest/syscalls b/runtest/syscalls
index 28174dddd716..961545e73834 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -327,6 +327,9 @@ fgetxattr01 fgetxattr01
 fgetxattr02 fgetxattr02
 fgetxattr03 fgetxattr03
 
+finit_module01 finit_module01
+finit_module02 finit_module02
+
 flistxattr01 flistxattr01
 flistxattr02 flistxattr02
 flistxattr03 flistxattr03
diff --git a/testcases/kernel/syscalls/finit_module/.gitignore b/testcases/kernel/syscalls/finit_module/.gitignore
new file mode 100644
index 000000000000..5fcafdb3736d
--- /dev/null
+++ b/testcases/kernel/syscalls/finit_module/.gitignore
@@ -0,0 +1,3 @@
+/finit_module01
+/finit_module02
+/*.ko
diff --git a/testcases/kernel/syscalls/finit_module/Makefile b/testcases/kernel/syscalls/finit_module/Makefile
new file mode 100644
index 000000000000..a529695d23cc
--- /dev/null
+++ b/testcases/kernel/syscalls/finit_module/Makefile
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+ifneq ($(KERNELRELEASE),)
+
+obj-m := finit_module.o
+
+else
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+REQ_VERSION_MAJOR	:= 3
+REQ_VERSION_PATCH	:= 8
+
+MAKE_TARGETS		:= finit_module01 finit_module02 finit_module.ko
+
+include $(top_srcdir)/include/mk/module.mk
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
+
+endif
diff --git a/testcases/kernel/syscalls/finit_module/finit_module.c b/testcases/kernel/syscalls/finit_module/finit_module.c
new file mode 100644
index 000000000000..78d03b899a7e
--- /dev/null
+++ b/testcases/kernel/syscalls/finit_module/finit_module.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org>
+ *
+ * Dummy test module.
+ *
+ * The module accepts a single argument named "status" and it fails
+ * initialization if the status is set to "invalid".
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/kernel.h>
+
+static char status[20];
+module_param_string(status, status, 20, 0444);
+
+static int dummy_init(void)
+{
+	struct proc_dir_entry *proc_dummy;
+
+	if (!strcmp(status, "invalid"))
+		return -EINVAL;
+
+	proc_dummy = proc_mkdir("dummy", 0);
+	return 0;
+}
+module_init(dummy_init);
+
+static void dummy_exit(void)
+{
+	remove_proc_entry("dummy", 0);
+}
+module_exit(dummy_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/testcases/kernel/syscalls/finit_module/finit_module01.c b/testcases/kernel/syscalls/finit_module/finit_module01.c
new file mode 100644
index 000000000000..c31c0c2dce4c
--- /dev/null
+++ b/testcases/kernel/syscalls/finit_module/finit_module01.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org>
+ */
+
+/*\
+ * [DESCRIPTION]
+ *
+ * Basic finit_module() tests.
+ *
+ * [ALGORITHM]
+ *
+ * Inserts a simple module after opening and mmaping the module file.
+\*/
+
+#include <errno.h>
+#include "lapi/init_module.h"
+#include "tst_module.h"
+
+#define MODULE_NAME	"finit_module.ko"
+
+int fd;
+
+static void setup(void)
+{
+	finit_module_supported_by_kernel();
+	fd = SAFE_OPEN(MODULE_NAME, O_RDONLY|O_CLOEXEC);
+}
+
+static void run(void)
+{
+	TST_EXP_PASS(finit_module(fd, "status=valid", 0));
+	if (!TST_PASS)
+		return;
+
+	tst_module_unload(MODULE_NAME);
+}
+
+static void cleanup(void)
+{
+	SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.cleanup = cleanup,
+	.needs_root = 1,
+};
diff --git a/testcases/kernel/syscalls/finit_module/finit_module02.c b/testcases/kernel/syscalls/finit_module/finit_module02.c
new file mode 100644
index 000000000000..088b15055221
--- /dev/null
+++ b/testcases/kernel/syscalls/finit_module/finit_module02.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org>
+ */
+
+/*\
+ * [DESCRIPTION]
+ *
+ * Basic finit_module() failure tests.
+ *
+ * [ALGORITHM]
+ *
+ * Tests various failure scenarios for finit_module().
+\*/
+
+#include <linux/capability.h>
+#include <errno.h>
+#include "lapi/init_module.h"
+#include "tst_module.h"
+#include "tst_capability.h"
+
+#define MODULE_NAME	"finit_module.ko"
+
+static int fd, fd_zero, fd_invalid = -1;
+
+static struct tst_cap cap_req = TST_CAP(TST_CAP_REQ, CAP_SYS_MODULE);
+static struct tst_cap cap_drop = TST_CAP(TST_CAP_DROP, CAP_SYS_MODULE);
+
+static struct tcase {
+	const char *name;
+	int *fd;
+	const char *param;
+	int open_flags;
+	int flags;
+	int cap;
+	int exp_errno;
+} tcases[] = {
+	{"invalid-fd", &fd_invalid, "", O_RDONLY | O_CLOEXEC, 0, 0, EBADF}, /* Keep this at index 0 */
+	{"zero-fd", &fd_zero, "", O_RDONLY | O_CLOEXEC, 0, 0, EINVAL},
+	{"null-param", &fd, NULL, O_RDONLY | O_CLOEXEC, 0, 0, EFAULT},
+	{"invalid-param", &fd, "status=invalid", O_RDONLY | O_CLOEXEC, 0, 0, EINVAL},
+	{"invalid-flags", &fd, "", O_RDONLY | O_CLOEXEC, -1, 0, EINVAL},
+	{"no-perm", &fd, "", O_RDONLY | O_CLOEXEC, 0, 1, EPERM},
+	{"module-exists", &fd, "", O_RDONLY | O_CLOEXEC, 0, 0, EEXIST},
+	{"file-not-readable", &fd, "", O_WRONLY | O_CLOEXEC, 0, 0, EBADF},
+};
+
+static void setup(void)
+{
+	finit_module_supported_by_kernel();
+
+	/* Kernel returned ENOEXEC for fd = -1 earlier */
+	if ((tst_kvercmp(4, 6, 0)) < 0)
+		tcases[0].exp_errno = ENOEXEC;
+}
+
+static void run(unsigned int n)
+{
+	struct tcase *tc = &tcases[n];
+
+	fd = SAFE_OPEN(MODULE_NAME, tc->open_flags);
+
+	if (tc->cap)
+		tst_cap_action(&cap_drop);
+
+	/* Insert module twice */
+	if (tc->exp_errno == EEXIST)
+		tst_module_load(MODULE_NAME, NULL);
+
+	TST_EXP_FAIL(finit_module(*tc->fd, tc->param, tc->flags), tc->exp_errno);
+
+	if (tc->exp_errno == EEXIST)
+		tst_module_unload(MODULE_NAME);
+
+	if (!TST_PASS && !TST_RET)
+		tst_module_unload(MODULE_NAME);
+
+	if (tc->cap)
+		tst_cap_action(&cap_req);
+
+	SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+	.test = run,
+	.tcnt = ARRAY_SIZE(tcases),
+	.setup = setup,
+	.needs_root = 1,
+};
-- 
2.25.0.rc1.19.g042ed3e048af


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [LTP] [PATCH V3 3/3] syscalls: finit_module: Add tests
  2020-12-17 10:29   ` [LTP] [PATCH V3 " Viresh Kumar
@ 2020-12-17 12:02     ` Cyril Hrubis
  0 siblings, 0 replies; 11+ messages in thread
From: Cyril Hrubis @ 2020-12-17 12:02 UTC (permalink / raw)
  To: ltp

Hi!
> +static void setup(void)
> +{
> +	finit_module_supported_by_kernel();
> +
> +	/* Kernel returned ENOEXEC for fd = -1 earlier */
> +	if ((tst_kvercmp(4, 6, 0)) < 0)
> +		tcases[0].exp_errno = ENOEXEC;

There are plenty of ways how to avoid hackery like that.

What about we defined a setup function in the test structure and then
loop over the testcases in the test setup() and execute all per-test
setup functions we have.

The we can keep the errno set to zero in the static structure and
initialize it in the per-testcase setup as:

static void bad_fd_setup(struct tcase *tc)
{
	if (tst_kvercmp(4, 6, 0)) < 0)
		tc->errno = ENOEXEC;
	else
		tc->errno = EBADFD;
}


Also I think that the last test needs to handle ETXTBSY in the same way
and we may possibly add more tests since I guess that most of the errors
that apply to execve() would apply here as well. What happpens for
example if we pass a fd that points to a directory?

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [LTP] [PATCH V4 3/3] syscalls: finit_module: Add tests
  2020-12-17  7:27 ` [LTP] [PATCH V2 3/3] syscalls: finit_module: " Viresh Kumar
  2020-12-17 10:09   ` Cyril Hrubis
  2020-12-17 10:29   ` [LTP] [PATCH V3 " Viresh Kumar
@ 2020-12-18  6:55   ` Viresh Kumar
  2021-01-06 10:00     ` Cyril Hrubis
  2 siblings, 1 reply; 11+ messages in thread
From: Viresh Kumar @ 2020-12-18  6:55 UTC (permalink / raw)
  To: ltp

This patch adds success and failure tests for finit_module() syscall.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
V4:
- Add fix_errno() callback in tcase in finit_module02.c and use it for 3
  of the tests.
- Add test where fd is a directory.

 include/lapi/init_module.h                    |  16 +++
 runtest/syscalls                              |   3 +
 .../kernel/syscalls/finit_module/.gitignore   |   3 +
 .../kernel/syscalls/finit_module/Makefile     |  21 +++
 .../syscalls/finit_module/finit_module.c      |  37 +++++
 .../syscalls/finit_module/finit_module01.c    |  49 +++++++
 .../syscalls/finit_module/finit_module02.c    | 131 ++++++++++++++++++
 7 files changed, 260 insertions(+)
 create mode 100644 testcases/kernel/syscalls/finit_module/.gitignore
 create mode 100644 testcases/kernel/syscalls/finit_module/Makefile
 create mode 100644 testcases/kernel/syscalls/finit_module/finit_module.c
 create mode 100644 testcases/kernel/syscalls/finit_module/finit_module01.c
 create mode 100644 testcases/kernel/syscalls/finit_module/finit_module02.c

diff --git a/include/lapi/init_module.h b/include/lapi/init_module.h
index 65ff70356c60..9e79e11b8557 100644
--- a/include/lapi/init_module.h
+++ b/include/lapi/init_module.h
@@ -16,4 +16,20 @@ static inline int init_module(void *module_image, unsigned long len,
 {
 	return tst_syscall(__NR_init_module, module_image, len, param_values);
 }
+
+static inline int finit_module(int fd, const char *param_values, int flags)
+{
+	return tst_syscall(__NR_finit_module, fd, param_values, flags);
+}
+
+void finit_module_supported_by_kernel(void)
+{
+       if ((tst_kvercmp(3, 8, 0)) < 0) {
+               /* Check if the syscall is backported on an older kernel */
+               TEST(syscall(__NR_finit_module, 0, "", 0));
+               if (TST_RET == -1 && TST_ERR == ENOSYS)
+                       tst_brk(TCONF, "Test not supported on kernel version < v3.8");
+       }
+}
+
 #endif /* INIT_MODULE_H__ */
diff --git a/runtest/syscalls b/runtest/syscalls
index 28174dddd716..961545e73834 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -327,6 +327,9 @@ fgetxattr01 fgetxattr01
 fgetxattr02 fgetxattr02
 fgetxattr03 fgetxattr03
 
+finit_module01 finit_module01
+finit_module02 finit_module02
+
 flistxattr01 flistxattr01
 flistxattr02 flistxattr02
 flistxattr03 flistxattr03
diff --git a/testcases/kernel/syscalls/finit_module/.gitignore b/testcases/kernel/syscalls/finit_module/.gitignore
new file mode 100644
index 000000000000..5fcafdb3736d
--- /dev/null
+++ b/testcases/kernel/syscalls/finit_module/.gitignore
@@ -0,0 +1,3 @@
+/finit_module01
+/finit_module02
+/*.ko
diff --git a/testcases/kernel/syscalls/finit_module/Makefile b/testcases/kernel/syscalls/finit_module/Makefile
new file mode 100644
index 000000000000..a529695d23cc
--- /dev/null
+++ b/testcases/kernel/syscalls/finit_module/Makefile
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+ifneq ($(KERNELRELEASE),)
+
+obj-m := finit_module.o
+
+else
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+REQ_VERSION_MAJOR	:= 3
+REQ_VERSION_PATCH	:= 8
+
+MAKE_TARGETS		:= finit_module01 finit_module02 finit_module.ko
+
+include $(top_srcdir)/include/mk/module.mk
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
+
+endif
diff --git a/testcases/kernel/syscalls/finit_module/finit_module.c b/testcases/kernel/syscalls/finit_module/finit_module.c
new file mode 100644
index 000000000000..78d03b899a7e
--- /dev/null
+++ b/testcases/kernel/syscalls/finit_module/finit_module.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org>
+ *
+ * Dummy test module.
+ *
+ * The module accepts a single argument named "status" and it fails
+ * initialization if the status is set to "invalid".
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/kernel.h>
+
+static char status[20];
+module_param_string(status, status, 20, 0444);
+
+static int dummy_init(void)
+{
+	struct proc_dir_entry *proc_dummy;
+
+	if (!strcmp(status, "invalid"))
+		return -EINVAL;
+
+	proc_dummy = proc_mkdir("dummy", 0);
+	return 0;
+}
+module_init(dummy_init);
+
+static void dummy_exit(void)
+{
+	remove_proc_entry("dummy", 0);
+}
+module_exit(dummy_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/testcases/kernel/syscalls/finit_module/finit_module01.c b/testcases/kernel/syscalls/finit_module/finit_module01.c
new file mode 100644
index 000000000000..c31c0c2dce4c
--- /dev/null
+++ b/testcases/kernel/syscalls/finit_module/finit_module01.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org>
+ */
+
+/*\
+ * [DESCRIPTION]
+ *
+ * Basic finit_module() tests.
+ *
+ * [ALGORITHM]
+ *
+ * Inserts a simple module after opening and mmaping the module file.
+\*/
+
+#include <errno.h>
+#include "lapi/init_module.h"
+#include "tst_module.h"
+
+#define MODULE_NAME	"finit_module.ko"
+
+int fd;
+
+static void setup(void)
+{
+	finit_module_supported_by_kernel();
+	fd = SAFE_OPEN(MODULE_NAME, O_RDONLY|O_CLOEXEC);
+}
+
+static void run(void)
+{
+	TST_EXP_PASS(finit_module(fd, "status=valid", 0));
+	if (!TST_PASS)
+		return;
+
+	tst_module_unload(MODULE_NAME);
+}
+
+static void cleanup(void)
+{
+	SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.cleanup = cleanup,
+	.needs_root = 1,
+};
diff --git a/testcases/kernel/syscalls/finit_module/finit_module02.c b/testcases/kernel/syscalls/finit_module/finit_module02.c
new file mode 100644
index 000000000000..109de94821da
--- /dev/null
+++ b/testcases/kernel/syscalls/finit_module/finit_module02.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org>
+ */
+
+/*\
+ * [DESCRIPTION]
+ *
+ * Basic finit_module() failure tests.
+ *
+ * [ALGORITHM]
+ *
+ * Tests various failure scenarios for finit_module().
+\*/
+
+#include <linux/capability.h>
+#include <errno.h>
+#include "lapi/init_module.h"
+#include "tst_module.h"
+#include "tst_capability.h"
+
+#define MODULE_NAME	"finit_module.ko"
+#define TEST_DIR	"test_dir"
+
+static int fd, fd_zero, fd_invalid = -1, fd_dir;
+
+static struct tst_cap cap_req = TST_CAP(TST_CAP_REQ, CAP_SYS_MODULE);
+static struct tst_cap cap_drop = TST_CAP(TST_CAP_DROP, CAP_SYS_MODULE);
+
+struct tcase {
+	const char *name;
+	int *fd;
+	const char *param;
+	int open_flags;
+	int flags;
+	int cap;
+	int exp_errno;
+	void (*fix_errno)(struct tcase *tc);
+};
+
+static void bad_fd_setup(struct tcase *tc)
+{
+	if (tst_kvercmp(4, 6, 0) < 0)
+		tc->exp_errno = ENOEXEC;
+	else
+		tc->exp_errno = EBADF;
+}
+
+static void wo_file_setup(struct tcase *tc)
+{
+	if (tst_kvercmp(4, 6, 0) < 0)
+		tc->exp_errno = EBADF;
+	else
+		tc->exp_errno = ETXTBSY;
+}
+
+static void dir_setup(struct tcase *tc)
+{
+	if (tst_kvercmp(4, 6, 0) < 0)
+		tc->exp_errno = EISDIR;
+	else
+		tc->exp_errno = EINVAL;
+}
+
+static struct tcase tcases[] = {
+	{"invalid-fd", &fd_invalid, "", O_RDONLY | O_CLOEXEC, 0, 0, 0, bad_fd_setup},
+	{"zero-fd", &fd_zero, "", O_RDONLY | O_CLOEXEC, 0, 0, EINVAL, NULL},
+	{"null-param", &fd, NULL, O_RDONLY | O_CLOEXEC, 0, 0, EFAULT, NULL},
+	{"invalid-param", &fd, "status=invalid", O_RDONLY | O_CLOEXEC, 0, 0, EINVAL, NULL},
+	{"invalid-flags", &fd, "", O_RDONLY | O_CLOEXEC, -1, 0, EINVAL, NULL},
+	{"no-perm", &fd, "", O_RDONLY | O_CLOEXEC, 0, 1, EPERM, NULL},
+	{"module-exists", &fd, "", O_RDONLY | O_CLOEXEC, 0, 0, EEXIST, NULL},
+	{"file-not-readable", &fd, "", O_WRONLY | O_CLOEXEC, 0, 0, 0, wo_file_setup},
+	{"directory", &fd_dir, "", O_RDONLY | O_CLOEXEC, 0, 0, 0, dir_setup},
+};
+
+static void setup(void)
+{
+	unsigned long int i;
+
+	finit_module_supported_by_kernel();
+	SAFE_MKDIR(TEST_DIR, 0700);
+	fd_dir = SAFE_OPEN(TEST_DIR, O_DIRECTORY);
+
+	for (i = 0; i < ARRAY_SIZE(tcases); i++) {
+		if (tcases[i].fix_errno)
+			tcases[i].fix_errno(&tcases[i]);
+	}
+}
+
+static void cleanup(void)
+{
+	SAFE_CLOSE(fd_dir);
+	SAFE_RMDIR(TEST_DIR);
+}
+
+static void run(unsigned int n)
+{
+	struct tcase *tc = &tcases[n];
+
+	fd = SAFE_OPEN(MODULE_NAME, tc->open_flags);
+
+	if (tc->cap)
+		tst_cap_action(&cap_drop);
+
+	/* Insert module twice */
+	if (tc->exp_errno == EEXIST)
+		tst_module_load(MODULE_NAME, NULL);
+
+	TST_EXP_FAIL(finit_module(*tc->fd, tc->param, tc->flags), tc->exp_errno,
+		     "TestName: %s", tc->name);
+
+	if (tc->exp_errno == EEXIST)
+		tst_module_unload(MODULE_NAME);
+
+	if (!TST_PASS && !TST_RET)
+		tst_module_unload(MODULE_NAME);
+
+	if (tc->cap)
+		tst_cap_action(&cap_req);
+
+	SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+	.test = run,
+	.tcnt = ARRAY_SIZE(tcases),
+	.setup = setup,
+	.cleanup = cleanup,
+	.needs_root = 1,
+};
-- 
2.25.0.rc1.19.g042ed3e048af


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [LTP] [PATCH V4 3/3] syscalls: finit_module: Add tests
  2020-12-18  6:55   ` [LTP] [PATCH V4 " Viresh Kumar
@ 2021-01-06 10:00     ` Cyril Hrubis
  0 siblings, 0 replies; 11+ messages in thread
From: Cyril Hrubis @ 2021-01-06 10:00 UTC (permalink / raw)
  To: ltp

Hi!
Applied, thanks.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2021-01-06 10:00 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-17  7:27 [LTP] [PATCH V2 1/3] tst_module: Add separate declarations of helpers for new tests framework Viresh Kumar
2020-12-17  7:27 ` [LTP] [PATCH V2 2/3] syscalls: init_module: Add tests Viresh Kumar
2020-12-17 10:03   ` Cyril Hrubis
2020-12-17  7:27 ` [LTP] [PATCH V2 3/3] syscalls: finit_module: " Viresh Kumar
2020-12-17 10:09   ` Cyril Hrubis
2020-12-17 10:24     ` Viresh Kumar
2020-12-17 10:29   ` [LTP] [PATCH V3 " Viresh Kumar
2020-12-17 12:02     ` Cyril Hrubis
2020-12-18  6:55   ` [LTP] [PATCH V4 " Viresh Kumar
2021-01-06 10:00     ` Cyril Hrubis
2020-12-17 10:01 ` [LTP] [PATCH V2 1/3] tst_module: Add separate declarations of helpers for new tests framework Cyril Hrubis

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.