Skip to contentSkip to conversation

selftests: capabilities: convert to TAP13 ksft framework

PATCH New Shuah Khan 1 participant 3 messages Jul 25, 2017 Kselftest

lore
Share & tools
lore

Shuah Khan

author
#0 lore raw

cover selftests: capabilities: convert to TAP13 ksft framework

This patch series consists of a fix to run a skipped test and converting to TAP13 ksft framework. I found this skipped test while I was testing the TAP13 changes.

Next up is converting err() and errx() to appropriate ksft_ routines as needed and appropriate. The output from non-root user run reflects the pending work.

Output after conversion when root runs the test:
------------------------------------------------

TAP version 13
# [RUN] +++ Tests with uid == 0 +++
# [NOTE] Using global UIDs for tests
# [RUN] Root => ep
# validate_cap:: Capabilities after execve were correct ok 1 Passed
# Check cap_ambient manipulation rules
ok 2 PR_CAP_AMBIENT_RAISE failed on non-inheritable cap ok 3 PR_CAP_AMBIENT_RAISE failed on non-permitted cap ok 4 PR_CAP_AMBIENT_RAISE worked
ok 5 Basic manipulation appears to work
# [RUN] Root +i => eip
# validate_cap:: Capabilities after execve were correct ok 6 Passed
# [RUN] UID 0 +ia => eipa
# validate_cap:: Capabilities after execve were correct ok 7 Passed
# [RUN] Root +ia, suidroot => eipa
# validate_cap:: Capabilities after execve were correct ok 8 Passed
# [RUN] Root +ia, suidnonroot => ip
# validate_cap:: Capabilities after execve were correct ok 9 Passed
# [RUN] Root +ia, sgidroot => eipa
# validate_cap:: Capabilities after execve were correct ok 10 Passed
# [RUN] Root, gid != 0, +ia, sgidroot => eip
# validate_cap:: Capabilities after execve were correct ok 11 Passed
# [RUN] Root +ia, sgidnonroot => eip
# validate_cap:: Capabilities after execve were correct ok 12 Passed
Pass 12 Fail 0 Xfail 0 Xpass 0 Skip 0
1..12
# ==================================================
# [RUN] +++ Tests with uid != 0 +++
# [NOTE] Using global UIDs for tests
# [RUN] Non-root => no caps
# validate_cap:: Capabilities after execve were correct ok 1 Passed
# Check cap_ambient manipulation rules
ok 2 PR_CAP_AMBIENT_RAISE failed on non-inheritable cap ok 3 PR_CAP_AMBIENT_RAISE failed on non-permitted cap ok 4 PR_CAP_AMBIENT_RAISE worked
ok 5 Basic manipulation appears to work
# [RUN] Non-root +i => i
# validate_cap:: Capabilities after execve were correct ok 6 Passed
# [RUN] UID 1 +ia => eipa
# validate_cap:: Capabilities after execve were correct ok 7 Passed
# [RUN] Non-root +ia, sgidnonroot => i
# validate_cap:: Capabilities after execve were correct ok 8 Passed
# [RUN] Non-root +ia, sgidroot => i
# validate_cap:: Capabilities after execve were correct ok 9 Passed
Pass 9 Fail 0 Xfail 0 Xpass 0 Skip 0
1..9

Output after conversion when a non-root user runs the test:
-----------------------------------------------------------

TAP version 13
# [RUN] +++ Tests with uid == 0 +++
test_execve: must be root or be able to create a userns # Child failed
# ==================================================
# [RUN] +++ Tests with uid != 0 +++
test_execve: must be root or be able to create a userns # Child failed

Shuah Khan (2):
selftests: capabilities: fix to run Non-root +ia, sgidroot => i test
selftests: capabilities: convert the test to use TAP13 ksft framework

 tools/testing/selftests/capabilities/test_execve.c | 88 +++++++++++++---------
 .../testing/selftests/capabilities/validate_cap.c  | 15 ++--
 2 files changed, 64 insertions(+), 39 deletions(-)
