Blob Blame History Raw
From 1ec648999d3bf01ae87cac65c810d5d8f19c71c0 Mon Sep 17 00:00:00 2001
From: Sven Schnelle <svens@stackframe.org>
Date: Tue, 10 Nov 2020 07:38:34 +0100
Subject: [PATCH 148/149] tests: fix execve test with fresh linux kernels

Starting with Linux commit v5.9-rc1~164^2^2~2, execve copies syscall
arguments before trying to find the executable, failing with EFAULT
in case of a faulty address.  Adjust the test to handle both variants
of execve behaviour.

* tests/execve.c (errstr): New variable.
(call_execve): New function.
(main): Use it instead of execve.  Do not hardcode ENOENT in expected
output of tests, use errstr instead.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
---
 tests/execve.c | 54 ++++++++++++++++++++++++++++++++----------------------
 1 file changed, 32 insertions(+), 22 deletions(-)

diff --git a/tests/execve.c b/tests/execve.c
index 2f6ae52..961d284 100644
--- a/tests/execve.c
+++ b/tests/execve.c
@@ -12,6 +12,16 @@
 #include <stdio.h>
 #include <unistd.h>
 
+static const char *errstr;
+
+static int
+call_execve(const char *pathname, char *const *argv, char *const *envp)
+{
+	int rc = execve(pathname, argv, envp);
+	errstr = sprintrc(rc);
+	return rc;
+}
+
 #define FILENAME "test.execve\nfilename"
 #define Q_FILENAME "test.execve\\nfilename"
 
@@ -43,7 +53,7 @@ main(void)
 	char ** const tail_argv = tail_memdup(argv, sizeof(argv));
 	char ** const tail_envp = tail_memdup(envp, sizeof(envp));
 
-	execve(FILENAME, tail_argv, tail_envp);
+	call_execve(FILENAME, tail_argv, tail_envp);
 	printf("execve(\"%s\""
 	       ", [\"%s\", \"%s\", \"%s\", %p, %p, %p, ... /* %p */]"
 #if VERBOSE
@@ -51,7 +61,7 @@ main(void)
 #else
 	       ", %p /* 5 vars, unterminated */"
 #endif
-	       ") = -1 ENOENT (%m)\n",
+	       ") = %s\n",
 	       Q_FILENAME, q_argv[0], q_argv[1], q_argv[2],
 	       argv[3], argv[4], argv[5], (char *) tail_argv + sizeof(argv)
 #if VERBOSE
@@ -60,60 +70,60 @@ main(void)
 #else
 	       , tail_envp
 #endif
-	       );
+	       , errstr);
 
 	tail_argv[ARRAY_SIZE(q_argv)] = NULL;
 	tail_envp[ARRAY_SIZE(q_envp)] = NULL;
 	(void) q_envp;	/* workaround for clang bug #33068 */
 
-	execve(FILENAME, tail_argv, tail_envp);
+	call_execve(FILENAME, tail_argv, tail_envp);
 	printf("execve(\"%s\", [\"%s\", \"%s\", \"%s\"]"
 #if VERBOSE
 	       ", [\"%s\", \"%s\"]"
 #else
 	       ", %p /* 2 vars */"
 #endif
-	       ") = -1 ENOENT (%m)\n",
+	       ") = %s\n",
 	       Q_FILENAME, q_argv[0], q_argv[1], q_argv[2]
 #if VERBOSE
 	       , q_envp[0], q_envp[1]
 #else
 	       , tail_envp
 #endif
-	       );
+	       , errstr);
 
-	execve(FILENAME, tail_argv + 2, tail_envp + 1);
+	call_execve(FILENAME, tail_argv + 2, tail_envp + 1);
 	printf("execve(\"%s\", [\"%s\"]"
 #if VERBOSE
 	       ", [\"%s\"]"
 #else
 	       ", %p /* 1 var */"
 #endif
-	       ") = -1 ENOENT (%m)\n",
+	       ") = %s\n",
 	       Q_FILENAME, q_argv[2]
 #if VERBOSE
 	       , q_envp[1]
 #else
 	       , tail_envp + 1
 #endif
-	       );
+	       , errstr);
 
 	TAIL_ALLOC_OBJECT_CONST_PTR(char *, empty);
 	char **const efault = empty + 1;
 	*empty = NULL;
 
