@@ -21,6 +21,8 @@
* Testcase to check fstatfs() sets errno correctly.
*/
+#include <setjmp.h>
+#include <signal.h>
#include <sys/vfs.h>
#include <sys/types.h>
#include <sys/statfs.h>
@@ -28,9 +30,6 @@
#include "test.h"
#include "safe_macros.h"
-static void setup(void);
-static void cleanup(void);
-
char *TCID = "fstatfs02";
static struct statfs buf;
@@ -53,6 +52,13 @@ static struct test_case_t {
int TST_TOTAL = ARRAY_SIZE(TC);
+static int sig_caught;
+static sigjmp_buf env;
+
+static void setup(void);
+static void cleanup(void);
+static void fstatfs_verify(const struct test_case_t *);
+
int main(int ac, char **av)
{
int lc;
@@ -67,23 +73,20 @@ int main(int ac, char **av)
tst_count = 0;
for (i = 0; i < TST_TOTAL; i++) {
+ sig_caught = 0;
+ if (sigsetjmp(env, 1) == 0)
+ fstatfs_verify(&TC[i]);
- TEST(fstatfs(TC[i].fd, TC[i].sbuf));
+ if (!sig_caught)
+ continue;
- if (TEST_RETURN != -1) {
- tst_resm(TFAIL, "call succeeded unexpectedly");
+ if (TC[i].error == EFAULT && sig_caught == SIGSEGV) {
+ tst_resm(TINFO, "received SIGSEGV instead of returning EFAULT");
+ tst_resm(TPASS | TTERRNO, "expected failure");
continue;
}
- if (TEST_ERRNO == TC[i].error) {
- tst_resm(TPASS, "expected failure - "
- "errno = %d : %s", TEST_ERRNO,
- strerror(TEST_ERRNO));
- } else {
- tst_resm(TFAIL, "unexpected error - %d : %s - "
- "expected %d", TEST_ERRNO,
- strerror(TEST_ERRNO), TC[i].error);
- }
+ tst_resm(TFAIL, "Received an unexpected signal: %d", sig_caught);
}
}
cleanup();
@@ -91,9 +94,16 @@ int main(int ac, char **av)
tst_exit();
}
+static void sighandler(int sig)
+{
+ sig_caught = sig;
+ siglongjmp(env, 1);
+
+}
+
static void setup(void)
{
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
+ tst_sig(NOFORK, sighandler, cleanup);
TEST_PAUSE;
@@ -103,6 +113,24 @@ static void setup(void)
#endif
}
+static void fstatfs_verify(const struct test_case_t *test)
+{
+ TEST(fstatfs(test->fd, test->sbuf));
+
+ if (TEST_RETURN != -1) {
+ tst_resm(TFAIL, "call succeeded unexpectedly");
+ return;
+ }
+
+ if (TEST_ERRNO == test->error) {
+ tst_resm(TPASS, "expected failure - errno = %d : %s",
+ TEST_ERRNO, strerror(TEST_ERRNO));
+ } else {
+ tst_resm(TFAIL, "unexpected error - %d : %s - expected %d",
+ TEST_ERRNO, strerror(TEST_ERRNO), test->error);
+ }
+}
+
static void cleanup(void)
{
#ifndef UCLINUX
@@ -32,6 +32,8 @@
* ELOOP.
*/
+#include <setjmp.h>
+#include <signal.h>
#include <sys/types.h>
#include <sys/statfs.h>
#include <sys/stat.h>
@@ -70,6 +72,10 @@ static struct test_case_t {
};
int TST_TOTAL = ARRAY_SIZE(TC);
+
+static int sig_caught;
+static sigjmp_buf env;
+
static void setup(void);
static void cleanup(void);
static void statfs_verify(const struct test_case_t *);
@@ -85,17 +91,37 @@ int main(int ac, char **av)
for (lc = 0; TEST_LOOPING(lc); lc++) {
tst_count = 0;
- for (i = 0; i < TST_TOTAL; i++)
- statfs_verify(&TC[i]);
+ for (i = 0; i < TST_TOTAL; i++) {
+ sig_caught = 0;
+ if (sigsetjmp(env, 1) == 0)
+ statfs_verify(&TC[i]);
+
+ if (!sig_caught)
+ continue;
+
+ if (TC[i].exp_error == EFAULT && sig_caught == SIGSEGV) {
+ tst_resm(TINFO, "received SIGSEGV instead of returning EFAULT");
+ tst_resm(TPASS | TTERRNO, "expected failure");
+ continue;
+ }
+
+ tst_resm(TFAIL, "Received an unexpected signal: %d", sig_caught);
+ }
}
cleanup();
tst_exit();
}
+static void sighandler(int sig)
+{
+ sig_caught = sig;
+ siglongjmp(env, 1);
+}
+
static void setup(void)
{
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
+ tst_sig(NOFORK, sighandler, cleanup);
TEST_PAUSE;
The [f]statfs02 testsuites check that [f]statfs returns EFUALT when the provided buf parameter is invalid. There are cases in which the supported libcs don't exhibit this behaviour. glibc versions newer than 2.34 and on systems that support [f]statfs64, call the syscall with a local struct statfs and then copy the result into buf. This throws a segfault for an invalid buf. musl dereferences buf before the syscall is called and, similarly, throws a segfault. Implement a sighandler to handle the cases where a segfault is thrown instead of returning EFAULT. Signed-off-by: Tudor Cretu <tudor.cretu@arm.com> --- testcases/kernel/syscalls/fstatfs/fstatfs02.c | 60 ++++++++++++++----- testcases/kernel/syscalls/statfs/statfs02.c | 32 +++++++++- 2 files changed, 73 insertions(+), 19 deletions(-)