Signature · 1 line
2.11.0
author
#1 lore raw

PATCH 1/2 selftests: capabilities: fix to run Non-root +ia, sgidroot => i test

do_tests() runs sgidnonroot test without fork_wait(). As a result the last test "Non-root +ia, sgidroot => i test" is left out. Fix it.

---
 tools/testing/selftests/capabilities/test_execve.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
tools/testing/selftests/capabilities/test_execve.c +2 -1
index 763f37fecfb8..7f2e999839c2 100644
@@ -380,7 +380,8 @@ static int do_tests(int uid, const char *our_path)
 						true, true, true, false);
 	} else {
 		printf("[RUN]\tNon-root +ia, sgidnonroot => i\n");
-		exec_other_validate_cap("./validate_cap_sgidnonroot",
+		if (fork_wait())
+			exec_other_validate_cap("./validate_cap_sgidnonroot",
 					false, false, true, false);
 
 		if (fork_wait()) {
Signature · 1 line
2.11.0
author
#2 lore raw

PATCH 2/2 selftests: capabilities: convert the test to use TAP13 ksft framework

In reply to Shuah Khan

Convert the test to use TAP13 ksft framework for test output. Converting error paths using err() and errx() will be done in another patch to make it easier for review and change management.

---
 tools/testing/selftests/capabilities/test_execve.c | 85 +++++++++++++---------
 .../testing/selftests/capabilities/validate_cap.c  | 15 ++--
 2 files changed, 62 insertions(+), 38 deletions(-)
tools/testing/selftests/capabilities/test_execve.c +52 -33
index 7f2e999839c2..7c38233292b0 100644
@@ -18,6 +18,8 @@
 #include <sys/prctl.h>
 #include <sys/stat.h>
 
+#include "../kselftest.h"
+
 #ifndef PR_CAP_AMBIENT
 #define PR_CAP_AMBIENT			47
 # define PR_CAP_AMBIENT_IS_SET		1
@@ -27,6 +29,7 @@
 #endif
 
 static int nerrs;
+static pid_t mpid;	/*  main() pid is used to avoid duplicate test counts */
 
 static void vmaybe_write_file(bool enoent_ok, char *filename, char *fmt, va_list ap)
 {
@@ -95,7 +98,7 @@ static bool create_and_enter_ns(uid_t inner_uid)
 	 */
 
 	if (unshare(CLONE_NEWNS) == 0) {
-		printf("[NOTE]\tUsing global UIDs for tests\n");
+		ksft_print_msg("[NOTE]\tUsing global UIDs for tests\n");
 		if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0)
 			err(1, "PR_SET_KEEPCAPS");
 		if (setresuid(inner_uid, inner_uid, -1) != 0)
@@ -111,7 +114,7 @@ static bool create_and_enter_ns(uid_t inner_uid)
 
 		have_outer_privilege = true;
 	} else if (unshare(CLONE_NEWUSER | CLONE_NEWNS) == 0) {
-		printf("[NOTE]\tUsing a user namespace for tests\n");
+		ksft_print_msg("[NOTE]\tUsing a user namespace for tests\n");
 		maybe_write_file("/proc/self/setgroups", "deny");
 		write_file("/proc/self/uid_map", "%d %d 1", inner_uid, outer_uid);
 		write_file("/proc/self/gid_map", "0 %d 1", outer_gid);
@@ -174,15 +177,16 @@ static bool fork_wait(void)
 		int status;
 		if (waitpid(child, &status, 0) != child ||
 		    !WIFEXITED(status)) {
-			printf("[FAIL]\tChild died\n");
+			ksft_print_msg("Child died\n");
 			nerrs++;
 		} else if (WEXITSTATUS(status) != 0) {
-			printf("[FAIL]\tChild failed\n");
+			ksft_print_msg("Child failed\n");
 			nerrs++;
 		} else {
-			printf("[OK]\tChild succeeded\n");
+			/* don't print this message for mpid */
+			if (getpid() != mpid)
+				ksft_test_result_pass("Passed\n");
 		}
-
 		return false;
 	} else {
 		err(1, "fork");
@@ -255,26 +259,29 @@ static int do_tests(int uid, const char *our_path)
 		err(1, "capng_apply");
 
 	if (uid == 0) {
-		printf("[RUN]\tRoot => ep\n");
+		ksft_print_msg("[RUN]\tRoot => ep\n");
 		if (fork_wait())
 			exec_validate_cap(true, true, false, false);
 	} else {
-		printf("[RUN]\tNon-root => no caps\n");
+		ksft_print_msg("[RUN]\tNon-root => no caps\n");
 		if (fork_wait())
 			exec_validate_cap(false, false, false, false);
 	}
 
-	printf("[OK]\tCheck cap_ambient manipulation rules\n");
+	ksft_print_msg("Check cap_ambient manipulation rules\n");
 
 	/* We should not be able to add ambient caps yet. */
 	if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_NET_BIND_SERVICE, 0, 0, 0) != -1 || errno != EPERM) {
 		if (errno == EINVAL)
-			printf("[FAIL]\tPR_CAP_AMBIENT_RAISE isn't supported\n");
+			ksft_test_result_fail(
+				"PR_CAP_AMBIENT_RAISE isn't supported\n");
 		else
-			printf("[FAIL]\tPR_CAP_AMBIENT_RAISE should have failed eith EPERM on a non-inheritable cap\n");
+			ksft_test_result_fail(
+				"PR_CAP_AMBIENT_RAISE should have failed eith EPERM on a non-inheritable cap\n");
 		return 1;
 	}
-	printf("[OK]\tPR_CAP_AMBIENT_RAISE failed on non-inheritable cap\n");
+	ksft_test_result_pass(
+		"PR_CAP_AMBIENT_RAISE failed on non-inheritable cap\n");
 
 	capng_update(CAPNG_ADD, CAPNG_INHERITABLE, CAP_NET_RAW);
 	capng_update(CAPNG_DROP, CAPNG_PERMITTED, CAP_NET_RAW);
@@ -282,22 +289,25 @@ static int do_tests(int uid, const char *our_path)
 	if (capng_apply(CAPNG_SELECT_CAPS) != 0)
 		err(1, "capng_apply");
 	if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_NET_RAW, 0, 0, 0) != -1 || errno != EPERM) {
-		printf("[FAIL]\tPR_CAP_AMBIENT_RAISE should have failed on a non-permitted cap\n");
+		ksft_test_result_fail(
+			"PR_CAP_AMBIENT_RAISE should have failed on a non-permitted cap\n");
 		return 1;
 	}
