public inbox for ltp@lists.linux.it
 help / color / mirror / Atom feed
* [LTP] [PATCH v2 0/3] provide a unified way to parse /proc/cmdline
@ 2024-03-09  9:01 Li Wang
  2024-03-09  9:01 ` [LTP] [PATCH v2 1/3] kconfig: add funtion " Li Wang
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Li Wang @ 2024-03-09  9:01 UTC (permalink / raw)
  To: ltp, chrubis, pvorel

V1 --> V2
	* redefine the struct name to tst_kcmdline_var
	* make use of SAFE_FOPEN/FCLOSE macro (Petr)
	* read the file char char building up the key and value (Cyril)
	* remove redundant varibales from the test (Petr)

Li Wang (3):
  kconfig: add funtion to parse /proc/cmdline
  init_module: To handle kernel module signature enforcement
  stack_clash: make use of tst_kcmdline_parse

 include/tst_kconfig.h                         | 23 ++++++++++
 lib/tst_kconfig.c                             | 45 +++++++++++++++++++
 testcases/cve/stack_clash.c                   | 14 +++---
 .../syscalls/delete_module/delete_module01.c  |  8 ++++
 .../syscalls/delete_module/delete_module03.c  |  8 ++++
 .../syscalls/finit_module/finit_module01.c    | 15 ++++++-
 .../syscalls/finit_module/finit_module02.c    | 37 +++++++++------
 .../syscalls/init_module/init_module01.c      | 13 ++++++
 .../syscalls/init_module/init_module02.c      | 19 +++++++-
 9 files changed, 158 insertions(+), 24 deletions(-)

-- 
2.40.1


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* [LTP] [PATCH v2 1/3] kconfig: add funtion to parse /proc/cmdline
  2024-03-09  9:01 [LTP] [PATCH v2 0/3] provide a unified way to parse /proc/cmdline Li Wang
@ 2024-03-09  9:01 ` Li Wang
  2024-03-11 12:27   ` Petr Vorel
  2024-03-09  9:01 ` [LTP] [PATCH v2 2/3] init_module: To handle kernel module signature enforcement Li Wang
  2024-03-09  9:01 ` [LTP] [PATCH v2 3/3] stack_clash: make use of tst_kcmdline_parse Li Wang
  2 siblings, 1 reply; 5+ messages in thread
From: Li Wang @ 2024-03-09  9:01 UTC (permalink / raw)
  To: ltp, chrubis, pvorel

A new structure tst_kcmdline_var is defined to hold a command-line
argument's key and a fixed-size value. Furthermore, function
tst_kcmdline_parse is added to the corresponding .c file, which
reads from /proc/cmdline, parses the command-line arguments, and
populates the tst_kcmdline_var array with the obtained key-value
pairs, ensuring safe file operations and buffer size checks.

Signed-off-by: Li Wang <liwang@redhat.com>
---
 include/tst_kconfig.h | 23 ++++++++++++++++++++++
 lib/tst_kconfig.c     | 45 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+)

diff --git a/include/tst_kconfig.h b/include/tst_kconfig.h
index 8b24a8380..a8cbfb786 100644
--- a/include/tst_kconfig.h
+++ b/include/tst_kconfig.h
@@ -64,4 +64,27 @@ void tst_kconfig_read(struct tst_kconfig_var vars[], size_t vars_len);
  */
 int tst_kconfig_check(const char *const kconfigs[]);
 
+/**
+ * Macro to initialize a tst_kcmdline_var structure with a specified parameter
+ * name and an empty value. This is useful for setting up an array of parameter
+ * structures before parsing the actual command-line arguments.
+ */
+#define TST_KCMDLINE_INIT(paraname) { \
+	.key = paraname, \
+	.value = "" \
+}
+
+/* Structure for storing command-line parameter key and its corresponding value */
+struct tst_kcmdline_var {
+	const char *key;
+	char value[128];
+};
+
+/**
+ * Parses command-line parameters from /proc/cmdline and stores them in params array
+ * params: The array of tst_kcmdline_var structures to be filled with parsed key-value pairs
+ * params_len: The length of the params array, indicating how many parameters to parse
+ */
+void tst_kcmdline_parse(struct tst_kcmdline_var params[], size_t params_len);
+
 #endif	/* TST_KCONFIG_H__ */
diff --git a/lib/tst_kconfig.c b/lib/tst_kconfig.c
index 595ea4b09..c200dd261 100644
--- a/lib/tst_kconfig.c
+++ b/lib/tst_kconfig.c
@@ -14,6 +14,7 @@
 #include "tst_private.h"
 #include "tst_kconfig.h"
 #include "tst_bool_expr.h"
+#include "tst_safe_stdio.h"
 
 static int kconfig_skip_check(void)
 {
@@ -565,3 +566,47 @@ char tst_kconfig_get(const char *confname)
 
 	return var.choice;
 }
+
+void tst_kcmdline_parse(struct tst_kcmdline_var params[], size_t params_len) {
+	char buf[128];
+	size_t buf_pos = 0, i;
+	int var_id = -1, c;
+
+	FILE *f = SAFE_FOPEN("/proc/cmdline", "r");
+
+	while ((c = fgetc(f)) != EOF) {
+		switch (c) {
+		case '=':
+			buf[buf_pos] = '\0';
+			for (i = 0; i < params_len; i++) {
+				if (strcmp(buf, params[i].key) == 0)
+					var_id = (int)i;
+			}
+
+			buf_pos = 0;
+		break;
+		case ' ':
+		case '\n':
+			buf[buf_pos] = '\0';
+			if (var_id >= 0 && var_id < (int)params_len)
+				strcpy(params[var_id].value, buf);
+
+			var_id = -1;
+			buf_pos = 0;
+		break;
+		default:
+			if (buf_pos + 1  >= sizeof(buf)) {
+				tst_res(TWARN, "Buffer overflowed while parsing /proc/cmdline");
+				while ((c = fgetc(f)) != EOF && c != ' ' && c != '\n');
+
+				var_id = -1;
+				buf_pos = 0;
+			}
+
+			buf[buf_pos++] = (char)c;
+		break;
+		}
+	}
+
+	SAFE_FCLOSE(f);
+}
-- 
2.40.1


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* [LTP] [PATCH v2 2/3] init_module: To handle kernel module signature enforcement
  2024-03-09  9:01 [LTP] [PATCH v2 0/3] provide a unified way to parse /proc/cmdline Li Wang
  2024-03-09  9:01 ` [LTP] [PATCH v2 1/3] kconfig: add funtion " Li Wang