-	execve(FILENAME, empty, empty);
+	call_execve(FILENAME, empty, empty);
 	printf("execve(\"%s\", []"
 #if VERBOSE
 	       ", []"
 #else
 	       ", %p /* 0 vars */"
 #endif
-	       ") = -1 ENOENT (%m)\n", Q_FILENAME
+	       ") = %s\n", Q_FILENAME
 #if !VERBOSE
 	       , empty
 #endif
-	       );
+	       , errstr);
 
 	char *const str_a = tail_alloc(DEFAULT_STRLEN + 2);
 	fill_memory_ex(str_a, DEFAULT_STRLEN + 1, '0', 10);
@@ -132,7 +142,7 @@ main(void)
 	}
 	a[i] = b[i] = NULL;
 
-	execve(FILENAME, a, b);
+	call_execve(FILENAME, a, b);
 	printf("execve(\"%s\", [\"%.*s\"...", Q_FILENAME, DEFAULT_STRLEN, a[0]);
 	for (i = 1; i < DEFAULT_STRLEN; ++i)
 		printf(", \"%s\"", a[i]);
@@ -149,9 +159,9 @@ main(void)
 #else
 	printf("], %p /* %u vars */", b, DEFAULT_STRLEN + 1);
 #endif
-	printf(") = -1 ENOENT (%m)\n");
+	printf(") = %s\n", errstr);
 
-	execve(FILENAME, a + 1, b + 1);
+	call_execve(FILENAME, a + 1, b + 1);
 	printf("execve(\"%s\", [\"%s\"", Q_FILENAME, a[1]);
 	for (i = 2; i <= DEFAULT_STRLEN; ++i)
 		printf(", \"%s\"", a[i]);
@@ -163,15 +173,15 @@ main(void)
 #else
 	printf("], %p /* %d vars */", b + 1, DEFAULT_STRLEN);
 #endif
-	printf(") = -1 ENOENT (%m)\n");
+	printf(") = %s\n", errstr);
 
-	execve(FILENAME, (char **) tail_argv[ARRAY_SIZE(q_argv)], efault);
-	printf("execve(\"%s\", NULL, %p) = -1 ENOENT (%m)\n",
-	       Q_FILENAME, efault);
+	call_execve(FILENAME, (char **) tail_argv[ARRAY_SIZE(q_argv)], efault);
+	printf("execve(\"%s\", NULL, %p) = %s\n",
+	       Q_FILENAME, efault, errstr);
 
-	execve(FILENAME, efault, NULL);
-	printf("execve(\"%s\", %p, NULL) = -1 ENOENT (%m)\n",
-	       Q_FILENAME, efault);
+	call_execve(FILENAME, efault, NULL);
+	printf("execve(\"%s\", %p, NULL) = %s\n",
+	       Q_FILENAME, efault, errstr);
 
 	leave_and_remove_subdir();
 
diff --git a/tests-m32/execve.c b/tests-m32/execve.c
index 2f6ae52..961d284 100644
--- a/tests-m32/execve.c
+++ b/tests-m32/execve.c
@@ -12,6 +12,16 @@
 #include <stdio.h>
 #include <unistd.h>
 
+static const char *errstr;
+
+static int
+call_execve(const char *pathname, char *const *argv, char *const *envp)
+{
+	int rc = execve(pathname, argv, envp);
+	errstr = sprintrc(rc);
+	return rc;
+}
+
 #define FILENAME "test.execve\nfilename"
 #define Q_FILENAME "test.execve\\nfilename"
 
@@ -43,7 +53,7 @@ main(void)
 	char ** const tail_argv = tail_memdup(argv, sizeof(argv));
 	char ** const tail_envp = tail_memdup(envp, sizeof(envp));
 
-	execve(FILENAME, tail_argv, tail_envp);
+	call_execve(FILENAME, tail_argv, tail_envp);
 	printf("execve(\"%s\""
 	       ", [\"%s\", \"%s\", \"%s\", %p, %p, %p, ... /* %p */]"
 #if VERBOSE
@@ -51,7 +61,7 @@ main(void)
 #else
 	       ", %p /* 5 vars, unterminated */"
 #endif
-	       ") = -1 ENOENT (%m)\n",
+	       ") = %s\n",
 	       Q_FILENAME, q_argv[0], q_argv[1], q_argv[2],
 	       argv[3], argv[4], argv[5], (char *) tail_argv + sizeof(argv)
 #if VERBOSE
@@ -60,60 +70,60 @@ main(void)
 #else
 	       , tail_envp
 #endif
-	       );
+	       , errstr);
 
 	tail_argv[ARRAY_SIZE(q_argv)] = NULL;
 	tail_envp[ARRAY_SIZE(q_envp)] = NULL;
 	(void) q_envp;	/* workaround for clang bug #33068 */
 
-	execve(FILENAME, tail_argv, tail_envp);
+	call_execve(FILENAME, tail_argv, tail_envp);
 	printf("execve(\"%s\", [\"%s\", \"%s\", \"%s\"]"
 #if VERBOSE
 	       ", [\"%s\", \"%s\"]"
 #else
 	       ", %p /* 2 vars */"
 #endif
-	       ") = -1 ENOENT (%m)\n",
+	       ") = %s\n",
 	       Q_FILENAME, q_argv[0], q_argv[1], q_argv[2]
 #if VERBOSE
 	       , q_envp[0], q_envp[1]
 #else
 	       , tail_envp
 #endif
-	       );
+	       , errstr);
 
-	execve(FILENAME, tail_argv + 2, tail_envp + 1);
+	call_execve(FILENAME, tail_argv + 2, tail_envp + 1);
 	printf("execve(\"%s\", [\"%s\"]"
 #if VERBOSE
 	       ", [\"%s\"]"
 #else
 	       ", %p /* 1 var */"
 #endif
-	       ") = -1 ENOENT (%m)\n",
+	       ") = %s\n",
 	       Q_FILENAME, q_argv[2]
 #if VERBOSE
 	       , q_envp[1]
 #else
 	       , tail_envp + 1
 #endif
-	       );
+	       , errstr);
 
 	TAIL_ALLOC_OBJECT_CONST_PTR(char *, empty);
 	char **const efault = empty + 1;
 	*empty = NULL;
 
-	execve(FILENAME, empty, empty);
+	call_execve(FILENAME, empty, empty);
 	printf("execve(\"%s\", []"
 #if VERBOSE
 	       ", []"
 #else
 	       ", %p /* 0 vars */"
 #endif
-	       ") = -1 ENOENT (%m)\n", Q_FILENAME
+	       ") = %s\n", Q_FILENAME
 #if !VERBOSE
 	       , empty
 #endif
-	       );
+	       , errstr);
 
 	char *const str_a = tail_alloc(DEFAULT_STRLEN + 2);
 	fill_memory_ex(str_a, DEFAULT_STRLEN + 1, '0', 10);
@@ -132,7 +142,7 @@ main(void)
 	}
 	a[i] = b[i] = NULL;
 
-	execve(FILENAME, a, b);
+	call_execve(FILENAME, a, b);
 	printf("execve(\"%s\", [\"%.*s\"...", Q_FILENAME, DEFAULT_STRLEN, a[0]);
 	for (i = 1; i < DEFAULT_STRLEN; ++i)
 		printf(", \"%s\"", a[i]);
@@ -149,9 +159,9 @@ main(void)
 #else
 	printf("], %p /* %u vars */", b, DEFAULT_STRLEN + 1);
 #endif
-	printf(") = -1 ENOENT (%m)\n");
+	printf(") = %s\n", errstr);
 
-	execve(FILENAME, a + 1, b + 1);
+	call_execve(FILENAME, a + 1, b + 1);
 	printf("execve(\"%s\", [\"%s\"", Q_FILENAME, a[1]);
 	for (i = 2; i <= DEFAULT_STRLEN; ++i)
 		printf(", \"%s\"", a[i]);
@@ -163,15 +173,15 @@ main(void)
 #else
 	printf("], %p /* %d vars */", b + 1, DEFAULT_STRLEN);
 #endif
-	printf(") = -1 ENOENT (%m)\n");
+	printf(") = %s\n", errstr);
 
-	execve(FILENAME, (char **) tail_argv[ARRAY_SIZE(q_argv)], efault);
-	printf("execve(\"%s\", NULL, %p) = -1 ENOENT (%m)\n",
-	       Q_FILENAME, efault);
+	call_execve(FILENAME, (char **) tail_argv[ARRAY_SIZE(q_argv)], efault);
+	printf("execve(\"%s\", NULL, %p) = %s\n",
+	       Q_FILENAME, efault, errstr);
 
-	execve(FILENAME, efault, NULL);
-	printf("execve(\"%s\", %p, NULL) = -1 ENOENT (%m)\n",
-	       Q_FILENAME, efault);
+	call_execve(FILENAME, efault, NULL);
+	printf("execve(\"%s\", %p, NULL) = %s\n",
+	       Q_FILENAME, efault, errstr);
 
 	leave_and_remove_subdir();
 
diff --git a/tests-mx32/execve.c b/tests-mx32/execve.c
index 2f6ae52..961d284 100644
--- a/tests-mx32/execve.c
+++ b/tests-mx32/execve.c
@@ -12,6 +12,16 @@
 #include <stdio.h>
 #include <unistd.h>
 
+static const char *errstr;
+
+static int
+call_execve(const char *pathname, char *const *argv, char *const *envp)
+{
+	int rc = execve(pathname, argv, envp);
+	errstr = sprintrc(rc);
+	return rc;
+}
+
 #define FILENAME "test.execve\nfilename"
 #define Q_FILENAME "test.execve\\nfilename"
 
@@ -43,7 +53,7 @@ main(void)
 	char ** const tail_argv = tail_memdup(argv, sizeof(argv));
 	char ** const tail_envp = tail_memdup(envp, sizeof(envp));
 
-	execve(FILENAME, tail_argv, tail_envp);
+	call_execve(FILENAME, tail_argv, tail_envp);
 	printf("execve(\"%s\""
 	       ", [\"%s\", \"%s\", \"%s\", %p, %p, %p, ... /* %p */]"
 #if VERBOSE
@@ -51,7 +61,7 @@ main(void)
 #else
 	       ", %p /* 5 vars, unterminated */"
 #endif
-	       ") = -1 ENOENT (%m)\n",
+	       ") = %s\n",
 	       Q_FILENAME, q_argv[0], q_argv[1], q_argv[2],
 	       argv[3], argv[4], argv[5], (char *) tail_argv + sizeof(argv)
 #if VERBOSE
@@ -60,60 +70,60 @@ main(void)
 #else
 	       , tail_envp
 #endif
-	       );
+	       , errstr);
 
 	tail_argv[ARRAY_SIZE(q_argv)] = NULL;
 	tail_envp[ARRAY_SIZE(q_envp)] = NULL;
 	(void) q_envp;	/* workaround for clang bug #33068 */
 
-	execve(FILENAME, tail_argv, tail_envp);
+	call_execve(FILENAME, tail_argv, tail_envp);
 	printf("execve(\"%s\", [\"%s\", \"%s\", \"%s\"]"
 #if VERBOSE
 	       ", [\"%s\", \"%s\"]"
 #else
 	       ", %p /* 2 vars */"
 #endif
-	       ") = -1 ENOENT (%m)\n",
+	       ") = %s\n",
 	       Q_FILENAME, q_argv[0], q_argv[1], q_argv[2]
 #if VERBOSE
 	       , q_envp[0], q_envp[1]
 #else
 	       , tail_envp
 #endif
-	       );
+	       , errstr);
 
-	execve(FILENAME, tail_argv + 2, tail_envp + 1);
+	call_execve(FILENAME, tail_argv + 2, tail_envp + 1);
 	printf("execve(\"%s\", [\"%s\"]"
 #if VERBOSE
 	       ", [\"%s\"]"
 #else
 	       ", %p /* 1 var */"
 #endif
-	       ") = -1 ENOENT (%m)\n",
+	       ") = %s\n",
 	       Q_FILENAME, q_argv[2]
 #if VERBOSE
 	       , q_envp[1]
 #else
 	       , tail_envp + 1
 #endif
-	       );
+	       , errstr);
 
 	TAIL_ALLOC_OBJECT_CONST_PTR(char *, empty);
 	char **const efault = empty + 1;
 	*empty = NULL;
 
-	execve(FILENAME, empty, empty);
+	call_execve(FILENAME, empty, empty);
 	printf("execve(\"%s\", []"
 #if VERBOSE
 	       ", []"
 #else
 	       ", %p /* 0 vars */"
 #endif
-	       ") = -1 ENOENT (%m)\n", Q_FILENAME
+	       ") = %s\n", Q_FILENAME
 #if !VERBOSE
 	       , empty
 #endif
-	       );
+	       , errstr);
 
 	char *const str_a = tail_alloc(DEFAULT_STRLEN + 2);
 	fill_memory_ex(str_a, DEFAULT_STRLEN + 1, '0', 10);
@@ -132,7 +142,7 @@ main(void)
 	}
 	a[i] = b[i] = NULL;
 
-	execve(FILENAME, a, b);
+	call_execve(FILENAME, a, b);
 	printf("execve(\"%s\", [\"%.*s\"...", Q_FILENAME, DEFAULT_STRLEN, a[0]);
 	for (i = 1; i < DEFAULT_STRLEN; ++i)
 		printf(", \"%s\"", a[i]);
@@ -149,9 +159,9 @@ main(void)
 #else
 	printf("], %p /* %u vars */", b, DEFAULT_STRLEN + 1);
 #endif
-	printf(") = -1 ENOENT (%m)\n");
+	printf(") = %s\n", errstr);
 
-	execve(FILENAME, a + 1, b + 1);
+	call_execve(FILENAME, a + 1, b + 1);
 	printf("execve(\"%s\", [\"%s\"", Q_FILENAME, a[1]);
 	for (i = 2; i <= DEFAULT_STRLEN; ++i)
 		printf(", \"%s\"", a[i]);
@@ -163,15 +173,15 @@ main(void)
 #else
 	printf("], %p /* %d vars */", b + 1, DEFAULT_STRLEN);
 #endif
-	printf(") = -1 ENOENT (%m)\n");
+	printf(") = %s\n", errstr);
 
-	execve(FILENAME, (char **) tail_argv[ARRAY_SIZE(q_argv)], efault);
-	printf("execve(\"%s\", NULL, %p) = -1 ENOENT (%m)\n",
-	       Q_FILENAME, efault);
+	call_execve(FILENAME, (char **) tail_argv[ARRAY_SIZE(q_argv)], efault);
+	printf("execve(\"%s\", NULL, %p) = %s\n",
+	       Q_FILENAME, efault, errstr);
 
-	execve(FILENAME, efault, NULL);
-	printf("execve(\"%s\", %p, NULL) = -1 ENOENT (%m)\n",
-	       Q_FILENAME, efault);
+	call_execve(FILENAME, efault, NULL);
+	printf("execve(\"%s\", %p, NULL) = %s\n",
+	       Q_FILENAME, efault, errstr);
 
 	leave_and_remove_subdir();
 
-- 
2.1.4