-	printf("[OK]\tPR_CAP_AMBIENT_RAISE failed on non-permitted cap\n");
+	ksft_test_result_pass(
+		"PR_CAP_AMBIENT_RAISE failed on non-permitted cap\n");
 
 	capng_update(CAPNG_ADD, CAPNG_INHERITABLE, CAP_NET_BIND_SERVICE);
 	if (capng_apply(CAPNG_SELECT_CAPS) != 0)
 		err(1, "capng_apply");
 	if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_NET_BIND_SERVICE, 0, 0, 0) != 0) {
-		printf("[FAIL]\tPR_CAP_AMBIENT_RAISE should have succeeded\n");
+		ksft_test_result_fail(
+			"PR_CAP_AMBIENT_RAISE should have succeeded\n");
 		return 1;
 	}
-	printf("[OK]\tPR_CAP_AMBIENT_RAISE worked\n");
+	ksft_test_result_pass("PR_CAP_AMBIENT_RAISE worked\n");
 
 	if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_BIND_SERVICE, 0, 0, 0) != 1) {
-		printf("[FAIL]\tPR_CAP_AMBIENT_IS_SET is broken\n");
+		ksft_test_result_fail("PR_CAP_AMBIENT_IS_SET is broken\n");
 		return 1;
 	}
 
