[PATCH 1/1] selftests/cachestat: add fault-path errno coverage for cachestat

Mohammed Rizwan Kaniyate <[email protected]>
Newsgroups org.kernel.vger.linux-kselftest,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
From: Mohammed Rizwan Kaniyate <[email protected]>

Add a dedicated fault test for cachestat argument
validation and errno behaviour.
The test verifies EBADF, EFAULT and EINVAL case
using a common helper that
resets/checks errno and reports mismatch.

Signed-off-by: Mohammed Rizwan Kaniyate <[email protected]>
---
 .../selftests/cachestat/test_cachestat.c      | 56 +++++++++++++++++--
 1 file changed, 50 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/cachestat/test_cachestat.c b/tools/testing/selftests/cachestat/test_cachestat.c
index 542cd09cb4434..6b23022b4ec76 100644
--- a/tools/testing/selftests/cachestat/test_cachestat.c
+++ b/tools/testing/selftests/cachestat/test_cachestat.c
@@ -18,7 +18,7 @@
 
 #include "kselftest.h"
 
-#define NR_TESTS	9
+#define NR_TESTS	10
 
 static const char * const dev_files[] = {
 	"/dev/zero", "/dev/null", "/dev/urandom",
@@ -294,23 +294,67 @@ bool run_cachestat_test(enum file_type type)
 	return ret;
 }
 
+bool expect_cachestat_errno(int fd, struct cachestat_range *csr, struct cachestat *cs,
+	unsigned int flags, int expected_errno, const char *desc)
+{
+	int sys_ret;
+
+	errno = 0;
+
+	sys_ret = syscall(__NR_cachestat, fd, csr, cs, flags);
+
+	if (sys_ret == -1 && errno == expected_errno) {
+		ksft_print_msg("cachestat test success for %s\n", desc);
+	} else {
+		ksft_print_msg("cachestat test fail : %s: ret=%d, errno=%d expected_errno=%d\n",
+			desc, sys_ret, errno, expected_errno);
+		return false;
+	}
+
+	return true;
+}
+
+bool test_cachestat_faults(void)
+{
+	bool ret = true;
+	struct cachestat cs = {0};
+	struct cachestat_range cr = {0, 0};
+	// Test that the cachestat syscall fails with a bad file descriptor
+	ret &= expect_cachestat_errno(-1, &cr, &cs, 0, EBADF, "bad file descriptor");
+
+	// Fails with a NULL cacherange
+	ret &= expect_cachestat_errno(0, NULL, &cs, 0, EFAULT, "NULL range");
+	// Fails with a NULL result
+	ret &= expect_cachestat_errno(0, &cr, NULL, 0, EFAULT, "NULL result");
+	// Fails with invalid user space address
+	ret &= expect_cachestat_errno(0, (struct cachestat_range *)0x1, &cs,
+		0, EFAULT, "invalid range address");
+	// Fails with invalid user space address
+	ret &= expect_cachestat_errno(0, &cr, (struct cachestat *)0x1, 0,
+		EFAULT, "invalid result address");
+	// Fails with invalid flag
+	ret &= expect_cachestat_errno(0, &cr, &cs, 1, EINVAL, "invalid flags");
+
+	return ret;
+}
+
 int main(void)
 {
 	int ret;
 
 	ksft_print_header();
 
+	errno = 0;
 	ret = syscall(__NR_cachestat, -1, NULL, NULL, 0);
 	if (ret == -1 && errno == ENOSYS)
 		ksft_exit_skip("cachestat syscall not available\n");
-
+	ret = 0;
 	ksft_set_plan(NR_TESTS);
 
-	if (ret == -1 && errno == EBADF) {
-		ksft_test_result_pass("bad file descriptor recognized\n");
-		ret = 0;
+	if (test_cachestat_faults()) {
+		ksft_test_result_pass("cachestat syscall fault tests passed\n");
 	} else {
-		ksft_test_result_fail("bad file descriptor ignored\n");
+		ksft_test_result_fail("cachestat syscall fault tests failed\n");
 		ret = 1;
 	}
 
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.