All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH v1 0/4] cleanup capset testcase
@ 2019-12-17 10:12 Yang Xu
  2019-12-17 10:12 ` [LTP] [PATCH v1 1/4] syscalls/capset01: Cleanup & convert to new library Yang Xu
                   ` (3 more replies)
  0 siblings, 4 replies; 22+ messages in thread
From: Yang Xu @ 2019-12-17 10:12 UTC (permalink / raw)
  To: ltp

I cleanup capset testcase as below:

capset01: test on three versions
capset02: add various EPERM error cases
capset03: add EPERM error test without CAP_SETPCAP
capset04: add new EPERM error test with vfs cap support

I have tested them with root/nobody user and debug EPERM error in kernel code
(security/commoncap.c cap_capset function ).  They are ok.

Yang Xu (4):
  syscalls/capset01: Cleanup & convert to new library
  syscalls/capset02: Cleanup & convert to new library
  syscalls/capset03: add new EPERM error test without CAP_SETPCAP
  syscalls/capset04: add new EPERM error test with vfs cap support

 runtest/syscalls                            |   2 +
 testcases/kernel/syscalls/capset/.gitignore |   2 +
 testcases/kernel/syscalls/capset/capset01.c | 150 ++------
 testcases/kernel/syscalls/capset/capset02.c | 364 ++++++++------------
 testcases/kernel/syscalls/capset/capset03.c |  65 ++++
 testcases/kernel/syscalls/capset/capset04.c |  86 +++++
 6 files changed, 319 insertions(+), 350 deletions(-)
 create mode 100644 testcases/kernel/syscalls/capset/capset03.c
 create mode 100644 testcases/kernel/syscalls/capset/capset04.c

-- 
2.18.0




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

* [LTP] [PATCH v1 1/4] syscalls/capset01: Cleanup & convert to new library
  2019-12-17 10:12 [LTP] [PATCH v1 0/4] cleanup capset testcase Yang Xu
@ 2019-12-17 10:12 ` Yang Xu
  2020-01-07 13:32   ` Cyril Hrubis
  2019-12-17 10:12 ` [LTP] [PATCH v1 2/4] syscalls/capset02: " Yang Xu
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 22+ messages in thread
From: Yang Xu @ 2019-12-17 10:12 UTC (permalink / raw)
  To: ltp

Test capset() syscall on three versions.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 testcases/kernel/syscalls/capset/capset01.c | 150 ++++----------------
 1 file changed, 29 insertions(+), 121 deletions(-)

diff --git a/testcases/kernel/syscalls/capset/capset01.c b/testcases/kernel/syscalls/capset/capset01.c
index 9c61773bb..75cdd83b9 100644
--- a/testcases/kernel/syscalls/capset/capset01.c
+++ b/testcases/kernel/syscalls/capset/capset01.c
@@ -1,142 +1,50 @@
 /*
  * Copyright (c) Wipro Technologies Ltd, 2002.  All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-/**********************************************************
- *
- *    TEST IDENTIFIER	: capset01
- *
- *    EXECUTED BY	: anyone
- *
- *    TEST TITLE	: Basic test for capset(2)
- *
- *    TEST CASE TOTAL	: 1
- *
  *    AUTHOR		: Saji Kumar.V.R <saji.kumar@wipro.com>
  *
- *    SIGNALS
- * 	Uses SIGUSR1 to pause before test if option set.
- * 	(See the parse_opts(3) man page).
- *
- *    DESCRIPTION
- *	This is a Phase I test for the capset(2) system call.
- *	It is intended to provide a limited exposure of the system call.
- *
- * 	Setup:
- * 	  Setup signal handling.
- *	  Pause for SIGUSR1 if option specified.
- *	  call capget() to save the current capability data
- *
- * 	Test:
- *	 Loop if the proper options are given.
- * 	  call capset() with the saved data
- *	  if return value == 0
- *		Test passed
- *	  Otherwise
- *		Test failed
- *
- * 	Cleanup:
- * 	  Print errno log and/or timing stats if options given
- *
- * USAGE:  <for command-line>
- * capset01 [-c n] [-e] [-i n] [-I x] [-P x] [-t] [-h] [-f] [-p]
- *			where,  -c n : Run n copies concurrently.
- *				-e   : Turn on errno logging.
- *				-h   : Show help screen
- *				-f   : Turn off functional testing
- *				-i n : Execute test n times.
- *				-I x : Execute test for x seconds.
- *				-p   : Pause for SIGUSR1 before starting
- *				-P x : Pause for x seconds between iterations.
- *				-t   : Turn on syscall timing.
- *
  * CHANGES:
  *  2005/01/01: add an hint to a possible solution when test fails
  *              - Ricky Ng-Adam <rngadam@yahoo.com>
  ****************************************************************/
+#include <sys/types.h>
 #include <unistd.h>
-#include <errno.h>
-#include "test.h"
+#include "tst_test.h"
 #include "lapi/syscalls.h"
-
-/**************************************************************************/
-/*                                                                        */
-/*   Some archs do not have the manpage documented sys/capability.h file, */
-/*   and require the use of the line below                                */
-
 #include <linux/capability.h>
 
-/*   If you are having issues with including this file and have the sys/  */
-/*   version, then you may want to try switching to it. -Robbie W.        */
-/**************************************************************************/
+static struct tcase {
+	int version;
+	char *message;
+} tcases[] = {
+	{0x19980330, "Test on LINUX_CAPABILITY_VERSION_1"},
+	{0x20071026, "Test on LINUX_CAPABILITY_VERSION_2"},
+	{0x20080522, "Test on LINUX_CAPABILITY_VERSION_3"},
+};
 
-static void setup();
-static void cleanup();
 
-char *TCID = "capset01";
-int TST_TOTAL = 1;
-
-static struct __user_cap_header_struct header;	/* cap_user_header_t is a pointer
-						   to __user_cap_header_struct */
-
-static struct __user_cap_data_struct data;	/* cap_user_data_t is a pointer to
-						   __user_cap_data_struct */
-
-int main(int ac, char **av)
+static void verify_capset(unsigned int n)
 {
+	struct tcase *tc = &tcases[n];
+	struct __user_cap_header_struct header;
+	struct __user_cap_data_struct data[2];
 
-	int lc;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();
+	tst_res(TINFO, "%s", tc->message);
+	header.version = tc->version;
+	header.pid = getpid();
 
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-
-		tst_count = 0;
-
-		TEST(ltp_syscall(__NR_capset, &header, &data));
-
-		if (TEST_RETURN == 0) {
-			tst_resm(TPASS, "capset() returned %ld", TEST_RETURN);
-		} else {
-			tst_resm(TFAIL | TTERRNO,
-				 "Test Failed, capset() returned %ld"
-				 " Maybe you need to do `modprobe capability`?",
-				 TEST_RETURN);
-		}
+	if (tst_syscall(__NR_capget, &header, data) == -1) {
+		tst_res(TFAIL | TTERRNO, "capget() failed");
+		return;
 	}
 
-	cleanup();
-
-	tst_exit();
+	TEST(tst_syscall(__NR_capset, &header, data));
+	if (TST_RET == 0)
+		tst_res(TPASS, "capset() returned %ld", TST_RET);
+	else
+		tst_res(TFAIL | TTERRNO, "Test Failed, capset() returned %ld", TST_RET);
 }
 
-void setup(void)
-{
-
-	tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
-
-	header.version = _LINUX_CAPABILITY_VERSION;
-	header.pid = 0;
-	if (ltp_syscall(__NR_capget, &header, &data) == -1)
-		tst_brkm(TBROK | TERRNO, NULL, "capget() failed");
-}
-
-void cleanup(void)
-{
-}
+static struct tst_test test = {
+	.tcnt = ARRAY_SIZE(tcases),
+	.test = verify_capset,
+};
-- 
2.18.0




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

* [LTP] [PATCH v1 2/4] syscalls/capset02: Cleanup & convert to new library
  2019-12-17 10:12 [LTP] [PATCH v1 0/4] cleanup capset testcase Yang Xu
  2019-12-17 10:12 ` [LTP] [PATCH v1 1/4] syscalls/capset01: Cleanup & convert to new library Yang Xu