@ 2024-03-09  9:01 ` Li Wang
  2024-03-09  9:01 ` [LTP] [PATCH v2 3/3] stack_clash: make use of tst_kcmdline_parse Li Wang
  2 siblings, 0 replies; 5+ messages in thread
From: Li Wang @ 2024-03-09  9:01 UTC (permalink / raw)
  To: ltp, chrubis, pvorel

The patch modifies init_module syscall test cases to account
for kernel module signature enforcement. It adds parsing for
the 'module.sig_enforce' parameter and adjusts test expectations
based on whether signature enforcement is enabled, using
new conditional logic.

If enforcement is active, tests expect an EKEYREJECTED error;
otherwise, they proceed as normal.

Signed-off-by: Li Wang <liwang@redhat.com>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Tested-by: Petr Vorel <pvorel@suse.cz>
---
 .../syscalls/delete_module/delete_module01.c  |  8 ++++
 .../syscalls/delete_module/delete_module03.c  |  8 ++++
 .../syscalls/finit_module/finit_module01.c    | 15 +++++++-
 .../syscalls/finit_module/finit_module02.c    | 37 ++++++++++++-------
 .../syscalls/init_module/init_module01.c      | 13 +++++++
 .../syscalls/init_module/init_module02.c      | 19 +++++++++-
 6 files changed, 85 insertions(+), 15 deletions(-)

diff --git a/testcases/kernel/syscalls/delete_module/delete_module01.c b/testcases/kernel/syscalls/delete_module/delete_module01.c
index 90d8b5289..11c4eae58 100644
--- a/testcases/kernel/syscalls/delete_module/delete_module01.c
+++ b/testcases/kernel/syscalls/delete_module/delete_module01.c
@@ -14,8 +14,10 @@
  * Install dummy_del_mod.ko and delete it with delete_module(2).
  */
 