@@ -305,7 +315,8 @@ static int do_tests(int uid, const char *our_path)
 		err(1, "PR_CAP_AMBIENT_CLEAR_ALL");
 
 	if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_BIND_SERVICE, 0, 0, 0) != 0) {
-		printf("[FAIL]\tPR_CAP_AMBIENT_CLEAR_ALL didn't work\n");
+		ksft_test_result_fail(
+			"PR_CAP_AMBIENT_CLEAR_ALL didn't work\n");
 		return 1;
 	}
 
@@ -317,21 +328,21 @@ static int do_tests(int uid, const char *our_path)
 		err(1, "capng_apply");
 
 	if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_BIND_SERVICE, 0, 0, 0) != 0) {
-		printf("[FAIL]\tDropping I should have dropped A\n");
+		ksft_test_result_fail("Dropping I should have dropped A\n");
 		return 1;
 	}
 
-	printf("[OK]\tBasic manipulation appears to work\n");
+	ksft_test_result_pass("Basic manipulation appears to work\n");
 
 	capng_update(CAPNG_ADD, CAPNG_INHERITABLE, CAP_NET_BIND_SERVICE);
 	if (capng_apply(CAPNG_SELECT_CAPS) != 0)
 		err(1, "capng_apply");
 	if (uid == 0) {
-		printf("[RUN]\tRoot +i => eip\n");
+		ksft_print_msg("[RUN]\tRoot +i => eip\n");
 		if (fork_wait())
 			exec_validate_cap(true, true, true, false);
 	} else {
-		printf("[RUN]\tNon-root +i => i\n");
+		ksft_print_msg("[RUN]\tNon-root +i => i\n");
 		if (fork_wait())
 			exec_validate_cap(false, false, true, false);
 	}
@@ -339,53 +350,54 @@ static int do_tests(int uid, const char *our_path)
 	if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_NET_BIND_SERVICE, 0, 0, 0) != 0)
 		err(1, "PR_CAP_AMBIENT_RAISE");
 
-	printf("[RUN]\tUID %d +ia => eipa\n", uid);
+	ksft_print_msg("[RUN]\tUID %d +ia => eipa\n", uid);
 	if (fork_wait())
 		exec_validate_cap(true, true, true, true);
 
 	/* The remaining tests need real privilege */
 
 	if (!have_outer_privilege) {
-		printf("[SKIP]\tSUID/SGID tests (needs privilege)\n");
+		ksft_test_result_skip("SUID/SGID tests (needs privilege)\n");
 		goto done;
 	}
 
 	if (uid == 0) {
-		printf("[RUN]\tRoot +ia, suidroot => eipa\n");
+		ksft_print_msg("[RUN]\tRoot +ia, suidroot => eipa\n");
 		if (fork_wait())
 			exec_other_validate_cap("./validate_cap_suidroot",
 						true, true, true, true);
 
-		printf("[RUN]\tRoot +ia, suidnonroot => ip\n");
+		ksft_print_msg("[RUN]\tRoot +ia, suidnonroot => ip\n");
 		if (fork_wait())
 			exec_other_validate_cap("./validate_cap_suidnonroot",
 						false, true, true, false);
 
-		printf("[RUN]\tRoot +ia, sgidroot => eipa\n");
+		ksft_print_msg("[RUN]\tRoot +ia, sgidroot => eipa\n");
 		if (fork_wait())
 			exec_other_validate_cap("./validate_cap_sgidroot",
 						true, true, true, true);
 
 		if (fork_wait()) {
-			printf("[RUN]\tRoot, gid != 0, +ia, sgidroot => eip\n");
+			ksft_print_msg(
+				"[RUN]\tRoot, gid != 0, +ia, sgidroot => eip\n");
 			if (setresgid(1, 1, 1) != 0)
 				err(1, "setresgid");
 			exec_other_validate_cap("./validate_cap_sgidroot",
 						true, true, true, false);
 		}
 
-		printf("[RUN]\tRoot +ia, sgidnonroot => eip\n");
+		ksft_print_msg("[RUN]\tRoot +ia, sgidnonroot => eip\n");
 		if (fork_wait())
 			exec_other_validate_cap("./validate_cap_sgidnonroot",
 						true, true, true, false);
 	} else {
-		printf("[RUN]\tNon-root +ia, sgidnonroot => i\n");
+		ksft_print_msg("[RUN]\tNon-root +ia, sgidnonroot => i\n");
 		if (fork_wait())
 			exec_other_validate_cap("./validate_cap_sgidnonroot",
 					false, false, true, false);
 
 		if (fork_wait()) {
-			printf("[RUN]\tNon-root +ia, sgidroot => i\n");
+			ksft_print_msg("[RUN]\tNon-root +ia, sgidroot => i\n");
 			if (setresgid(1, 1, 1) != 0)
 				err(1, "setresgid");
 			exec_other_validate_cap("./validate_cap_sgidroot",
@@ -394,6 +406,7 @@ static int do_tests(int uid, const char *our_path)
 	}
 
 done:
+	ksft_print_cnts();
 	return nerrs ? 1 : 0;
 }
 
@@ -401,6 +414,8 @@ int main(int argc, char **argv)
 {
 	char *tmp1, *tmp2, *our_path;
 
+	ksft_print_header();
+
 	/* Find our path */
 	tmp1 = strdup(argv[0]);
 	if (!tmp1)
@@ -411,13 +426,17 @@ int main(int argc, char **argv)
 		err(1, "strdup");
 	free(tmp1);
 
+	mpid = getpid();
+
 	if (fork_wait()) {
-		printf("[RUN]\t+++ Tests with uid == 0 +++\n");
+		ksft_print_msg("[RUN]\t+++ Tests with uid == 0 +++\n");
 		return do_tests(0, our_path);
 	}
 
+	ksft_print_msg("==================================================\n");
+
 	if (fork_wait()) {
-		printf("[RUN]\t+++ Tests with uid != 0 +++\n");
+		ksft_print_msg("[RUN]\t+++ Tests with uid != 0 +++\n");
 		return do_tests(1, our_path);
 	}
 
tools/testing/selftests/capabilities/validate_cap.c +10 -5
index dd3c45f7b23c..9fd4345a8987 100644
@@ -7,6 +7,8 @@
 #include <sys/prctl.h>
 #include <sys/auxv.h>
 
+#include "../kselftest.h"
+
 #ifndef PR_CAP_AMBIENT
 #define PR_CAP_AMBIENT			47
 # define PR_CAP_AMBIENT_IS_SET		1
@@ -51,23 +53,26 @@ int main(int argc, char **argv)
 	capng_get_caps_process();
 
 	if (capng_have_capability(CAPNG_EFFECTIVE, CAP_NET_BIND_SERVICE) != bool_arg(argv, 1)) {
-		printf("[FAIL]\tWrong effective state%s\n", atsec);
+		ksft_print_msg("Wrong effective state%s\n", atsec);
 		return 1;
 	}
+
 	if (capng_have_capability(CAPNG_PERMITTED, CAP_NET_BIND_SERVICE) != bool_arg(argv, 2)) {
-		printf("[FAIL]\tWrong permitted state%s\n", atsec);
+		ksft_print_msg("Wrong permitted state%s\n", atsec);
 		return 1;
 	}
+
 	if (capng_have_capability(CAPNG_INHERITABLE, CAP_NET_BIND_SERVICE) != bool_arg(argv, 3)) {
-		printf("[FAIL]\tWrong inheritable state%s\n", atsec);
+		ksft_print_msg("Wrong inheritable state%s\n", atsec);
 		return 1;
 	}
 
 	if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_BIND_SERVICE, 0, 0, 0) != bool_arg(argv, 4)) {
-		printf("[FAIL]\tWrong ambient state%s\n", atsec);
+		ksft_print_msg("Wrong ambient state%s\n", atsec);
 		return 1;
 	}
 
-	printf("[OK]\tCapabilities after execve were correct\n");
+	ksft_print_msg("%s: Capabilities after execve were correct\n",
+			"validate_cap:");
 	return 0;
 }
Signature · 1 line
2.11.0