@ 2019-12-17 10:12 ` Yang Xu
  2019-12-17 10:12 ` [LTP] [PATCH v1 3/4] syscalls/capset03: add new EPERM error test without CAP_SETPCAP Yang Xu
  2019-12-17 10:12 ` [LTP] [PATCH v3 4/5] syscalls/quotactl05: add project quota test for xfs filesystem Yang Xu
  3 siblings, 0 replies; 22+ messages in thread
From: Yang Xu @ 2019-12-17 10:12 UTC (permalink / raw)
  To: ltp

It adds a preferred linux capabilities version check like
capget02. Also, it adds various cases about EPERM error.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 testcases/kernel/syscalls/capset/capset02.c | 364 ++++++++------------
 1 file changed, 135 insertions(+), 229 deletions(-)

diff --git a/testcases/kernel/syscalls/capset/capset02.c b/testcases/kernel/syscalls/capset/capset02.c
index aece29511..4df555ce4 100644
--- a/testcases/kernel/syscalls/capset/capset02.c
+++ b/testcases/kernel/syscalls/capset/capset02.c
@@ -1,261 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (c) Wipro Technologies Ltd, 2002.  All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+ * Author: Saji Kumar.V.R <saji.kumar@wipro.com>
+ *
+ * Tests basic error handling of the capset syscall.
+ * 1) capset() fails with errno set to EFAULT if an invalid address
+ * is given for header.
+ * 2) capset() fails with errno set to EFAULT if an invalid address
+ * is given for data.
+ * 3) capset() fails with errno set ot EINVAL if an unused pid is
+ * given for header->pid.
+ * 4) capset() fails with errno set to EINVAL if an invalid value
+ * is given for header->version.
+ * 5) capset() fails with errno set to EPERM if the new_Effective is
+ * not a subset of the new_Permitted.
+ * 6) capset() fails with errno set to EPERM if the new_Permitted is
+ * not a subset of the old_Permitted.
+ * 7) capset() fails with errno set ot EPERM if the new_Inheritable is
+ * not a subset of  the old_Inheritable and bounding set.
  */
-/**********************************************************
- *
- *    TEST IDENTIFIER	: capset02
- *
- *    EXECUTED BY	: anyone
- *
- *    TEST TITLE	: Tests for error conditions.
- *
- *    TEST CASE TOTAL	: 4
- *
- *    AUTHOR		: Saji Kumar.V.R <saji.kumar@wipro.com>
- *
- *    SIGNALS
- * 	Uses SIGUSR1 to pause before test if option set.
- * 	(See the parse_opts(3) man page).
- *
- *    DESCRIPTION
- *	Verify that
- *	1) capset() fails with errno set to EFAULT if an invalid address
- *	   is given for header
- *	2) capset() fails with errno set to EFAULT if an invalid address
- *	   is given for data
- *	3) capset() fails with errno set to EINVAL if an invalid value
- *	   is given for header->version
- *	4) capset() fails with errno set to EPERM the process does not
- *	   have enough privilege to set capabilities
- *
- *
- * 	Setup:
- * 	  Setup signal handling.
- *	  Pause for SIGUSR1 if option specified.
- *	  Call capget() to save current capability data
- *
- * 	Test:
- *	 Loop if the proper options are given.
- *	  do test specific setup.
- * 	  call capset with proper arguments
- *	  if capset() fails with expected errno
- *		Test passed
- *	  Otherwise
- *		Test failed
- *	  do test specific cleanup
- *
- * 	Cleanup:
- * 	  Print errno log and/or timing stats if options given
- *
- * USAGE:  <for command-line>
- * capset02 [-c n] [-e] [-i n] [-I x] [-P x] [-t] [-h] [-f] [-p]
- *			where,  -c n : Run n copies concurrently.
- *				-e   : Turn on errno logging.
- *				-h   : Show help screen
- *				-f   : Turn off functional testing
- *				-i n : Execute test n times.
- *				-I x : Execute test for x seconds.
- *				-p   : Pause for SIGUSR1 before starting
- *				-P x : Pause for x seconds between iterations.
- *				-t   : Turn on syscall timing.
- *
- ****************************************************************/
+#include <stdlib.h>
 #include <sys/types.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <pwd.h>
-#include <signal.h>
-#include <string.h>
 #include <unistd.h>
-#include "test.h"
-#include "safe_macros.h"
+#include <sys/prctl.h>
+#include "tst_test.h"
 #include "lapi/syscalls.h"
-
-/**************************************************************************/
-/*                                                                        */
-/*   Some archs do not have the manpage documented sys/capability.h file, */
-/*   and require the use of the line below                                */
-
 #include <linux/capability.h>
 
-/*   If you are having issues with including this file and have the sys/  */
-/*   version, then you may want to try switching to it. -Robbie W.        */
-/**************************************************************************/
+#define CAP1 (1 << CAP_NET_RAW | 1 << CAP_CHOWN  | 1 << CAP_SETPCAP)
+#define CAP2 (CAP1 | 1 << CAP_KILL)
 
-#define INVALID_VERSION 0
-
-static void setup(void);
-static void cleanup(void);
-static void test_setup(int, char *);
-static void child_func(void);
+static unsigned int check_root_flag, drop_flag;
+static struct __user_cap_header_struct header, bad_version_header, unused_pid_header;
+static struct __user_cap_data_struct data[2];
+static struct __user_cap_data_struct good_data[2] = {
+	{
+		.effective = CAP1,
+		.permitted = CAP1,
+		.inheritable = CAP1,
+	},
+};
 
-static pid_t child_pid = -1;
+static struct __user_cap_data_struct bad_data_pe[2] = {
+	{
+		.effective = CAP2,
+		.permitted = CAP1,
+		.inheritable = CAP1,
+	},
+};
 
-char *TCID = "capset02";
+static struct __user_cap_data_struct bad_data_pp[2] = {
+	{
+		.effective = CAP1,
+		.permitted = CAP2,
+		.inheritable = CAP1,
+	},
+};
 
-static struct __user_cap_header_struct header;
-static struct __user_cap_data_struct data;
+static struct __user_cap_data_struct bad_data_pi[2] = {
+	{
+		.effective = CAP1,
+		.permitted = CAP1,
+		.inheritable = CAP2,
+	},
+};
 
-struct test_case_t {
+static struct tcase {
 	cap_user_header_t headerp;
 	cap_user_data_t datap;
-	int exp_errno;
-	char *errdesc;
-} test_cases[] = {
-#ifndef UCLINUX
-	/* Skip since uClinux does not implement memory protection */
-	{
-	(cap_user_header_t) - 1, &data, EFAULT, "EFAULT"}, {
-	&header, (cap_user_data_t) - 1, EFAULT, "EFAULT"},
-#endif
-	{
-	&header, &data, EINVAL, "EINVAL"}, {
-&header, &data, EPERM, "EPERM"},};
-
-int TST_TOTAL = sizeof(test_cases) / sizeof(test_cases[0]);
-
-int main(int ac, char **av)
+	int exp_err;
+	/*
+	 * 1 needs reset header version
+	 * 2 needs root privilege
+	 * 3 needs drop cap in bouding set
+	 */
+	int flag;
+	char *message;
+} tcases[] = {
+	{NULL, data, EFAULT, 0, "Test bad address header"},
+	{&header, NULL, EFAULT, 0, "Test bad address data"},
+	{&unused_pid_header, data, EINVAL, 1, "Test bad pid"},
+	{&bad_version_header, data, EINVAL, 1, "Test bad version"},
+	{&header, bad_data_pe, EPERM, 0, "Test bad value data(when pE is not in pP)"},
+	{&header, bad_data_pp, EPERM, 2, "Test bad value data(when pP is not in old pP)"},
+	{&header, bad_data_pi, EPERM, 3, "Test bad value data(when pI is not in bounding set or old pI)"},
+};
+
+static void verify_capset(unsigned int n)
 {
+	struct tcase *tc = &tcases[n];
 
-	int lc, i;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-#ifdef UCLINUX
-	maybe_run_child(&child_func, "");
-#endif
-
-	setup();
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-
-		tst_count = 0;
-
-#ifdef UCLINUX
-		i = 2;
-#else
-		i = 0;
-#endif
-
-		for (; i < TST_TOTAL; i++) {
-
-			test_setup(i, av[0]);
-			TEST(ltp_syscall(__NR_capset, test_cases[i].headerp,
-				     test_cases[i].datap));
-
-			if (TEST_RETURN == -1 &&
-			    TEST_ERRNO == test_cases[i].exp_errno) {
-				tst_resm(TPASS, "capset() returned -1,"
-					 " errno: %s", test_cases[i].errdesc);
-			} else {
-				tst_resm(TFAIL | TTERRNO,
-					 "Test Failed, capset() returned %ld",
-					 TEST_RETURN);
-			}
-		}
+	tst_res(TINFO, "%s", tc->message);
+	if (tc->flag == 2 && !check_root_flag) {
+		tst_res(TCONF, "This test needs root privilege, skip it");
+		return;
+	}
+	if (tc->flag == 3 && !drop_flag) {
+		tst_res(TCONF, "This test needs to drop CAP_KILL in bounding set, skip it");
+		return;
 	}
 
-	cleanup();
-
-	tst_exit();
-
-}
-
-void setup(void)
-{
-	tst_require_root();
-
-	TEST_PAUSE;
-
+	TEST(tst_syscall(__NR_capset, tc->headerp, tc->datap));
+	if (TST_RET == 0) {
+		tst_res(TFAIL, "capset() succeed unexpectedly");
+		return;
+	}
+	if (TST_ERR == tc->exp_err)
+		tst_res(TPASS | TTERRNO, "capset() failed as expected");
+	else
+		tst_res(TFAIL | TTERRNO, "capset() expected %s got ",
+			tst_strerrno(tc->exp_err));
 	/*
-	 * Save current capability data.
-	 * header.version must be _LINUX_CAPABILITY_VERSION
+	 * When an unsupported version value is specified, it will
+	 * return the kernel preferred value of _LINUX_CAPABILITY_VERSION_?.
+	 * Since linux 2.6.26, version 3 is default. We use it.
 	 */
-	header.version = _LINUX_CAPABILITY_VERSION;
-	if (ltp_syscall(__NR_capget, &header, &data) == -1)
-		tst_brkm(TBROK | TERRNO, NULL, "capget failed");
-}
-
-void cleanup(void)
-{
-	if (0 < child_pid) {
-		kill(child_pid, SIGTERM);
-		wait(NULL);
+	if (tc->flag == 1) {
+		if (tc->headerp->version == 0x20080522)
+			tc->headerp->version = 0;
+		else
+			tst_res(TFAIL, "kernel doesn't return preferred linux"
+				" capability version when using bad version");
 	}
 }
 
-void child_func(void)
+static void setup(void)
 {
-	for (;;) {
-		sleep(10);
-	}
-}
-
-void test_setup(int i, char *argv0)
-{
-	char nobody_uid[] = "nobody";
-	struct passwd *ltpuser;
+	unsigned int i;
+	pid_t pid;
 
-	switch (i) {
-	case 0:
-		break;
+	pid = getpid();
 
-	case 1:
-		header.version = _LINUX_CAPABILITY_VERSION;
-		header.pid = 0;
-		break;
+	header.version = 0x20080522;
+	header.pid = pid;
+	bad_version_header.version = 0;
+	bad_version_header.pid = pid;
+	unused_pid_header.pid = 0x20080522;
+	unused_pid_header.pid = tst_get_unused_pid();
 
-	case 2:
-		header.version = INVALID_VERSION;
-		header.pid = 0;
-		break;
 
-	case 3:
-		header.version = _LINUX_CAPABILITY_VERSION;
-		/*
-		 * when a non-zero pid is specified, process should have
-		 * CAP_SETPCAP capability to change capabilities.
-		 * by default, CAP_SETPCAP is not enabled. So giving
-		 * a non-zero pid results in capset() failing with
-		 * errno EPERM
-		 *
-		 * Note: this seems to have changed with recent kernels
-		 * => create a child and try to set its capabilities
-		 */
-		child_pid = FORK_OR_VFORK();
-		if (child_pid == -1)
-			tst_brkm(TBROK | TERRNO, cleanup, "fork failed");
-		else if (child_pid == 0) {
-#ifdef UCLINUX
-			if (self_exec(argv0, "") < 0) {
-				perror("self_exec failed");
-				exit(1);
-			}
-#else
-			child_func();
-#endif
-		} else {
-			header.pid = child_pid;
-			ltpuser = getpwnam(nobody_uid);
-			if (ltpuser == NULL)
-				tst_brkm(TBROK | TERRNO, cleanup,
-					 "getpwnam failed");
-			SAFE_SETEUID(cleanup, ltpuser->pw_uid);
-
-		}
-		break;
+	for (i = 0; i < ARRAY_SIZE(tcases); i++) {
+		if (!tcases[i].headerp)
+			tcases[i].headerp = tst_get_bad_addr(NULL);
+		if (!tcases[i].datap)
+			tcases[i].datap = tst_get_bad_addr(NULL);
+	}
 
+	if (geteuid() == 0) {
+		TEST(tst_syscall(__NR_capset, &header, good_data));
+		if (TST_RET == -1)
+			tst_res(TFAIL | TTERRNO, "capset good_data failed");
+		else
+			check_root_flag = 1;
+		TEST(prctl(PR_CAPBSET_DROP, CAP_KILL));
+		if (TST_RET == -1)
+			tst_res(TFAIL | TTERRNO, "drop CAP_KILL failed");
+		else
+			drop_flag = 1;
 	}
 }
+
+static struct tst_test test = {
+	.setup = setup,
+	.tcnt = ARRAY_SIZE(tcases),
+	.test = verify_capset,
+};
-- 
2.18.0




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

* [LTP] [PATCH v1 3/4] syscalls/capset03: add new EPERM error test without CAP_SETPCAP
  2019-12-17 10:12 [LTP] [PATCH v1 0/4] cleanup capset testcase Yang Xu
  2019-12-17 10:12 ` [LTP] [PATCH v1 1/4] syscalls/capset01: Cleanup & convert to new library Yang Xu
  2019-12-17 10:12 ` [LTP] [PATCH v1 2/4] syscalls/capset02: " Yang Xu
@ 2019-12-17 10:12 ` Yang Xu
  2020-01-07 13:39   ` Cyril Hrubis
  2019-12-17 10:12 ` [LTP] [PATCH v3 4/5] syscalls/quotactl05: add project quota test for xfs filesystem Yang Xu
  3 siblings, 1 reply; 22+ messages in thread
From: Yang Xu @ 2019-12-17 10:12 UTC (permalink / raw)
  To: ltp

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 runtest/syscalls                            |  1 +
 testcases/kernel/syscalls/capset/.gitignore |  1 +
 testcases/kernel/syscalls/capset/capset03.c | 65 +++++++++++++++++++++
 3 files changed, 67 insertions(+)
 create mode 100644 testcases/kernel/syscalls/capset/capset03.c

diff --git a/runtest/syscalls b/runtest/syscalls
index fa87ef63f..4f481be6d 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -44,6 +44,7 @@ capget02 capget02
 
 capset01 capset01
 capset02 capset02
+capset03 capset03
 
 cacheflush01 cacheflush01
 
diff --git a/testcases/kernel/syscalls/capset/.gitignore b/testcases/kernel/syscalls/capset/.gitignore
index 004ce7b3e..3f9a4d5e8 100644
--- a/testcases/kernel/syscalls/capset/.gitignore
+++ b/testcases/kernel/syscalls/capset/.gitignore
@@ -1,2 +1,3 @@
 /capset01
 /capset02
+/capset03
diff --git a/testcases/kernel/syscalls/capset/capset03.c b/testcases/kernel/syscalls/capset/capset03.c
new file mode 100644
index 000000000..d973095a4
--- /dev/null
+++ b/testcases/kernel/syscalls/capset/capset03.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2019 FUJITSU LIMITED. All rights reserved.
+ * Author: Yang Xu <xuyang2018.jy@cn.fujitsu.com
+ *
+ * capset() fails with errno set or EPERM if the new_Inheritable is
+ * not a subset of old_Inheritable and old_Permitted without CAP_SETPCAP.
+ */
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/prctl.h>
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+#include <linux/capability.h>
+
+static struct __user_cap_header_struct header = {
+	.version = 0x20080522,
+	.pid = 0,
+};
+
+static struct __user_cap_data_struct data[2] = {
+	{
+		.effective = 1 << CAP_KILL,
+		.permitted = 1 << CAP_KILL,
+		.inheritable = 1 << CAP_KILL,
+	},
+};
+
+static void verify_capset(void)
+{
+	tst_res(TINFO, "Test bad value data(when pI is not old pP or old pI without CAP_SETPCAP)");
+	data[0].inheritable = (1 << CAP_KILL | 1 << CAP_NET_RAW);
+	TEST(tst_syscall(__NR_capset, &header, data));
+	if (TST_RET == 0) {
+		tst_res(TFAIL, "capset succeed unexpectedly");
+		return;
+	}
+	if (TST_ERR == EPERM)
+		tst_res(TPASS | TTERRNO, "capset() failed as expected");
+	else
+		tst_res(TFAIL | TTERRNO, "capset expected EPERM, bug got");
+}
+
+static void setup(void)
+{
+	pid_t pid;
+
+	pid = getpid();
+	header.pid = pid;
+	if (geteuid() == 0) {
+		TEST(tst_syscall(__NR_capset, &header, data));
+		if (TST_RET == -1)
+			tst_brk(TBROK | TTERRNO, "capset data failed");
+	}
+}
+
+static struct tst_test test = {
+	.setup = setup,
+	.test_all = verify_capset,
+	.caps = (struct tst_cap []) {
+		TST_CAP(TST_CAP_DROP, CAP_SETPCAP),
+		{}
+	},
+};
-- 
2.18.0




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

* [LTP] [PATCH v3 4/5] syscalls/quotactl05: add project quota test for xfs filesystem
  2019-12-17 10:12 [LTP] [PATCH v1 0/4] cleanup capset testcase Yang Xu
                   ` (2 preceding siblings ...)
  2019-12-17 10:12 ` [LTP] [PATCH v1 3/4] syscalls/capset03: add new EPERM error test without CAP_SETPCAP Yang Xu
@ 2019-12-17 10:12 ` Yang Xu
  2019-12-17 10:16   ` Yang Xu
  3 siblings, 1 reply; 22+ messages in thread
From: Yang Xu @ 2019-12-17 10:12 UTC (permalink / raw)
  To: ltp

This is a variant about quotactl02. It is used to test project quota.
I split it into a new case instead of adding it in quotaclt02 because
kernel doesn't permit mount both group and project quota before
commit d892d5864f02 ("xfs: Start using pquotaino from the superblock.").

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 runtest/syscalls                              |  1 +
 testcases/kernel/syscalls/quotactl/.gitignore |  2 +
 .../kernel/syscalls/quotactl/quotactl05.c     | 99 +++++++++++++++++++
 3 files changed, 102 insertions(+)
 create mode 100644 testcases/kernel/syscalls/quotactl/quotactl05.c

diff --git a/runtest/syscalls b/runtest/syscalls
index c30e9e620..f2c7b0daf 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -954,6 +954,7 @@ quotactl01 quotactl01
 quotactl02 quotactl02
 quotactl03 quotactl03
 quotactl04 quotactl04
+quotactl05 quotactl05
 
 read01 read01
 read02 read02
diff --git a/testcases/kernel/syscalls/quotactl/.gitignore b/testcases/kernel/syscalls/quotactl/.gitignore
index 1db7c5d98..9621e7717 100644
--- a/testcases/kernel/syscalls/quotactl/.gitignore
+++ b/testcases/kernel/syscalls/quotactl/.gitignore
@@ -2,3 +2,5 @@
 /quotactl02
 /quotactl03
 /quotactl04
+/quotactl05
+
diff --git a/testcases/kernel/syscalls/quotactl/quotactl05.c b/testcases/kernel/syscalls/quotactl/quotactl05.c
new file mode 100644
index 000000000..2c4f49f7c
--- /dev/null
+++ b/testcases/kernel/syscalls/quotactl/quotactl05.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2019 FUJITSU LIMITED. All rights reserved.
+ * Author: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
+ *
+ * Test Name: quotactl05
+ *
+ * Description:
+ * This testcase checks basic flags of quotactl(2) for project on an XFS file
+ * system:
+ * 1) quotactl(2) succeeds to turn off xfs quota and get xfs quota off status
+ *    for project.
+ * 2) quotactl(2) succeeds to turn on xfs quota and get xfs quota on status
+ *    for project.
+ * 3) quotactl(2) succeeds to set and use Q_XGETQUOTA to get xfs disk quota
+ *    limits for project.
+ * 4) quotactl(2) succeeds to set and use Q_XGETNEXTQUOTA to get xfs disk
+ *    quota limits Cgreater than or equal to ID for project.
+ * 5) quotactl(2) succeeds to turn off xfs quota and get xfs quota off statv
+ *    for project.
+ * 6) quotactl(2) succeeds to turn on xfs quota and get xfs quota on statv
+ *    for project.
+ */
+#include "quotactl02.h"
+#if defined(HAVE_XFS_XQM_H)
+
+static uint32_t qflagp = XFS_QUOTA_PDQ_ENFD;
+static struct t_case {
+	int cmd;
+	void *addr;
+	void (*func_check)();
+	int check_subcmd;
+	int flag;
+	char *des;
+} tcases[] = {
+	{QCMD(Q_XQUOTAOFF, PRJQUOTA), &qflagp, check_qoff,
+	QCMD(Q_XGETQSTAT, PRJQUOTA), 1,
+	"turn off xfs quota and get xfs quota off status for project"},
+
+	{QCMD(Q_XQUOTAON, PRJQUOTA), &qflagp, check_qon,
+	QCMD(Q_XGETQSTAT, PRJQUOTA), 1,
+	"turn on xfs quota and get xfs quota on status for project"},
+
+	{QCMD(Q_XSETQLIM, PRJQUOTA), &set_dquota, check_qlim,
+	QCMD(Q_XGETQUOTA, PRJQUOTA), 0,
+	"Q_XGETQUOTA for project"},
+
+	{QCMD(Q_XSETQLIM, PRJQUOTA), &set_dquota, check_qlim,
+	QCMD(Q_XGETNEXTQUOTA, PRJQUOTA), 0,
+	"Q_XGETNEXTQUOTA for project"},
+
+#if defined(HAVE_STRUCT_FS_QUOTA_STATV)
+	{QCMD(Q_XQUOTAOFF, PRJQUOTA), &qflagp, check_qoffv,
+	QCMD(Q_XGETQSTATV, PRJQUOTA), 1,
+	"turn off xfs quota and get xfs quota off statv for project"},
+
+	{QCMD(Q_XQUOTAON, PRJQUOTA), &qflagp, check_qonv,
+	QCMD(Q_XGETQSTATV, PRJQUOTA), 1,
+	"turn on xfs quota and get xfs quota on statv for project"},
+#endif
+};
+
+static void setup(void)
+{
+	test_id = geteuid();
+}
+
+static void verify_quota(unsigned int n)
+{
+	struct t_case *tc = &tcases[n];
+
+	TEST(quotactl(tc->cmd, tst_device->dev, test_id, tc->addr));
+	if (TST_RET == -1) {
+		tst_res(TFAIL | TTERRNO, "quotactl() failed to %s", tc->des);
+		return;
+	}
+
+	if (tc->flag)
+		tc->func_check(tc->check_subcmd, tc->des, *(int *)(tc->addr));
+	else
+		tc->func_check(tc->check_subcmd, tc->des);
+}
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.needs_root = 1,
+	.needs_kconfigs = kconfigs,
+	.test = verify_quota,
+	.tcnt = ARRAY_SIZE(tcases),
+	.mount_device = 1,
+	.dev_fs_type = "xfs",
+	.mntpoint = mntpoint,
+	.mnt_data = "prjquota",
+	.setup = setup,
+};
+
+#else
+	TST_TEST_TCONF("This system didn't have <xfs/xqm.h>");
+#endif
-- 
2.18.0




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

* [LTP] [PATCH v3 4/5] syscalls/quotactl05: add project quota test for xfs filesystem
  2019-12-17 10:12 ` [LTP] [PATCH v3 4/5] syscalls/quotactl05: add project quota test for xfs filesystem Yang Xu
@ 2019-12-17 10:16   ` Yang Xu
  0 siblings, 0 replies; 22+ messages in thread
From: Yang Xu @ 2019-12-17 10:16 UTC (permalink / raw)
  To: ltp

Hi All
Sorry, please ingore this email. It has been merged.

Kind Regards
Yang Xu

on 2019/12/17 18:12, Yang Xu wrote:
> This is a variant about quotactl02. It is used to test project quota.
> I split it into a new case instead of adding it in quotaclt02 because
> kernel doesn't permit mount both group and project quota before
> commit d892d5864f02 ("xfs: Start using pquotaino from the superblock.").
> 
> Signed-off-by: Yang Xu<xuyang2018.jy@cn.fujitsu.com>
> ---
>   runtest/syscalls                              |  1 +
>   testcases/kernel/syscalls/quotactl/.gitignore |  2 +
>   .../kernel/syscalls/quotactl/quotactl05.c     | 99 +++++++++++++++++++
>   3 files changed, 102 insertions(+)
>   create mode 100644 testcases/kernel/syscalls/quotactl/quotactl05.c



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

* [LTP] [PATCH v1 1/4] syscalls/capset01: Cleanup & convert to new library
  2019-12-17 10:12 ` [LTP] [PATCH v1 1/4] syscalls/capset01: Cleanup & convert to new library Yang Xu
@ 2020-01-07 13:32   ` Cyril Hrubis
  2020-01-08  2:37     ` Yang Xu
  0 siblings, 1 reply; 22+ messages in thread
From: Cyril Hrubis @ 2020-01-07 13:32 UTC (permalink / raw)
  To: ltp

Hi!
This test was missing the SPDX licence header, I've added it and pushed,
thanks.

Also we do not cover the pid == 0 case here either, that should be added
later on.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v1 3/4] syscalls/capset03: add new EPERM error test without CAP_SETPCAP
  2019-12-17 10:12 ` [LTP] [PATCH v1 3/4] syscalls/capset03: add new EPERM error test without CAP_SETPCAP Yang Xu
@ 2020-01-07 13:39   ` Cyril Hrubis
  2020-01-08  3:19     ` Yang Xu
  0 siblings, 1 reply; 22+ messages in thread
From: Cyril Hrubis @ 2020-01-07 13:39 UTC (permalink / raw)
  To: ltp

Hi!
> +static void setup(void)
> +{
> +	pid_t pid;
> +
> +	pid = getpid();
> +	header.pid = pid;
> +	if (geteuid() == 0) {
> +		TEST(tst_syscall(__NR_capset, &header, data));
> +		if (TST_RET == -1)
> +			tst_brk(TBROK | TTERRNO, "capset data failed");
> +	}

Please don't do that. If tests needs root (even for a subset of the
test) just set the .needs_root flag.

> +}
> +
> +static struct tst_test test = {
> +	.setup = setup,
> +	.test_all = verify_capset,
> +	.caps = (struct tst_cap []) {
> +		TST_CAP(TST_CAP_DROP, CAP_SETPCAP),
> +		{}
> +	},
> +};
> -- 
> 2.18.0
> 
> 
> 
> 
> -- 
> Mailing list info: https://lists.linux.it/listinfo/ltp

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v1 1/4] syscalls/capset01: Cleanup & convert to new library
  2020-01-07 13:32   ` Cyril Hrubis
@ 2020-01-08  2:37     ` Yang Xu
  0 siblings, 0 replies; 22+ messages in thread
From: Yang Xu @ 2020-01-08  2:37 UTC (permalink / raw)
  To: ltp

Hi
> Hi!
> This test was missing the SPDX licence header, I've added it and pushed,
> thanks.
> 
> Also we do not cover the pid == 0 case here either, that should be added
> later on.
> 
Like capget01 discussion, I will add it.



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

* [LTP] [PATCH v1 3/4] syscalls/capset03: add new EPERM error test without CAP_SETPCAP
  2020-01-07 13:39   ` Cyril Hrubis
@ 2020-01-08  3:19     ` Yang Xu
  2020-01-08 11:03       ` Cyril Hrubis
  0 siblings, 1 reply; 22+ messages in thread
From: Yang Xu @ 2020-01-08  3:19 UTC (permalink / raw)
  To: ltp

Hi
> Hi!
>> +static void setup(void)
>> +{
>> +	pid_t pid;
>> +
>> +	pid = getpid();
>> +	header.pid = pid;
>> +	if (geteuid() == 0) {
>> +		TEST(tst_syscall(__NR_capset, &header, data));
>> +		if (TST_RET == -1)
>> +			tst_brk(TBROK | TTERRNO, "capset data failed");
>> +	}
> 
> Please don't do that. If tests needs root (even for a subset of the
> test) just set the .needs_root flag.
> 
This test doesn't need root. These code is designed to create a 
envrionment for root user to generate this type EPERM 
error?new_Inheritable is not a subset of old_Inheritable and 
old_Permitted without CAP_SETPCAP?.
root user:
old pI: CAP_KILL
old pP: CAP_KILL
new pI: CAP_KILL + CAP_NET_RAW

other user:
old pI: 0
old pP: 0
new pI: CAP_KILL + CAP_NET_RAW

other user also met condition and can generate this EPERM error.

ps: In capset03, getpid() is useless, we can use pid = 0 to replace.
Also, if we can use pid =0 in error test, maybe we don't need to test 
pid =0 in capget01/capset01.c . What do you think about it?
>> +}
>> +
>> +static struct tst_test test = {
>> +	.setup = setup,
>> +	.test_all = verify_capset,
>> +	.caps = (struct tst_cap []) {
>> +		TST_CAP(TST_CAP_DROP, CAP_SETPCAP),
>> +		{}
>> +	},
>> +};
>> -- 
>> 2.18.0
>>
>>
>>
>>
>> -- 
>> Mailing list info: https://lists.linux.it/listinfo/ltp
> 



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

* [LTP] [PATCH v1 3/4] syscalls/capset03: add new EPERM error test without CAP_SETPCAP
  2020-01-08  3:19     ` Yang Xu
@ 2020-01-08 11:03       ` Cyril Hrubis
  2020-01-09  6:17         ` Yang Xu
  0 siblings, 1 reply; 22+ messages in thread
From: Cyril Hrubis @ 2020-01-08 11:03 UTC (permalink / raw)
  To: ltp

Hi!
> >> +static void setup(void)
> >> +{
> >> +	pid_t pid;
> >> +
> >> +	pid = getpid();
> >> +	header.pid = pid;
> >> +	if (geteuid() == 0) {
> >> +		TEST(tst_syscall(__NR_capset, &header, data));
> >> +		if (TST_RET == -1)
> >> +			tst_brk(TBROK | TTERRNO, "capset data failed");
> >> +	}
> > 
> > Please don't do that. If tests needs root (even for a subset of the
> > test) just set the .needs_root flag.
> > 
> This test doesn't need root. These code is designed to create a 
> envrionment for root user to generate this type EPERM 
> error??new_Inheritable is not a subset of old_Inheritable and 
> old_Permitted without CAP_SETPCAP??.
> root user:
> old pI: CAP_KILL
> old pP: CAP_KILL
> new pI: CAP_KILL + CAP_NET_RAW
> 
> other user:
> old pI: 0
> old pP: 0
> new pI: CAP_KILL + CAP_NET_RAW
> 
> other user also met condition and can generate this EPERM error.

Hmm, we are testing different things under root and non-root then. When
the test is executed under a regular user we assert that the system
default is sane + the capset assertion, while under the root we test
only capset.

It would make sense to run the test only under root to make sure that we
are consistent.

Also the CAP_DROP in the tst_test structure seems to be useless to me.


Looking at man 7 capabilities, there are also transitions defined for
what is supposed to happen when we change user id. It would make sense
to write tests that capabilities are correctly dropped when UID changes
from 0 to nonzero. Which is what this test is testing when executed as
non-root, since the transition from 0 to nonzero must have happened
somewhere when user has logged in.

> ps: In capset03, getpid() is useless, we can use pid = 0 to replace.
> Also, if we can use pid =0 in error test, maybe we don't need to test 
> pid =0 in capget01/capset01.c . What do you think about it?

Sure. We can use 0 in all tests if we have a least one for each syscall
that tests it with pid != 0.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v1 3/4] syscalls/capset03: add new EPERM error test without CAP_SETPCAP
  2020-01-08 11:03       ` Cyril Hrubis
@ 2020-01-09  6:17         ` Yang Xu
  2020-01-09 12:41           ` Cyril Hrubis
  0 siblings, 1 reply; 22+ messages in thread
From: Yang Xu @ 2020-01-09  6:17 UTC (permalink / raw)
  To: ltp

Hi!
> Hi!
>>>> +static void setup(void)
>>>> +{
>>>> +	pid_t pid;
>>>> +
>>>> +	pid = getpid();
>>>> +	header.pid = pid;
>>>> +	if (geteuid() == 0) {
>>>> +		TEST(tst_syscall(__NR_capset, &header, data));
>>>> +		if (TST_RET == -1)
>>>> +			tst_brk(TBROK | TTERRNO, "capset data failed");
>>>> +	}
>>>
>>> Please don't do that. If tests needs root (even for a subset of the
>>> test) just set the .needs_root flag.
>>>
>> This test doesn't need root. These code is designed to create a
>> envrionment for root user to generate this type EPERM
>> error??new_Inheritable is not a subset of old_Inheritable and
>> old_Permitted without CAP_SETPCAP??.
>> root user:
>> old pI: CAP_KILL
>> old pP: CAP_KILL
>> new pI: CAP_KILL + CAP_NET_RAW
>>
>> other user:
>> old pI: 0
>> old pP: 0
>> new pI: CAP_KILL + CAP_NET_RAW
>>
>> other user also met condition and can generate this EPERM error.
> 
> Hmm, we are testing different things under root and non-root then. When
> the test is executed under a regular user we assert that the system
> default is sane + the capset assertion, while under the root we test
> only capset.
> 
> It would make sense to run the test only under root to make sure that we
> are consistent.
> 
Ok. I will make this case consistent and add .need_root flag.
> Also the CAP_DROP in the tst_test structure seems to be useless to me.
> 
> 
> Looking at man 7 capabilities, there are also transitions defined for
> what is supposed to happen when we change user id. It would make sense
> to write tests that capabilities are correctly dropped when UID changes
> from 0 to nonzero. Which is what this test is testing when executed as
> non-root, since the transition from 0 to nonzero must have happened
> somewhere when user has logged in.
In man 7 capabilities " Effect of user ID changes on capabilities",
I see transitions between 0 and nonzero user IDs. But it is about 
capabilities?not about capset syscall. I think we should add these 
cases(user ID changes on capabilities) into kernel/security (such as 
cap_bound or filecaps). In capset, we can only test capset various EPERM 
error as kernel sercurity/commoncap.c  cap_capset function.
---------------------------------
      if (cap_inh_is_capped() &&
             !cap_issubset(*inheritable,
                           cap_combine(old->cap_inheritable,
                                       old->cap_permitted)))
                 /* incapable of using this inheritable set */
                 return -EPERM;

         if (!cap_issubset(*inheritable,
                           cap_combine(old->cap_inheritable,
                                       old->cap_bset)))
                 /* no new pI capabilities outside bounding set */
                 return -EPERM;

         /* verify restrictions on target's new Permitted set */
         if (!cap_issubset(*permitted, old->cap_permitted))
                 return -EPERM;

         /* verify the _new_Effective_ is a subset of the _new_Permitted_ */
         if (!cap_issubset(*effective, *permitted))
                 return -EPERM;
---------------------------------
Also, if we only run under root, CAP_DROP(CAP_SETPCAP) is needed  to 
reproduce this EPERM error.
> 
>> ps: In capset03, getpid() is useless, we can use pid = 0 to replace.
>> Also, if we can use pid =0 in error test, maybe we don't need to test
>> pid =0 in capget01/capset01.c . What do you think about it?
> 
> Sure. We can use 0 in all tests if we have a least one for each syscall
> that tests it with pid != 0.
Ok. I will do it.
> 



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

* [LTP] [PATCH v1 3/4] syscalls/capset03: add new EPERM error test without CAP_SETPCAP
  2020-01-09  6:17         ` Yang Xu
@ 2020-01-09 12:41           ` Cyril Hrubis
  2020-01-10  5:35             ` Yang Xu
  2020-01-10 10:21             ` [LTP] [PATCH v2 1/3] syscalls/capset02: Cleanup & convert to new library Yang Xu
  0 siblings, 2 replies; 22+ messages in thread
From: Cyril Hrubis @ 2020-01-09 12:41 UTC (permalink / raw)
  To: ltp

Hi!
> > Also the CAP_DROP in the tst_test structure seems to be useless to me.
> > 
> > 
> > Looking at man 7 capabilities, there are also transitions defined for
> > what is supposed to happen when we change user id. It would make sense
> > to write tests that capabilities are correctly dropped when UID changes
> > from 0 to nonzero. Which is what this test is testing when executed as
> > non-root, since the transition from 0 to nonzero must have happened
> > somewhere when user has logged in.
> In man 7 capabilities " Effect of user ID changes on capabilities",
> I see transitions between 0 and nonzero user IDs. But it is about 
> capabilities??not about capset syscall. I think we should add these 
> cases(user ID changes on capabilities) into kernel/security (such as 
> cap_bound or filecaps). In capset, we can only test capset various EPERM 
> error as kernel sercurity/commoncap.c  cap_capset function.
> ---------------------------------
>       if (cap_inh_is_capped() &&
>              !cap_issubset(*inheritable,
>                            cap_combine(old->cap_inheritable,
>                                        old->cap_permitted)))
>                  /* incapable of using this inheritable set */
>                  return -EPERM;
> 
>          if (!cap_issubset(*inheritable,
>                            cap_combine(old->cap_inheritable,
>                                        old->cap_bset)))
>                  /* no new pI capabilities outside bounding set */
>                  return -EPERM;
> 
>          /* verify restrictions on target's new Permitted set */
>          if (!cap_issubset(*permitted, old->cap_permitted))
>                  return -EPERM;
> 
>          /* verify the _new_Effective_ is a subset of the _new_Permitted_ */
>          if (!cap_issubset(*effective, *permitted))
>                  return -EPERM;
> ---------------------------------

Indeed these does not belog under setcap(). Maybe we could add these
checks under setuid tests, since we are testing side efect of setuid.
But having these under security/ would work as well.

> Also, if we only run under root, CAP_DROP(CAP_SETPCAP) is needed  to 
> reproduce this EPERM error.

Isn't the first thing that the test does to remove all capabilities but
CAP_KILL? Why do we need to drop anything beforehand?

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v1 3/4] syscalls/capset03: add new EPERM error test without CAP_SETPCAP
  2020-01-09 12:41           ` Cyril Hrubis
@ 2020-01-10  5:35             ` Yang Xu
  2020-01-10 10:21             ` [LTP] [PATCH v2 1/3] syscalls/capset02: Cleanup & convert to new library Yang Xu
  1 sibling, 0 replies; 22+ messages in thread
From: Yang Xu @ 2020-01-10  5:35 UTC (permalink / raw)
  To: ltp

Hi!
> Hi!
>>> Also the CAP_DROP in the tst_test structure seems to be useless to me.
>>>
>>>
>>> Looking at man 7 capabilities, there are also transitions defined for
>>> what is supposed to happen when we change user id. It would make sense
>>> to write tests that capabilities are correctly dropped when UID changes
>>> from 0 to nonzero. Which is what this test is testing when executed as
>>> non-root, since the transition from 0 to nonzero must have happened
>>> somewhere when user has logged in.
>> In man 7 capabilities " Effect of user ID changes on capabilities",
>> I see transitions between 0 and nonzero user IDs. But it is about
>> capabilities??not about capset syscall. I think we should add these
>> cases(user ID changes on capabilities) into kernel/security (such as
>> cap_bound or filecaps). In capset, we can only test capset various EPERM
>> error as kernel sercurity/commoncap.c  cap_capset function.
>> ---------------------------------
>>        if (cap_inh_is_capped() &&
>>               !cap_issubset(*inheritable,
>>                             cap_combine(old->cap_inheritable,
>>                                         old->cap_permitted)))
>>                   /* incapable of using this inheritable set */
>>                   return -EPERM;
>>
>>           if (!cap_issubset(*inheritable,
>>                             cap_combine(old->cap_inheritable,
>>                                         old->cap_bset)))
>>                   /* no new pI capabilities outside bounding set */
>>                   return -EPERM;
>>
>>           /* verify restrictions on target's new Permitted set */
>>           if (!cap_issubset(*permitted, old->cap_permitted))
>>                   return -EPERM;
>>
>>           /* verify the _new_Effective_ is a subset of the _new_Permitted_ */
>>           if (!cap_issubset(*effective, *permitted))
>>                   return -EPERM;
>> ---------------------------------
> 
> Indeed these does not belog under setcap(). Maybe we could add these
> checks under setuid tests, since we are testing side efect of setuid.
> But having these under security/ would work as well.Maybe put them in setuid is better because I don't know a  good 
directory name for them in security(such as user_change_cap). Anyway, I 
will list them in my todo.
> 
>> Also, if we only run under root, CAP_DROP(CAP_SETPCAP) is needed  to
>> reproduce this EPERM error.
> 
> Isn't the first thing that the test does to remove all capabilities but
> CAP_KILL? Why do we need to drop anything beforehand?
Yes, you are right. I forgot it. I will remove this drop and also used 
guarded buffer  for the other capset cases .
> 



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

* [LTP] [PATCH v2 1/3] syscalls/capset02: Cleanup & convert to new library
  2020-01-09 12:41           ` Cyril Hrubis
  2020-01-10  5:35             ` Yang Xu
@ 2020-01-10 10:21             ` Yang Xu
  2020-01-10 10:21               ` [LTP] [PATCH v2 2/3] syscalls/capset03: add new EPERM error test without CAP_SETPCAP Yang Xu
                                 ` (3 more replies)
  1 sibling, 4 replies; 22+ messages in thread
From: Yang Xu @ 2020-01-10 10:21 UTC (permalink / raw)
  To: ltp

It adds a preferred linux capabilities version check like
capget02. Also, it adds various cases about EPERM error.

--------
v1-v2:
1. use guarded buffer
2. add needs_root flag
3. remove wrong EINVAL error test about unused pid
--------

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 testcases/kernel/syscalls/capset/capset02.c | 332 ++++++--------------
 1 file changed, 93 insertions(+), 239 deletions(-)

diff --git a/testcases/kernel/syscalls/capset/capset02.c b/testcases/kernel/syscalls/capset/capset02.c
index aece29511..15589d462 100644
--- a/testcases/kernel/syscalls/capset/capset02.c
+++ b/testcases/kernel/syscalls/capset/capset02.c
@@ -1,261 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (c) Wipro Technologies Ltd, 2002.  All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+ * Author: Saji Kumar.V.R <saji.kumar@wipro.com>
+ *
+ * Tests basic error handling of the capset syscall.
+ * 1) capset() fails with errno set to EFAULT if an invalid address
+ * is given for header.
+ * 2) capset() fails with errno set to EFAULT if an invalid address
+ * is given for data.
+ * 3) capset() fails with errno set to EINVAL if an invalid value
+ * is given for header->version.
+ * 4) capset() fails with errno set to EPERM if the new_Effective is
+ * not a subset of the new_Permitted.
+ * 5) capset() fails with errno set to EPERM if the new_Permitted is
+ * not a subset of the old_Permitted.
+ * 6) capset() fails with errno set ot EPERM if the new_Inheritable is
+ * not a subset of  the old_Inheritable and bounding set.
  */
-/**********************************************************
- *
- *    TEST IDENTIFIER	: capset02
- *
- *    EXECUTED BY	: anyone
- *
- *    TEST TITLE	: Tests for error conditions.
- *
- *    TEST CASE TOTAL	: 4
- *
- *    AUTHOR		: Saji Kumar.V.R <saji.kumar@wipro.com>
- *
- *    SIGNALS
- * 	Uses SIGUSR1 to pause before test if option set.
- * 	(See the parse_opts(3) man page).
- *
- *    DESCRIPTION
- *	Verify that
- *	1) capset() fails with errno set to EFAULT if an invalid address
- *	   is given for header
- *	2) capset() fails with errno set to EFAULT if an invalid address
- *	   is given for data
- *	3) capset() fails with errno set to EINVAL if an invalid value
- *	   is given for header->version
- *	4) capset() fails with errno set to EPERM the process does not
- *	   have enough privilege to set capabilities
- *
- *
- * 	Setup:
- * 	  Setup signal handling.
- *	  Pause for SIGUSR1 if option specified.
- *	  Call capget() to save current capability data
- *
- * 	Test:
- *	 Loop if the proper options are given.
- *	  do test specific setup.
- * 	  call capset with proper arguments
- *	  if capset() fails with expected errno
- *		Test passed
- *	  Otherwise
- *		Test failed
- *	  do test specific cleanup
- *
- * 	Cleanup:
- * 	  Print errno log and/or timing stats if options given
- *
- * USAGE:  <for command-line>
- * capset02 [-c n] [-e] [-i n] [-I x] [-P x] [-t] [-h] [-f] [-p]
- *			where,  -c n : Run n copies concurrently.
- *				-e   : Turn on errno logging.
- *				-h   : Show help screen
- *				-f   : Turn off functional testing
- *				-i n : Execute test n times.
- *				-I x : Execute test for x seconds.
- *				-p   : Pause for SIGUSR1 before starting
- *				-P x : Pause for x seconds between iterations.
- *				-t   : Turn on syscall timing.
- *
- ****************************************************************/
+#include <stdlib.h>
 #include <sys/types.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <pwd.h>
-#include <signal.h>
-#include <string.h>
 #include <unistd.h>
-#include "test.h"
-#include "safe_macros.h"
+#include <sys/prctl.h>
+#include "tst_test.h"
 #include "lapi/syscalls.h"
-
-/**************************************************************************/
-/*                                                                        */
-/*   Some archs do not have the manpage documented sys/capability.h file, */
-/*   and require the use of the line below                                */
-
 #include <linux/capability.h>
 
-/*   If you are having issues with including this file and have the sys/  */
-/*   version, then you may want to try switching to it. -Robbie W.        */
-/**************************************************************************/
-
-#define INVALID_VERSION 0
-
-static void setup(void);
-static void cleanup(void);
-static void test_setup(int, char *);
-static void child_func(void);
-
-static pid_t child_pid = -1;
-
-char *TCID = "capset02";
-
-static struct __user_cap_header_struct header;
-static struct __user_cap_data_struct data;
-
-struct test_case_t {
-	cap_user_header_t headerp;
-	cap_user_data_t datap;
-	int exp_errno;
-	char *errdesc;
-} test_cases[] = {
-#ifndef UCLINUX
-	/* Skip since uClinux does not implement memory protection */
-	{
-	(cap_user_header_t) - 1, &data, EFAULT, "EFAULT"}, {
-	&header, (cap_user_data_t) - 1, EFAULT, "EFAULT"},
-#endif
-	{
-	&header, &data, EINVAL, "EINVAL"}, {
-&header, &data, EPERM, "EPERM"},};
-
-int TST_TOTAL = sizeof(test_cases) / sizeof(test_cases[0]);
-
-int main(int ac, char **av)
+#define CAP1 (1 << CAP_NET_RAW | 1 << CAP_CHOWN  | 1 << CAP_SETPCAP)
+#define CAP2 (CAP1 | 1 << CAP_KILL)
+
+static int drop_flag;
+static struct __user_cap_header_struct *header;
+static struct __user_cap_data_struct *data;
+
+static struct tcase {
+	int version;
+	int pid;
+	int effective;
+	int permitted;
+	int inheritable;
+	int exp_err;
+	int flag;
+	char *message;
+} tcases[] = {
+	{0x20080522, 0, CAP1, CAP1, CAP1, EFAULT, 1, "Test bad address header"},
+	{0x20080522, 0, CAP1, CAP1, CAP1, EFAULT, 2, "Test bad address data"},
+	{0, 0, CAP1, CAP1, CAP1, EINVAL, 0, "Test bad version"},
+	{0x20080522, 0, CAP2, CAP1, CAP1, EPERM, 0, "Test bad value data(when pE is not in pP)"},
+	{0x20080522, 0, CAP1, CAP2, CAP1, EPERM, 0, "Test bad value data(when pP is not in old pP)"},
+	{0x20080522, 0, CAP1, CAP1, CAP2, EPERM, 0, "Test bad value data(when pI is not in bounding set or old pI)"},
+};
+
+static void verify_capset(unsigned int n)
 {
+	struct tcase *tc = &tcases[n];
 
-	int lc, i;
+	header->version = tc->version;
+	header->pid = tc->pid;
 
-	tst_parse_opts(ac, av, NULL, NULL);
-#ifdef UCLINUX
-	maybe_run_child(&child_func, "");
-#endif
+	data->effective = tc->effective;
+	data->permitted = tc->permitted;
+	data->inheritable = tc->inheritable;
 
-	setup();
+	tst_res(TINFO, "%s", tc->message);
 
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-
-		tst_count = 0;
-
-#ifdef UCLINUX
-		i = 2;
-#else
-		i = 0;
-#endif
-
-		for (; i < TST_TOTAL; i++) {
-
-			test_setup(i, av[0]);
-			TEST(ltp_syscall(__NR_capset, test_cases[i].headerp,
-				     test_cases[i].datap));
-
-			if (TEST_RETURN == -1 &&
-			    TEST_ERRNO == test_cases[i].exp_errno) {
-				tst_resm(TPASS, "capset() returned -1,"
-					 " errno: %s", test_cases[i].errdesc);
-			} else {
-				tst_resm(TFAIL | TTERRNO,
-					 "Test Failed, capset() returned %ld",
-					 TEST_RETURN);
-			}
-		}
+	TEST(tst_syscall(__NR_capset, tc->flag - 1 ? header : NULL,
+				tc->flag - 2 ? data : NULL));
+	if (TST_RET == 0) {
+		tst_res(TFAIL, "capset() succeed unexpectedly");
+		return;
 	}
-
-	cleanup();
-
-	tst_exit();
-
-}
-
-void setup(void)
-{
-	tst_require_root();
-
-	TEST_PAUSE;
-
+	if (TST_ERR == tc->exp_err)
+		tst_res(TPASS | TTERRNO, "capset() failed as expected");
+	else
+		tst_res(TFAIL | TTERRNO, "capset() expected %s got ",
+			tst_strerrno(tc->exp_err));
 	/*
-	 * Save current capability data.
-	 * header.version must be _LINUX_CAPABILITY_VERSION
+	 * When an unsupported version value is specified, it will
+	 * return the kernel preferred value of _LINUX_CAPABILITY_VERSION_?.
+	 * Since linux 2.6.26, version 3 is default. We use it.
 	 */
-	header.version = _LINUX_CAPABILITY_VERSION;
-	if (ltp_syscall(__NR_capget, &header, &data) == -1)
-		tst_brkm(TBROK | TERRNO, NULL, "capget failed");
+	if (header->version != 0x20080522)
+		tst_res(TFAIL, "kernel doesn't return preferred linux"
+			" capability version when using bad version");
 }
 
-void cleanup(void)
+static void setup(void)
 {
-	if (0 < child_pid) {
-		kill(child_pid, SIGTERM);
-		wait(NULL);
-	}
+	header->version = 0x20080522;
+	data->effective = CAP1;
+	data->permitted = CAP1;
+	data->inheritable = CAP1;
+
+	TEST(tst_syscall(__NR_capset, header, data));
+	if (TST_RET == -1)
+		tst_brk(TBROK | TTERRNO, "capset data failed");
+
+	TEST(prctl(PR_CAPBSET_DROP, CAP_KILL));
+	if (TST_RET == -1)
+		tst_res(TFAIL | TTERRNO, "drop CAP_KILL failed");
+	else
+		drop_flag = 1;
 }
 
-void child_func(void)
-{
-	for (;;) {
-		sleep(10);
+static struct tst_test test = {
+	.setup = setup,
+	.tcnt = ARRAY_SIZE(tcases),
+	.test = verify_capset,
+	.needs_root = 1,
+	.bufs = (struct tst_buffers []) {
+		{&header, .size = sizeof(*header)},
+		{&data, .size = 2 * sizeof(*data)},
+		{},
 	}
-}
-
-void test_setup(int i, char *argv0)
-{
-	char nobody_uid[] = "nobody";
-	struct passwd *ltpuser;
-
-	switch (i) {
-	case 0:
-		break;
-
-	case 1:
-		header.version = _LINUX_CAPABILITY_VERSION;
-		header.pid = 0;
-		break;
-
-	case 2:
-		header.version = INVALID_VERSION;
-		header.pid = 0;
-		break;
-
-	case 3:
-		header.version = _LINUX_CAPABILITY_VERSION;
-		/*
-		 * when a non-zero pid is specified, process should have
-		 * CAP_SETPCAP capability to change capabilities.
-		 * by default, CAP_SETPCAP is not enabled. So giving
-		 * a non-zero pid results in capset() failing with
-		 * errno EPERM
-		 *
-		 * Note: this seems to have changed with recent kernels
-		 * => create a child and try to set its capabilities
-		 */
-		child_pid = FORK_OR_VFORK();
-		if (child_pid == -1)
-			tst_brkm(TBROK | TERRNO, cleanup, "fork failed");
-		else if (child_pid == 0) {
-#ifdef UCLINUX
-			if (self_exec(argv0, "") < 0) {
-				perror("self_exec failed");
-				exit(1);
-			}
-#else
-			child_func();
-#endif
-		} else {
-			header.pid = child_pid;
-			ltpuser = getpwnam(nobody_uid);
-			if (ltpuser == NULL)
-				tst_brkm(TBROK | TERRNO, cleanup,
-					 "getpwnam failed");
-			SAFE_SETEUID(cleanup, ltpuser->pw_uid);
-
-		}
-		break;
-
-	}
-}
+};
-- 
2.18.0




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

* [LTP] [PATCH v2 2/3] syscalls/capset03: add new EPERM error test without CAP_SETPCAP
  2020-01-10 10:21             ` [LTP] [PATCH v2 1/3] syscalls/capset02: Cleanup & convert to new library Yang Xu
@ 2020-01-10 10:21               ` Yang Xu
  2020-01-15 14:28                 ` Cyril Hrubis
  2020-01-10 10:21               ` [LTP] [PATCH v2 3/3] syscalls/capset04: add new EPERM error test with vfs cap support Yang Xu
                                 ` (2 subsequent siblings)
  3 siblings, 1 reply; 22+ messages in thread
From: Yang Xu @ 2020-01-10 10:21 UTC (permalink / raw)
  To: ltp

-------------------
v1->v2:
1.remove useless drop
2. use guarded buffer allocation
-------------------

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 runtest/syscalls                            |  1 +
 testcases/kernel/syscalls/capset/.gitignore |  1 +
 testcases/kernel/syscalls/capset/capset03.c | 59 +++++++++++++++++++++
 3 files changed, 61 insertions(+)
 create mode 100644 testcases/kernel/syscalls/capset/capset03.c

diff --git a/runtest/syscalls b/runtest/syscalls
index fa87ef63f..4f481be6d 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -44,6 +44,7 @@ capget02 capget02
 
 capset01 capset01
 capset02 capset02
+capset03 capset03
 
 cacheflush01 cacheflush01
 
diff --git a/testcases/kernel/syscalls/capset/.gitignore b/testcases/kernel/syscalls/capset/.gitignore
index 004ce7b3e..3f9a4d5e8 100644
--- a/testcases/kernel/syscalls/capset/.gitignore
+++ b/testcases/kernel/syscalls/capset/.gitignore
@@ -1,2 +1,3 @@
 /capset01
 /capset02
+/capset03
diff --git a/testcases/kernel/syscalls/capset/capset03.c b/testcases/kernel/syscalls/capset/capset03.c
new file mode 100644
index 000000000..d5754753d
--- /dev/null
+++ b/testcases/kernel/syscalls/capset/capset03.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2019 FUJITSU LIMITED. All rights reserved.
+ * Author: Yang Xu <xuyang2018.jy@cn.fujitsu.com
+ *
+ * capset() fails with errno set or EPERM if the new_Inheritable is
+ * not a subset of old_Inheritable and old_Permitted without CAP_SETPCAP.
+ */
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+#include <linux/capability.h>
+
+#define CAP1 (1 << CAP_KILL)
+#define CAP2 (CAP1 | 1 << CAP_NET_RAW)
+
+static struct __user_cap_header_struct *header;
+static struct __user_cap_data_struct *data;
+
+static void verify_capset(void)
+{
+	tst_res(TINFO, "Test bad value data(when pI is not old pP or old pI without CAP_SETPCAP)");
+	data[0].inheritable = CAP2;
+	TEST(tst_syscall(__NR_capset, header, data));
+	if (TST_RET == 0) {
+		tst_res(TFAIL, "capset succeed unexpectedly");
+		return;
+	}
+	if (TST_ERR == EPERM)
+		tst_res(TPASS | TTERRNO, "capset() failed as expected");
+	else
+		tst_res(TFAIL | TTERRNO, "capset expected EPERM, bug got");
+}
+
+static void setup(void)
+{
+	header->version = 0x20080522;
+
+	data[0].effective = CAP1;
+	data[0].permitted = CAP1;
+	data[0].inheritable = CAP1;
+
+	TEST(tst_syscall(__NR_capset, header, data));
+	if (TST_RET == -1)
+		tst_brk(TBROK | TTERRNO, "capset data failed");
+}
+
+static struct tst_test test = {
+	.setup = setup,
+	.test_all = verify_capset,
+	.needs_root = 1,
+	.bufs = (struct tst_buffers []) {
+		{&header, .size = sizeof(*header)},
+		{&data, .size = 2 * sizeof(*data)},
+		{},
+	}
+};
-- 
2.18.0




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

* [LTP] [PATCH v2 3/3] syscalls/capset04: add new EPERM error test with vfs cap support
  2020-01-10 10:21             ` [LTP] [PATCH v2 1/3] syscalls/capset02: Cleanup & convert to new library Yang Xu
  2020-01-10 10:21               ` [LTP] [PATCH v2 2/3] syscalls/capset03: add new EPERM error test without CAP_SETPCAP Yang Xu
@ 2020-01-10 10:21               ` Yang Xu
  2020-01-15 14:28                 ` Cyril Hrubis
  2020-01-10 14:30               ` [LTP] [PATCH v2 1/3] syscalls/capset02: Cleanup & convert to new library Cyril Hrubis
  2020-01-15 13:43               ` Cyril Hrubis
  3 siblings, 1 reply; 22+ messages in thread
From: Yang Xu @ 2020-01-10 10:21 UTC (permalink / raw)
  To: ltp

Now, most linux distributions has VFS capabilities supports, so
modifying other process cap is never permitted. This case from old
capset02.c.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 runtest/syscalls                            |  1 +
 testcases/kernel/syscalls/capset/.gitignore |  1 +
 testcases/kernel/syscalls/capset/capset04.c | 81 +++++++++++++++++++++
 3 files changed, 83 insertions(+)
 create mode 100644 testcases/kernel/syscalls/capset/capset04.c

diff --git a/runtest/syscalls b/runtest/syscalls
index 4f481be6d..f58fefe17 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -45,6 +45,7 @@ capget02 capget02
 capset01 capset01
 capset02 capset02
 capset03 capset03
+capset04 capset04
 
 cacheflush01 cacheflush01
 
diff --git a/testcases/kernel/syscalls/capset/.gitignore b/testcases/kernel/syscalls/capset/.gitignore
index 3f9a4d5e8..d0a7a13a4 100644
--- a/testcases/kernel/syscalls/capset/.gitignore
+++ b/testcases/kernel/syscalls/capset/.gitignore
@@ -1,3 +1,4 @@
 /capset01
 /capset02
 /capset03
+/capset04
diff --git a/testcases/kernel/syscalls/capset/capset04.c b/testcases/kernel/syscalls/capset/capset04.c
new file mode 100644
index 000000000..895b62e17
--- /dev/null
+++ b/testcases/kernel/syscalls/capset/capset04.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) Wipro Technologies Ltd, 2002.  All Rights Reserved.
+ * Author: Saji Kumar.V.R <saji.kumar@wipro.com>
+ *
+ * Tests whether we can use capset() to modify the capabilities of a thread
+ * other than itself. Now, most linux distributions with kernel supporting
+ * VFS capabilities, this should be never permitted.
+ */
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+#include <linux/capability.h>
+
+static struct __user_cap_header_struct *header;
+static struct __user_cap_data_struct *data;
+static pid_t child_pid;
+static int clean_nflag;
+static void cleanup(void);
+
+static void child_func(void)
+{
+	for (;;)
+		sleep(10);
+}
+
+static void verify_capset(void)
+{
+	child_pid = SAFE_FORK();
+	if (child_pid == 0) {
+		child_func();
+		exit(0);
+	}
+
+	clean_nflag = 0;
+	header->pid = child_pid;
+
+	TEST(tst_syscall(__NR_capset, header, data));
+	if (TST_RET == 0) {
+		tst_res(TFAIL, "capset succeed unexpectedly");
+		cleanup();
+		return;
+	}
+	if (TST_ERR == EPERM)
+		tst_res(TPASS, "capset doesn't can modify other process capabilities");
+	else
+		tst_res(TFAIL | TTERRNO, "capset expected EPERM, bug got");
+
+	cleanup();
+}
+
+static void setup(void)
+{
+	header->version = 0x20080522;
+	TEST(tst_syscall(__NR_capget, header, data));
+	if (TST_RET == -1)
+		tst_brk(TBROK | TTERRNO, "capget data failed");
+}
+
+static void cleanup(void)
+{
+	if (child_pid > 0 && !clean_nflag) {
+		SAFE_KILL(child_pid, SIGTERM);
+		SAFE_WAIT(NULL);
+		clean_nflag = 1;
+	}
+}
+
+static struct tst_test test = {
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = verify_capset,
+	.forks_child = 1,
+	.bufs = (struct tst_buffers []) {
+		{&header, .size = sizeof(*header)},
+		{&data, .size = 2 * sizeof(*data)},
+		{},
+	}
+};
-- 
2.18.0




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

* [LTP] [PATCH v2 1/3] syscalls/capset02: Cleanup & convert to new library
  2020-01-10 10:21             ` [LTP] [PATCH v2 1/3] syscalls/capset02: Cleanup & convert to new library Yang Xu
  2020-01-10 10:21               ` [LTP] [PATCH v2 2/3] syscalls/capset03: add new EPERM error test without CAP_SETPCAP Yang Xu
  2020-01-10 10:21               ` [LTP] [PATCH v2 3/3] syscalls/capset04: add new EPERM error test with vfs cap support Yang Xu
@ 2020-01-10 14:30               ` Cyril Hrubis
  2020-01-13  1:31                 ` Yang Xu
  2020-01-15 13:43               ` Cyril Hrubis
  3 siblings, 1 reply; 22+ messages in thread
From: Cyril Hrubis @ 2020-01-10 14:30 UTC (permalink / raw)
  To: ltp

Hi!
> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> ---
>  testcases/kernel/syscalls/capset/capset02.c | 332 ++++++--------------
>  1 file changed, 93 insertions(+), 239 deletions(-)
> 
> diff --git a/testcases/kernel/syscalls/capset/capset02.c b/testcases/kernel/syscalls/capset/capset02.c
> index aece29511..15589d462 100644
> --- a/testcases/kernel/syscalls/capset/capset02.c
> +++ b/testcases/kernel/syscalls/capset/capset02.c
> @@ -1,261 +1,115 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
>  /*
>   * Copyright (c) Wipro Technologies Ltd, 2002.  All Rights Reserved.
> - *
> - * This program is free software; you can redistribute it and/or modify it
> - * under the terms of version 2 of the GNU General Public License as
> - * published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it would be useful, but
> - * WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> - *
> - * You should have received a copy of the GNU General Public License along
> - * with this program; if not, write the Free Software Foundation, Inc.,
> - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> - *
> + * Author: Saji Kumar.V.R <saji.kumar@wipro.com>
> + *
> + * Tests basic error handling of the capset syscall.
> + * 1) capset() fails with errno set to EFAULT if an invalid address
> + * is given for header.
> + * 2) capset() fails with errno set to EFAULT if an invalid address
> + * is given for data.
> + * 3) capset() fails with errno set to EINVAL if an invalid value
> + * is given for header->version.
> + * 4) capset() fails with errno set to EPERM if the new_Effective is
> + * not a subset of the new_Permitted.
> + * 5) capset() fails with errno set to EPERM if the new_Permitted is
> + * not a subset of the old_Permitted.
> + * 6) capset() fails with errno set ot EPERM if the new_Inheritable is
> + * not a subset of  the old_Inheritable and bounding set.
>   */
> -/**********************************************************
> - *
> - *    TEST IDENTIFIER	: capset02
> - *
> - *    EXECUTED BY	: anyone
> - *
> - *    TEST TITLE	: Tests for error conditions.
> - *
> - *    TEST CASE TOTAL	: 4
> - *
> - *    AUTHOR		: Saji Kumar.V.R <saji.kumar@wipro.com>
> - *
> - *    SIGNALS
> - * 	Uses SIGUSR1 to pause before test if option set.
> - * 	(See the parse_opts(3) man page).
> - *
> - *    DESCRIPTION
> - *	Verify that
> - *	1) capset() fails with errno set to EFAULT if an invalid address
> - *	   is given for header
> - *	2) capset() fails with errno set to EFAULT if an invalid address
> - *	   is given for data
> - *	3) capset() fails with errno set to EINVAL if an invalid value
> - *	   is given for header->version
> - *	4) capset() fails with errno set to EPERM the process does not
> - *	   have enough privilege to set capabilities
> - *
> - *
> - * 	Setup:
> - * 	  Setup signal handling.
> - *	  Pause for SIGUSR1 if option specified.
> - *	  Call capget() to save current capability data
> - *
> - * 	Test:
> - *	 Loop if the proper options are given.
> - *	  do test specific setup.
> - * 	  call capset with proper arguments
> - *	  if capset() fails with expected errno
> - *		Test passed
> - *	  Otherwise
> - *		Test failed
> - *	  do test specific cleanup
> - *
> - * 	Cleanup:
> - * 	  Print errno log and/or timing stats if options given
> - *
> - * USAGE:  <for command-line>
> - * capset02 [-c n] [-e] [-i n] [-I x] [-P x] [-t] [-h] [-f] [-p]
> - *			where,  -c n : Run n copies concurrently.
> - *				-e   : Turn on errno logging.
> - *				-h   : Show help screen
> - *				-f   : Turn off functional testing
> - *				-i n : Execute test n times.
> - *				-I x : Execute test for x seconds.
> - *				-p   : Pause for SIGUSR1 before starting
> - *				-P x : Pause for x seconds between iterations.
> - *				-t   : Turn on syscall timing.
> - *
> - ****************************************************************/
> +#include <stdlib.h>
>  #include <sys/types.h>
> -#include <sys/wait.h>
> -#include <errno.h>
> -#include <pwd.h>
> -#include <signal.h>
> -#include <string.h>
>  #include <unistd.h>
> -#include "test.h"
> -#include "safe_macros.h"
> +#include <sys/prctl.h>
> +#include "tst_test.h"
>  #include "lapi/syscalls.h"
> -
> -/**************************************************************************/
> -/*                                                                        */
> -/*   Some archs do not have the manpage documented sys/capability.h file, */
> -/*   and require the use of the line below                                */
> -
>  #include <linux/capability.h>
>  
> -/*   If you are having issues with including this file and have the sys/  */
> -/*   version, then you may want to try switching to it. -Robbie W.        */
> -/**************************************************************************/
> -
> -#define INVALID_VERSION 0
> -
> -static void setup(void);
> -static void cleanup(void);
> -static void test_setup(int, char *);
> -static void child_func(void);
> -
> -static pid_t child_pid = -1;
> -
> -char *TCID = "capset02";
> -
> -static struct __user_cap_header_struct header;
> -static struct __user_cap_data_struct data;
> -
> -struct test_case_t {
> -	cap_user_header_t headerp;
> -	cap_user_data_t datap;
> -	int exp_errno;
> -	char *errdesc;
> -} test_cases[] = {
> -#ifndef UCLINUX
> -	/* Skip since uClinux does not implement memory protection */
> -	{
> -	(cap_user_header_t) - 1, &data, EFAULT, "EFAULT"}, {
> -	&header, (cap_user_data_t) - 1, EFAULT, "EFAULT"},
> -#endif
> -	{
> -	&header, &data, EINVAL, "EINVAL"}, {
> -&header, &data, EPERM, "EPERM"},};
> -
> -int TST_TOTAL = sizeof(test_cases) / sizeof(test_cases[0]);
> -
> -int main(int ac, char **av)
> +#define CAP1 (1 << CAP_NET_RAW | 1 << CAP_CHOWN  | 1 << CAP_SETPCAP)
> +#define CAP2 (CAP1 | 1 << CAP_KILL)
> +
> +static int drop_flag;
> +static struct __user_cap_header_struct *header;
> +static struct __user_cap_data_struct *data;
> +
> +static struct tcase {
> +	int version;
> +	int pid;
> +	int effective;
> +	int permitted;
> +	int inheritable;
> +	int exp_err;
> +	int flag;
> +	char *message;
> +} tcases[] = {
> +	{0x20080522, 0, CAP1, CAP1, CAP1, EFAULT, 1, "Test bad address header"},
> +	{0x20080522, 0, CAP1, CAP1, CAP1, EFAULT, 2, "Test bad address data"},
> +	{0, 0, CAP1, CAP1, CAP1, EINVAL, 0, "Test bad version"},
> +	{0x20080522, 0, CAP2, CAP1, CAP1, EPERM, 0, "Test bad value data(when pE is not in pP)"},
> +	{0x20080522, 0, CAP1, CAP2, CAP1, EPERM, 0, "Test bad value data(when pP is not in old pP)"},
> +	{0x20080522, 0, CAP1, CAP1, CAP2, EPERM, 0, "Test bad value data(when pI is not in bounding set or old pI)"},
> +};
> +
> +static void verify_capset(unsigned int n)
>  {
> +	struct tcase *tc = &tcases[n];
>  
> -	int lc, i;
> +	header->version = tc->version;
> +	header->pid = tc->pid;
>  
> -	tst_parse_opts(ac, av, NULL, NULL);
> -#ifdef UCLINUX
> -	maybe_run_child(&child_func, "");
> -#endif
> +	data->effective = tc->effective;
> +	data->permitted = tc->permitted;
> +	data->inheritable = tc->inheritable;
>  
> -	setup();
> +	tst_res(TINFO, "%s", tc->message);
>  
> -	for (lc = 0; TEST_LOOPING(lc); lc++) {
> -
> -		tst_count = 0;
> -
> -#ifdef UCLINUX
> -		i = 2;
> -#else
> -		i = 0;
> -#endif
> -
> -		for (; i < TST_TOTAL; i++) {
> -
> -			test_setup(i, av[0]);
> -			TEST(ltp_syscall(__NR_capset, test_cases[i].headerp,
> -				     test_cases[i].datap));
> -
> -			if (TEST_RETURN == -1 &&
> -			    TEST_ERRNO == test_cases[i].exp_errno) {
> -				tst_resm(TPASS, "capset() returned -1,"
> -					 " errno: %s", test_cases[i].errdesc);
> -			} else {
> -				tst_resm(TFAIL | TTERRNO,
> -					 "Test Failed, capset() returned %ld",
> -					 TEST_RETURN);
> -			}
> -		}
> +	TEST(tst_syscall(__NR_capset, tc->flag - 1 ? header : NULL,
> +				tc->flag - 2 ? data : NULL));
> +	if (TST_RET == 0) {
> +		tst_res(TFAIL, "capset() succeed unexpectedly");
> +		return;
>  	}
> -
> -	cleanup();
> -
> -	tst_exit();
> -
> -}
> -
> -void setup(void)
> -{
> -	tst_require_root();
> -
> -	TEST_PAUSE;
> -
> +	if (TST_ERR == tc->exp_err)
> +		tst_res(TPASS | TTERRNO, "capset() failed as expected");
> +	else
> +		tst_res(TFAIL | TTERRNO, "capset() expected %s got ",
> +			tst_strerrno(tc->exp_err));
>  	/*
> -	 * Save current capability data.
> -	 * header.version must be _LINUX_CAPABILITY_VERSION
> +	 * When an unsupported version value is specified, it will
> +	 * return the kernel preferred value of _LINUX_CAPABILITY_VERSION_?.
> +	 * Since linux 2.6.26, version 3 is default. We use it.
>  	 */
> -	header.version = _LINUX_CAPABILITY_VERSION;
> -	if (ltp_syscall(__NR_capget, &header, &data) == -1)
> -		tst_brkm(TBROK | TERRNO, NULL, "capget failed");
> +	if (header->version != 0x20080522)
> +		tst_res(TFAIL, "kernel doesn't return preferred linux"
> +			" capability version when using bad version");
>  }
>  
> -void cleanup(void)
> +static void setup(void)
>  {
> -	if (0 < child_pid) {
> -		kill(child_pid, SIGTERM);
> -		wait(NULL);
> -	}
> +	header->version = 0x20080522;
> +	data->effective = CAP1;
> +	data->permitted = CAP1;
> +	data->inheritable = CAP1;
> +
> +	TEST(tst_syscall(__NR_capset, header, data));
> +	if (TST_RET == -1)
> +		tst_brk(TBROK | TTERRNO, "capset data failed");
> +
> +	TEST(prctl(PR_CAPBSET_DROP, CAP_KILL));
> +	if (TST_RET == -1)
> +		tst_res(TFAIL | TTERRNO, "drop CAP_KILL failed");
> +	else
> +		drop_flag = 1;

This flag does not seem to be used anywhere. Can't we simply tst_brk()
here if the call fails?

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v2 1/3] syscalls/capset02: Cleanup & convert to new library
  2020-01-10 14:30               ` [LTP] [PATCH v2 1/3] syscalls/capset02: Cleanup & convert to new library Cyril Hrubis
@ 2020-01-13  1:31                 ` Yang Xu
  0 siblings, 0 replies; 22+ messages in thread
From: Yang Xu @ 2020-01-13  1:31 UTC (permalink / raw)
  To: ltp

Hi Cyril
>> +	TEST(prctl(PR_CAPBSET_DROP, CAP_KILL));
>> +	if (TST_RET == -1)
>> +		tst_res(TFAIL | TTERRNO, "drop CAP_KILL failed");
>> +	else
>> +		drop_flag = 1;
> This flag does not seem to be used anywhere. Can't we simply tst_brk()
> here if the call fails?

Since it has used needs_root flag, I think removing this flag is ok(I 
removed it in verify functions, but forgot to remove it in setup).

Best Regards
Yang Xu



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

* [LTP] [PATCH v2 1/3] syscalls/capset02: Cleanup & convert to new library
  2020-01-10 10:21             ` [LTP] [PATCH v2 1/3] syscalls/capset02: Cleanup & convert to new library Yang Xu
                                 ` (2 preceding siblings ...)
  2020-01-10 14:30               ` [LTP] [PATCH v2 1/3] syscalls/capset02: Cleanup & convert to new library Cyril Hrubis
@ 2020-01-15 13:43               ` Cyril Hrubis
  3 siblings, 0 replies; 22+ messages in thread
From: Cyril Hrubis @ 2020-01-15 13:43 UTC (permalink / raw)
  To: ltp

Hi!
Pushed with minor changes, thanks.

The diff is:

diff --git a/testcases/kernel/syscalls/capset/capset02.c b/testcases/kernel/syscalls/capset/capset02.c
index 15589d462..a6c4f29a0 100644
--- a/testcases/kernel/syscalls/capset/capset02.c
+++ b/testcases/kernel/syscalls/capset/capset02.c
@@ -28,10 +28,11 @@
 #define CAP1 (1 << CAP_NET_RAW | 1 << CAP_CHOWN  | 1 << CAP_SETPCAP)
 #define CAP2 (CAP1 | 1 << CAP_KILL)
 
-static int drop_flag;
 static struct __user_cap_header_struct *header;
 static struct __user_cap_data_struct *data;
 
+static void *bad_addr;
+
 static struct tcase {
        int version;
        int pid;
@@ -63,8 +64,8 @@ static void verify_capset(unsigned int n)
 
        tst_res(TINFO, "%s", tc->message);
 
-       TEST(tst_syscall(__NR_capset, tc->flag - 1 ? header : NULL,
-                               tc->flag - 2 ? data : NULL));
+       TEST(tst_syscall(__NR_capset, tc->flag - 1 ? header : bad_addr,
+                               tc->flag - 2 ? data : bad_addr));
        if (TST_RET == 0) {
                tst_res(TFAIL, "capset() succeed unexpectedly");
                return;
@@ -97,9 +98,9 @@ static void setup(void)
 
        TEST(prctl(PR_CAPBSET_DROP, CAP_KILL));
        if (TST_RET == -1)
-               tst_res(TFAIL | TTERRNO, "drop CAP_KILL failed");
-       else
-               drop_flag = 1;
+               tst_brk(TBROK | TTERRNO, "drop CAP_KILL failed");
+
+       bad_addr = tst_get_bad_addr(NULL);
 }


-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v2 2/3] syscalls/capset03: add new EPERM error test without CAP_SETPCAP
  2020-01-10 10:21               ` [LTP] [PATCH v2 2/3] syscalls/capset03: add new EPERM error test without CAP_SETPCAP Yang Xu
@ 2020-01-15 14:28                 ` Cyril Hrubis
  0 siblings, 0 replies; 22+ messages in thread
From: Cyril Hrubis @ 2020-01-15 14:28 UTC (permalink / raw)
  To: ltp

Hi!
Pushed, thanks.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v2 3/3] syscalls/capset04: add new EPERM error test with vfs cap support
  2020-01-10 10:21               ` [LTP] [PATCH v2 3/3] syscalls/capset04: add new EPERM error test with vfs cap support Yang Xu
@ 2020-01-15 14:28                 ` Cyril Hrubis
  0 siblings, 0 replies; 22+ messages in thread
From: Cyril Hrubis @ 2020-01-15 14:28 UTC (permalink / raw)
  To: ltp

Hi!
I've simplified the code a bit and pushed, thanks.

-- 
Cyril Hrubis
chrubis@suse.cz

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

end of thread, other threads:[~2020-01-15 14:28 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-17 10:12 [LTP] [PATCH v1 0/4] cleanup capset testcase Yang Xu
2019-12-17 10:12 ` [LTP] [PATCH v1 1/4] syscalls/capset01: Cleanup & convert to new library Yang Xu
2020-01-07 13:32   ` Cyril Hrubis
2020-01-08  2:37     ` Yang Xu
2019-12-17 10:12 ` [LTP] [PATCH v1 2/4] syscalls/capset02: " Yang Xu
2019-12-17 10:12 ` [LTP] [PATCH v1 3/4] syscalls/capset03: add new EPERM error test without CAP_SETPCAP Yang Xu
2020-01-07 13:39   ` Cyril Hrubis
2020-01-08  3:19     ` Yang Xu
2020-01-08 11:03       ` Cyril Hrubis
2020-01-09  6:17         ` Yang Xu
2020-01-09 12:41           ` Cyril Hrubis
2020-01-10  5:35             ` Yang Xu
2020-01-10 10:21             ` [LTP] [PATCH v2 1/3] syscalls/capset02: Cleanup & convert to new library Yang Xu
2020-01-10 10:21               ` [LTP] [PATCH v2 2/3] syscalls/capset03: add new EPERM error test without CAP_SETPCAP Yang Xu
2020-01-15 14:28                 ` Cyril Hrubis
2020-01-10 10:21               ` [LTP] [PATCH v2 3/3] syscalls/capset04: add new EPERM error test with vfs cap support Yang Xu
2020-01-15 14:28                 ` Cyril Hrubis
2020-01-10 14:30               ` [LTP] [PATCH v2 1/3] syscalls/capset02: Cleanup & convert to new library Cyril Hrubis
2020-01-13  1:31                 ` Yang Xu
2020-01-15 13:43               ` Cyril Hrubis
2019-12-17 10:12 ` [LTP] [PATCH v3 4/5] syscalls/quotactl05: add project quota test for xfs filesystem Yang Xu
2019-12-17 10:16   ` Yang Xu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.