+#include <stdlib.h>
 #include "tst_test.h"
 #include "tst_module.h"
+#include "tst_kconfig.h"
 #include "lapi/syscalls.h"
 
 #define MODULE_NAME	"dummy_del_mod"
@@ -25,6 +27,12 @@ static int module_loaded;
 
 static void do_delete_module(void)
 {
+	struct tst_kcmdline_var params = TST_KCMDLINE_INIT("module.sig_enforce");
+
+	tst_kcmdline_parse(&params, 1);
+	if (atoi(params.value) == 1)
+		tst_brk(TCONF, "module signature is enforced, skip test");
+
 	if (!module_loaded) {
 		tst_module_load(MODULE_NAME_KO, NULL);
 		module_loaded = 1;
diff --git a/testcases/kernel/syscalls/delete_module/delete_module03.c b/testcases/kernel/syscalls/delete_module/delete_module03.c
index 7e92fc2af..fdf0c293d 100644
--- a/testcases/kernel/syscalls/delete_module/delete_module03.c
+++ b/testcases/kernel/syscalls/delete_module/delete_module03.c
@@ -12,9 +12,11 @@
  * if tried to remove a module while other modules depend on this module.
  */
 
+#include <stdlib.h>
 #include <errno.h>
 #include "tst_test.h"
 #include "tst_module.h"
+#include "tst_kconfig.h"
 #include "lapi/syscalls.h"
 
 #define DUMMY_MOD		"dummy_del_mod"
@@ -50,6 +52,12 @@ static void do_delete_module(void)
 
 static void setup(void)
 {
+	struct tst_kcmdline_var params = TST_KCMDLINE_INIT("module.sig_enforce");
+
+	tst_kcmdline_parse(&params, 1);
+	if (atoi(params.value) == 1)
+		tst_brk(TCONF, "module signature is enforced, skip test");
+
 	/* Load first kernel module */
 	tst_module_load(DUMMY_MOD_KO, NULL);
 	dummy_mod_loaded = 1;
diff --git a/testcases/kernel/syscalls/finit_module/finit_module01.c b/testcases/kernel/syscalls/finit_module/finit_module01.c
index 1929c30fa..01c5e987d 100644
--- a/testcases/kernel/syscalls/finit_module/finit_module01.c
+++ b/testcases/kernel/syscalls/finit_module/finit_module01.c
@@ -13,18 +13,25 @@
  * Inserts a simple module after opening and mmaping the module file.
  */
 
+#include <stdlib.h>
 #include <errno.h>
 #include "lapi/init_module.h"
 #include "tst_module.h"
+#include "tst_kconfig.h"
 
 #define MODULE_NAME	"finit_module.ko"
 
-static int fd;
+static int fd, sig_enforce;
 
 static char *mod_path;
 
 static void setup(void)
 {
+	struct tst_kcmdline_var params = TST_KCMDLINE_INIT("module.sig_enforce");
+
+	tst_kcmdline_parse(&params, 1);
+	sig_enforce = atoi(params.value);
+
 	tst_module_exists(MODULE_NAME, &mod_path);
 
 	fd = SAFE_OPEN(mod_path, O_RDONLY|O_CLOEXEC);
@@ -32,6 +39,12 @@ static void setup(void)
 
 static void run(void)
 {
+	if (sig_enforce == 1) {
+		tst_res(TINFO, "module signature is enforced");
+		TST_EXP_FAIL(finit_module(fd, "status=valid", 0), EKEYREJECTED);
+		return;
+	}
+
 	TST_EXP_PASS(finit_module(fd, "status=valid", 0));
 	if (!TST_PASS)
 		return;
diff --git a/testcases/kernel/syscalls/finit_module/finit_module02.c b/testcases/kernel/syscalls/finit_module/finit_module02.c
index 223d9b388..22bb50be9 100644
--- a/testcases/kernel/syscalls/finit_module/finit_module02.c
+++ b/testcases/kernel/syscalls/finit_module/finit_module02.c
@@ -14,9 +14,11 @@
  */
 
 #include <linux/capability.h>
+#include <stdlib.h>
 #include <errno.h>
 #include "lapi/init_module.h"
 #include "tst_module.h"
+#include "tst_kconfig.h"
 #include "tst_capability.h"
 
 #define MODULE_NAME	"finit_module.ko"
@@ -25,7 +27,7 @@
 static char *mod_path;
 
 static int fd, fd_zero, fd_invalid = -1, fd_dir;
-static int kernel_lockdown, secure_boot;
+static int kernel_lockdown, secure_boot, sig_enforce;
 
 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);
@@ -59,27 +61,26 @@ static void dir_setup(struct tcase *tc)
 }
 
 static struct tcase tcases[] = {
-	{"invalid-fd", &fd_invalid, "", O_RDONLY | O_CLOEXEC, 0, 0, 0, 0,
-		bad_fd_setup},
+	{"invalid-fd", &fd_invalid, "", O_RDONLY | O_CLOEXEC, 0, 0, 0, 0, bad_fd_setup},
 	{"zero-fd", &fd_zero, "", O_RDONLY | O_CLOEXEC, 0, 0, EINVAL, 0, NULL},
 	{"null-param", &fd, NULL, O_RDONLY | O_CLOEXEC, 0, 0, EFAULT, 1, NULL},
-	{"invalid-param", &fd, "status=invalid", O_RDONLY | O_CLOEXEC, 0, 0,
-		EINVAL, 1, NULL},
-	{"invalid-flags", &fd, "", O_RDONLY | O_CLOEXEC, -1, 0, EINVAL, 0,
-		NULL},
+	{"invalid-param", &fd, "status=invalid", O_RDONLY | O_CLOEXEC, 0, 0, EINVAL, 1, NULL},
+	{"invalid-flags", &fd, "", O_RDONLY | O_CLOEXEC, -1, 0, EINVAL, 0, NULL},
 	{"no-perm", &fd, "", O_RDONLY | O_CLOEXEC, 0, 1, EPERM, 0, NULL},
-	{"module-exists", &fd, "", O_RDONLY | O_CLOEXEC, 0, 0, EEXIST, 1,
-		NULL},
-	{"file-not-readable", &fd, "", O_WRONLY | O_CLOEXEC, 0, 0, EBADF, 0,
-		NULL},
-	{"file-readwrite", &fd, "", O_RDWR | O_CLOEXEC, 0, 0, ETXTBSY, 0,
-		NULL},
+	{"module-exists", &fd, "", O_RDONLY | O_CLOEXEC, 0, 0, EEXIST, 1, NULL},
+	{"module-unsigned", &fd, "", O_RDONLY | O_CLOEXEC, 0, 0, EKEYREJECTED, 1, NULL},
+	{"file-not-readable", &fd, "", O_WRONLY | O_CLOEXEC, 0, 0, EBADF, 0, NULL},
+	{"file-readwrite", &fd, "", O_RDWR | O_CLOEXEC, 0, 0, ETXTBSY, 0, NULL},
 	{"directory", &fd_dir, "", O_RDONLY | O_CLOEXEC, 0, 0, 0, 0, dir_setup},
 };
 
 static void setup(void)
 {
 	unsigned long int i;
+	struct tst_kcmdline_var params = TST_KCMDLINE_INIT("module.sig_enforce");
+
+	tst_kcmdline_parse(&params, 1);
+	sig_enforce = atoi(params.value);
 
 	tst_module_exists(MODULE_NAME, &mod_path);
 
@@ -109,6 +110,16 @@ static void run(unsigned int n)
 		return;
 	}
 
+	if ((sig_enforce == 1) && (tc->exp_errno != EKEYREJECTED)) {
+		tst_res(TCONF, "module signature is enforced, skipping %s", tc->name);
+		return;
+	}
+
+	if ((sig_enforce != 1) && (tc->exp_errno == EKEYREJECTED)) {
+		tst_res(TCONF, "module signature is not enforced, skipping %s", tc->name);
+		return;
+	}
+
 	fd = SAFE_OPEN(mod_path, tc->open_flags);
 
 	if (tc->cap)
diff --git a/testcases/kernel/syscalls/init_module/init_module01.c b/testcases/kernel/syscalls/init_module/init_module01.c
index 26ff0b93b..1f2442635 100644
--- a/testcases/kernel/syscalls/init_module/init_module01.c
+++ b/testcases/kernel/syscalls/init_module/init_module01.c
@@ -13,18 +13,25 @@
  * Inserts a simple module after opening and mmaping the module file.
  */
 
+#include <stdlib.h>
 #include <errno.h>
 #include "lapi/init_module.h"
 #include "tst_module.h"
+#include "tst_kconfig.h"
 
 #define MODULE_NAME	"init_module.ko"
 
 static struct stat sb;
 static void *buf;
+static int sig_enforce;
 
 static void setup(void)
 {
 	int fd;
+	struct tst_kcmdline_var params = TST_KCMDLINE_INIT("module.sig_enforce");
+
+	tst_kcmdline_parse(&params, 1);
+	sig_enforce = atoi(params.value);
 
 	tst_module_exists(MODULE_NAME, NULL);
 
@@ -36,6 +43,12 @@ static void setup(void)
 
 static void run(void)
 {
+	if (sig_enforce == 1) {
+		tst_res(TINFO, "module signature is enforced");
+		TST_EXP_FAIL(init_module(buf, sb.st_size, "status=valid"), EKEYREJECTED);
+		return;
+	}
+
 	TST_EXP_PASS(init_module(buf, sb.st_size, "status=valid"));
 	if (!TST_PASS)
 		return;
diff --git a/testcases/kernel/syscalls/init_module/init_module02.c b/testcases/kernel/syscalls/init_module/init_module02.c
index e6730e21c..e69628fc6 100644
--- a/testcases/kernel/syscalls/init_module/init_module02.c
+++ b/testcases/kernel/syscalls/init_module/init_module02.c
@@ -14,15 +14,17 @@
  */
 
 #include <linux/capability.h>
+#include <stdlib.h>
 #include <errno.h>
 #include "lapi/init_module.h"
+#include "tst_kconfig.h"
 #include "tst_module.h"
 #include "tst_capability.h"
 
 #define MODULE_NAME	"init_module.ko"
 
 static unsigned long size, zero_size;
-static int kernel_lockdown, secure_boot;
+static int kernel_lockdown, secure_boot, sig_enforce;
 static void *buf, *faulty_buf, *null_buf;
 
 static struct tst_cap cap_req = TST_CAP(TST_CAP_REQ, CAP_SYS_MODULE);
@@ -44,12 +46,17 @@ static struct tcase {
 	{"invalid_param", &buf, &size, "status=invalid", 0, 1, EINVAL},
 	{"no-perm", &buf, &size, "", 1, 0, EPERM},
 	{"module-exists", &buf, &size, "", 0, 1, EEXIST},
+	{"module-unsigned", &buf, &size, "", 0, 1, EKEYREJECTED},
 };
 
 static void setup(void)
 {
 	struct stat sb;
 	int fd;
+	struct tst_kcmdline_var params = TST_KCMDLINE_INIT("module.sig_enforce");
+
+	tst_kcmdline_parse(&params, 1);
+	sig_enforce = atoi(params.value);
 
 	tst_module_exists(MODULE_NAME, NULL);
 
@@ -73,6 +80,16 @@ static void run(unsigned int n)
 		return;
 	}
 
+	if ((sig_enforce == 1) && (tc->exp_errno != EKEYREJECTED)) {
+		tst_res(TCONF, "module signature is enforced, skipping %s", tc->name);
+		return;
+	}
+
+	if ((sig_enforce != 1) && (tc->exp_errno == EKEYREJECTED)) {
+		tst_res(TCONF, "module signature is not enforced, skipping %s", tc->name);
+		return;
+	}
+
 	if (tc->cap)
 		tst_cap_action(&cap_drop);
 
-- 
2.40.1


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* [LTP] [PATCH v2 3/3] stack_clash: make use of tst_kcmdline_parse
  2024-03-09  9:01 [LTP] [PATCH v2 0/3] provide a unified way to parse /proc/cmdline Li Wang
  2024-03-09  9:01 ` [LTP] [PATCH v2 1/3] kconfig: add funtion " Li Wang
  2024-03-09  9:01 ` [LTP] [PATCH v2 2/3] init_module: To handle kernel module signature enforcement Li Wang
@ 2024-03-09  9:01 ` Li Wang
  2 siblings, 0 replies; 5+ messages in thread
From: Li Wang @ 2024-03-09  9:01 UTC (permalink / raw)
  To: ltp, chrubis, pvorel

Signed-off-by: Li Wang <liwang@redhat.com>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
---
 testcases/cve/stack_clash.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/testcases/cve/stack_clash.c b/testcases/cve/stack_clash.c
index 56b970a1b..b11774f28 100644
--- a/testcases/cve/stack_clash.c
+++ b/testcases/cve/stack_clash.c
@@ -44,6 +44,7 @@
 #include <stdlib.h>
 
 #include "tst_test.h"
+#include "tst_kconfig.h"
 #include "tst_safe_stdio.h"
 #include "lapi/mmap.h"
 
@@ -272,19 +273,14 @@ void do_child(void)
 
 void setup(void)
 {
-	char buf[4096], *p;
-
 	page_size = sysconf(_SC_PAGESIZE);
 	page_mask = ~(page_size - 1);
 
-	buf[4095] = '\0';
-	SAFE_FILE_SCANF("/proc/cmdline", "%4095[^\n]", buf);
+	struct tst_kcmdline_var params = TST_KCMDLINE_INIT("stack_guard_gap");
+	tst_kcmdline_parse(&params, 1);
 
-	if ((p = strstr(buf, "stack_guard_gap=")) != NULL) {
-		if (sscanf(p, "stack_guard_gap=%ld", &GAP_PAGES) != 1) {
-			tst_brk(TBROK | TERRNO, "sscanf");
-			return;
-		}
+	if (params.value[0] != '\0') {
+		GAP_PAGES= atol(params.value);
 		tst_res(TINFO, "stack_guard_gap = %ld", GAP_PAGES);
 	}
 
-- 
2.40.1


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* Re: [LTP] [PATCH v2 1/3] kconfig: add funtion to parse /proc/cmdline
  2024-03-09  9:01 ` [LTP] [PATCH v2 1/3] kconfig: add funtion " Li Wang
@ 2024-03-11 12:27   ` Petr Vorel
  0 siblings, 0 replies; 5+ messages in thread
From: Petr Vorel @ 2024-03-11 12:27 UTC (permalink / raw)
  To: Li Wang; +Cc: ltp

Hi Li,

It looks to me you introduced new warnings, could you please fix them before
merged?
tst_kconfig.c:398: ERROR: code indent should use tabs where possible
tst_kconfig.c:398: WARNING: please, no spaces at the start of a line
tst_kconfig.c:570: ERROR: open brace '{' following function definitions go on the next line
tst_kconfig.c:600: ERROR: trailing statements should be on next line

Also nits (to be changed before merge) below.

> A new structure tst_kcmdline_var is defined to hold a command-line
> argument's key and a fixed-size value. Furthermore, function
> tst_kcmdline_parse is added to the corresponding .c file, which
> reads from /proc/cmdline, parses the command-line arguments, and
> populates the tst_kcmdline_var array with the obtained key-value
> pairs, ensuring safe file operations and buffer size checks.

> Signed-off-by: Li Wang <liwang@redhat.com>
> ---
>  include/tst_kconfig.h | 23 ++++++++++++++++++++++
>  lib/tst_kconfig.c     | 45 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 68 insertions(+)

> diff --git a/include/tst_kconfig.h b/include/tst_kconfig.h
> index 8b24a8380..a8cbfb786 100644
> --- a/include/tst_kconfig.h
> +++ b/include/tst_kconfig.h
> @@ -64,4 +64,27 @@ void tst_kconfig_read(struct tst_kconfig_var vars[], size_t vars_len);
>   */
>  int tst_kconfig_check(const char *const kconfigs[]);

> +/**
> + * Macro to initialize a tst_kcmdline_var structure with a specified parameter
> + * name and an empty value. This is useful for setting up an array of parameter
> + * structures before parsing the actual command-line arguments.
> + */
> +#define TST_KCMDLINE_INIT(paraname) { \
> +	.key = paraname, \
> +	.value = "" \
> +}
> +
> +/* Structure for storing command-line parameter key and its corresponding value */
nit: I guess /** is for autogenerated docs (maybe Andrea uses it one day with
sphinx :). Therefore maybe here also /* ? Also missing dot at the end of the
sentence.

> +struct tst_kcmdline_var {
> +	const char *key;
> +	char value[128];
> +};
> +
> +/**
> + * Parses command-line parameters from /proc/cmdline and stores them in params array
> + * params: The array of tst_kcmdline_var structures to be filled with parsed key-value pairs
nit: @param params, missing dot at the end of the sentence.
> + * params_len: The length of the params array, indicating how many parameters to parse
nit: @param params_len, missing dot at the end of the sentence.
> + */
> +void tst_kcmdline_parse(struct tst_kcmdline_var params[], size_t params_len);
> +
>  #endif	/* TST_KCONFIG_H__ */
> diff --git a/lib/tst_kconfig.c b/lib/tst_kconfig.c
> index 595ea4b09..c200dd261 100644
> --- a/lib/tst_kconfig.c
> +++ b/lib/tst_kconfig.c
> @@ -14,6 +14,7 @@
>  #include "tst_private.h"
>  #include "tst_kconfig.h"
>  #include "tst_bool_expr.h"
> +#include "tst_safe_stdio.h"

>  static int kconfig_skip_check(void)
>  {
> @@ -565,3 +566,47 @@ char tst_kconfig_get(const char *confname)

>  	return var.choice;
>  }
> +
> +void tst_kcmdline_parse(struct tst_kcmdline_var params[], size_t params_len) {
> +	char buf[128];
> +	size_t buf_pos = 0, i;
> +	int var_id = -1, c;
> +
> +	FILE *f = SAFE_FOPEN("/proc/cmdline", "r");
> +
> +	while ((c = fgetc(f)) != EOF) {
I hope fgetc() does not explode on ppc64le the same way as it did on
libs/libltpswap/libswap.c (see 6f82542fc ("libswap.c: Improve calculate swap dev
number")), where for some reason fgets() had to be used. But here it's actually
processing chars, not just counting EOF, so it should be ok. I'll try to retest it,
but please have look as well.

> +		switch (c) {
> +		case '=':
> +			buf[buf_pos] = '\0';
> +			for (i = 0; i < params_len; i++) {
> +				if (strcmp(buf, params[i].key) == 0)
> +					var_id = (int)i;
> +			}
> +
> +			buf_pos = 0;
> +		break;
> +		case ' ':
> +		case '\n':
> +			buf[buf_pos] = '\0';
> +			if (var_id >= 0 && var_id < (int)params_len)
> +				strcpy(params[var_id].value, buf);
> +
> +			var_id = -1;
> +			buf_pos = 0;
> +		break;
> +		default:
> +			if (buf_pos + 1  >= sizeof(buf)) {
> +				tst_res(TWARN, "Buffer overflowed while parsing /proc/cmdline");
> +				while ((c = fgetc(f)) != EOF && c != ' ' && c != '\n');
> +
> +				var_id = -1;
> +				buf_pos = 0;
> +			}
> +
> +			buf[buf_pos++] = (char)c;
> +		break;
> +		}
> +	}

LGTM.

Reviewed-by: Petr Vorel <pvorel@suse.cz>

BTW it would be great to add a test for this functionality (there are
already some tests in lib/newlib_tests/test_kconfig*.c).

Kind regards,
Petr

> +
> +	SAFE_FCLOSE(f);
> +}

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

end of thread, other threads:[~2024-03-11 12:27 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-09  9:01 [LTP] [PATCH v2 0/3] provide a unified way to parse /proc/cmdline Li Wang
2024-03-09  9:01 ` [LTP] [PATCH v2 1/3] kconfig: add funtion " Li Wang
2024-03-11 12:27   ` Petr Vorel
2024-03-09  9:01 ` [LTP] [PATCH v2 2/3] init_module: To handle kernel module signature enforcement Li Wang
2024-03-09  9:01 ` [LTP] [PATCH v2 3/3] stack_clash: make use of tst_kcmdline_parse Li Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox