All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH] syscalls/prctl02: add more error tests
@ 2019-10-25 12:39 Yang Xu
  2019-10-31  8:59 ` [LTP] [PATCH v2] " Yang Xu
  0 siblings, 1 reply; 19+ messages in thread
From: Yang Xu @ 2019-10-25 12:39 UTC (permalink / raw)
  To: ltp

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 include/lapi/prctl.h                      | 10 ++++
 testcases/kernel/syscalls/prctl/prctl02.c | 68 ++++++++++++++++++++---
 2 files changed, 71 insertions(+), 7 deletions(-)

diff --git a/include/lapi/prctl.h b/include/lapi/prctl.h
index 8ee492259..ea52ecac3 100644
--- a/include/lapi/prctl.h
+++ b/include/lapi/prctl.h
@@ -29,6 +29,11 @@
 # define PR_GET_NO_NEW_PRIVS 39
 #endif
 
+#ifndef PR_SET_THP_DISABLE
+# define PR_SET_THP_DISABLE 41
+# define PR_GET_THP_DISABLE 42
+#endif
+
 #ifndef PR_CAP_AMBIENT
 # define PR_CAP_AMBIENT             47
 # define PR_CAP_AMBIENT_IS_SET      1
@@ -37,4 +42,9 @@
 # define PR_CAP_AMBIENT_CLEAR_ALL   4
 #endif
 
+#ifndef PR_GET_SPECULATION_CTRL
+# define PR_GET_SPECULATION_CTRL 52
+# define PR_SET_SPECULATION_CTRL 53
+#endif
+
 #endif /* LAPI_PRCTL_H__ */
diff --git a/testcases/kernel/syscalls/prctl/prctl02.c b/testcases/kernel/syscalls/prctl/prctl02.c
index ec45911fd..8739b4fab 100644
--- a/testcases/kernel/syscalls/prctl/prctl02.c
+++ b/testcases/kernel/syscalls/prctl/prctl02.c
@@ -4,32 +4,77 @@
  *
  * 1) prctl() fails with EINVAL when an invalid value is given for option
  * 2) prctl() fails with EINVAL when option is PR_SET_PDEATHSIG & arg2 is
- * not zero or a valid signal number
+ * not zero or a valid signal number.
+ * 3) prctl() fails with EINVAL when option is PR_SET_DUMPABLE & arg2 is
+ * neither SUID_DUMP_DISABLE nor SUID_DUMP_USER.
+ * 4) prctl() fails with EFAULT when arg2 is an invalid address.
+ * 5) prctl() fails with EFAULT when option is PR_SET_SECCOMP & arg2 is
+ * SECCOMP_MODE_FILTER & arg3 is an invalid address.
+ * 6) prctl() fails with EINVAL when option is PR_SET_TIMING & arg2 is not
+ * not PR_TIMING_STATISTICAL.
+ * 7,8) prctl() fails with EINVAL when option is PR_SET_NO_NEW_PRIVS & arg2
+ * is not equal to 1 or arg3 is nonzero.
+ * 9) prctl() fails with EINVAL when options is PR_GET_NO_NEW_PRIVS & arg2,
+ * arg3, arg4, or arg5 is nonzero.
+ * 10) prctl() fails with EINVAL when options is PR_SET_THP_DISABLE & arg3,
+ * arg4, arg5 is non-zero.
+ * 11) prctl() fails with EINVAL when options is PR_GET_THP_DISABLE & arg2,
+ * arg3, arg4, or arg5 is nonzero.
+ * 12) prctl() fails with EINVAL when options is PR_CAP_AMBIENT & an unused
+ * argument such as arg4 is nonzero.
+ * 13) prctl() fails with EINVAL when option is PR_GET_SPECULATION_CTRL and
+ * unused arguments is nonzero.
+ * 14) prctl() fails with EPERM when option is PR_SET_SECUREBITS and the
+ * caller does not have the CAP_SETPCAP capability.
+ * 15) prctl() fails with EPERM when option is PR_CAPBSET_DROP and the caller
+ * does not have the CAP_SETPCAP capability.
  */
 
 #include <errno.h>
 #include <signal.h>
 #include <sys/prctl.h>
-
+#include "lapi/prctl.h"
+#include "lapi/seccomp.h"
 #include "tst_test.h"
+#include "tst_capability.h"
 
 #define OPTION_INVALID 999
 #define INVALID_ARG 999
-
 static struct tcase {
 	int option;
 	unsigned long arg2;
+	unsigned long arg3;
 	int exp_errno;
+	int bad_addr;
 } tcases[] = {
-	{OPTION_INVALID, 0, EINVAL},
-	{PR_SET_PDEATHSIG, INVALID_ARG, EINVAL},
+	{OPTION_INVALID, 0, 0, EINVAL, 0},
+	{PR_SET_PDEATHSIG, INVALID_ARG, 0, EINVAL, 0},
+	{PR_SET_DUMPABLE, 2, 0, EINVAL, 0},
+	{PR_SET_NAME, 0, 0, EFAULT, 1},
+	{PR_SET_SECCOMP, 2, 0, EFAULT, 1},
+	{PR_SET_TIMING, 1, 0, EINVAL, 0},
+	{PR_SET_NO_NEW_PRIVS, 0, 0, EINVAL, 0},
+	{PR_SET_NO_NEW_PRIVS, 1, 1, EINVAL, 0},
+	{PR_GET_NO_NEW_PRIVS, 1, 0, EINVAL, 0},
+	{PR_SET_THP_DISABLE, 0, 1, EINVAL, 0},
+	{PR_GET_THP_DISABLE, 1, 0, EINVAL, 0},
+	{PR_CAP_AMBIENT, 2, 1, EINVAL, 0},
+	{PR_GET_SPECULATION_CTRL, 1, 0, EINVAL, 0},
+	{PR_SET_SECUREBITS, 0, 0, EPERM, 0},
+	{PR_CAPBSET_DROP, 1, 0, EPERM, 0},
 };
 
 static void verify_prctl(unsigned int n)
 {
 	struct tcase *tc = &tcases[n];
 
-	TEST(prctl(tc->option, tc->arg2));
+	if (tc->bad_addr) {
+		if (tc->arg2)
+			tc->arg3 = (unsigned long)tst_get_bad_addr(NULL);
+		else
+			tc->arg2 = (unsigned long)tst_get_bad_addr(NULL);
+	}
+	TEST(prctl(tc->option, tc->arg2, tc->arg3));
 	if (TST_RET == 0) {
 		tst_res(TFAIL, "prctl() succeeded unexpectedly");
 		return;
@@ -38,7 +83,11 @@ static void verify_prctl(unsigned int n)
 	if (tc->exp_errno == TST_ERR) {
 		tst_res(TPASS | TTERRNO, "prctl() failed as expected");
 	} else {
-		tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
+		if (TST_ERR == ENOSYS)
+			tst_res(TINFO,
+				"This prctl() option is not supported on current system");
+		else
+			tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
 				tst_strerrno(tc->exp_errno));
 	}
 }
@@ -46,4 +95,9 @@ static void verify_prctl(unsigned int n)
 static struct tst_test test = {
 	.tcnt = ARRAY_SIZE(tcases),
 	.test = verify_prctl,
+	.caps = (struct tst_cap []) {
+		TST_CAP(TST_CAP_REQ, CAP_SYS_ADMIN),
+		TST_CAP(TST_CAP_DROP, CAP_SETPCAP),
+		{}
+	},
 };
-- 
2.18.0




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

* [LTP] [PATCH v2] syscalls/prctl02: add more error tests
  2019-10-25 12:39 [LTP] [PATCH] syscalls/prctl02: add more error tests Yang Xu
@ 2019-10-31  8:59 ` Yang Xu
  2019-11-01  8:49   ` Petr Vorel
  0 siblings, 1 reply; 19+ messages in thread
From: Yang Xu @ 2019-10-31  8:59 UTC (permalink / raw)
  To: ltp

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>

------
v1->v2:
1. add EACCES tests
2. remove ENOSYS, if kernel doesn't support option, it reports EINVAL.
 use ltp-prctl.m4 to distinguish.
------
---
 include/lapi/prctl.h                      |  10 +++
 m4/ltp-prctl.m4                           |   3 +-
 testcases/kernel/syscalls/prctl/prctl02.c | 104 ++++++++++++++++++++--
 3 files changed, 110 insertions(+), 7 deletions(-)

diff --git a/include/lapi/prctl.h b/include/lapi/prctl.h
index 8ee492259..ea52ecac3 100644
--- a/include/lapi/prctl.h
+++ b/include/lapi/prctl.h
@@ -29,6 +29,11 @@
 # define PR_GET_NO_NEW_PRIVS 39
 #endif
 
+#ifndef PR_SET_THP_DISABLE
+# define PR_SET_THP_DISABLE 41
+# define PR_GET_THP_DISABLE 42
+#endif
+
 #ifndef PR_CAP_AMBIENT
 # define PR_CAP_AMBIENT             47
 # define PR_CAP_AMBIENT_IS_SET      1
@@ -37,4 +42,9 @@
 # define PR_CAP_AMBIENT_CLEAR_ALL   4
 #endif
 
+#ifndef PR_GET_SPECULATION_CTRL
+# define PR_GET_SPECULATION_CTRL 52
+# define PR_SET_SPECULATION_CTRL 53
+#endif
+
 #endif /* LAPI_PRCTL_H__ */
diff --git a/m4/ltp-prctl.m4 b/m4/ltp-prctl.m4
index e429db8fe..b592789ee 100644
--- a/m4/ltp-prctl.m4
+++ b/m4/ltp-prctl.m4
@@ -4,7 +4,8 @@ dnl Author: Ngie Cooper <yaneurabeya@gmail.com>
 
 AC_DEFUN([LTP_CHECK_PRCTL_SUPPORT],[
 AC_CHECK_HEADERS(sys/prctl.h,[
-	AC_CHECK_DECLS([PR_CAPBSET_DROP, PR_CAPBSET_READ], [],[],[
+	AC_CHECK_DECLS([PR_CAPBSET_DROP, PR_CAPBSET_READ, PR_CAP_AMBIENT,
+PR_SET_NO_NEW_PRIVS, PR_GET_SPECULATION_CTRL, PR_SET_THP_DISABLE], [],[],[
 #include <sys/prctl.h>
 ]) dnl AC_CHECK_DECLS
 ])]
diff --git a/testcases/kernel/syscalls/prctl/prctl02.c b/testcases/kernel/syscalls/prctl/prctl02.c
index ec45911fd..1798c4bd5 100644
--- a/testcases/kernel/syscalls/prctl/prctl02.c
+++ b/testcases/kernel/syscalls/prctl/prctl02.c
@@ -4,32 +4,116 @@
  *
  * 1) prctl() fails with EINVAL when an invalid value is given for option
  * 2) prctl() fails with EINVAL when option is PR_SET_PDEATHSIG & arg2 is
- * not zero or a valid signal number
+ * not zero or a valid signal number.
+ * 3) prctl() fails with EINVAL when option is PR_SET_DUMPABLE & arg2 is
+ * neither SUID_DUMP_DISABLE nor SUID_DUMP_USER.
+ * 4) prctl() fails with EFAULT when arg2 is an invalid address.
+ * 5) prctl() fails with EFAULT when option is PR_SET_SECCOMP & arg2 is
+ * SECCOMP_MODE_FILTER & arg3 is an invalid address.
+ * 6) prctl() fails with EACCES when option is PR_SET_SECCOMP & arg2 is
+ * SECCOMP_MODE_FILTER & the process does not have the CAP_SYS_ADMIN
+ * capability.
+ * 7) prctl() fails with EINVAL when option is PR_SET_TIMING & arg2 is not
+ * not PR_TIMING_STATISTICAL.
+ * 8,9) prctl() fails with EINVAL when option is PR_SET_NO_NEW_PRIVS & arg2
+ * is not equal to 1 or arg3 is nonzero.
+ * 10) prctl() fails with EINVAL when options is PR_GET_NO_NEW_PRIVS & arg2,
+ * arg3, arg4, or arg5 is nonzero.
+ * 11) prctl() fails with EINVAL when options is PR_SET_THP_DISABLE & arg3,
+ * arg4, arg5 is non-zero.
+ * 12) prctl() fails with EINVAL when options is PR_GET_THP_DISABLE & arg2,
+ * arg3, arg4, or arg5 is nonzero.
+ * 13) prctl() fails with EINVAL when options is PR_CAP_AMBIENT & an unused
+ * argument such as arg4 is nonzero.
+ * 14) prctl() fails with EINVAL when option is PR_GET_SPECULATION_CTRL and
+ * unused arguments is nonzero.
+ * 15) prctl() fails with EPERM when option is PR_SET_SECUREBITS and the
+ * caller does not have the CAP_SETPCAP capability.
+ * 16) prctl() fails with EPERM when option is PR_CAPBSET_DROP and the caller
+ * does not have the CAP_SETPCAP capability.
  */
 
 #include <errno.h>
 #include <signal.h>
 #include <sys/prctl.h>
-
+#include <linux/filter.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include "config.h"
+#include "lapi/prctl.h"
+#include "lapi/seccomp.h"
+#include "lapi/syscalls.h"
 #include "tst_test.h"
+#include "tst_capability.h"
 
 #define OPTION_INVALID 999
 #define INVALID_ARG 999
 
+static const struct sock_filter  strict_filter[] = {
+	BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof (struct seccomp_data, nr))),
+
+	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_close, 5, 0),
+	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_exit,  4, 0),
+	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_wait4, 3, 0),
+	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_write, 2, 0),
+	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_clone, 1, 0),
+
+	BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),
+	BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)
+};
+
+static const struct sock_fprog  strict = {
+	.len = (unsigned short)ARRAY_SIZE(strict_filter),
+	.filter = (struct sock_filter *)strict_filter
+};
+
 static struct tcase {
 	int option;
 	unsigned long arg2;
+	unsigned long arg3;
 	int exp_errno;
+	int bad_addr;
 } tcases[] = {
-	{OPTION_INVALID, 0, EINVAL},
-	{PR_SET_PDEATHSIG, INVALID_ARG, EINVAL},
+	{OPTION_INVALID, 0, 0, EINVAL, 0},
+	{PR_SET_PDEATHSIG, INVALID_ARG, 0, EINVAL, 0},
+	{PR_SET_DUMPABLE, 2, 0, EINVAL, 0},
+	{PR_SET_NAME, 0, 0, EFAULT, 1},
+	{PR_SET_SECCOMP, 2, 0, EFAULT, 1},
+	{PR_SET_SECCOMP, 2, 2, EACCES, 0},
+	{PR_SET_TIMING, 1, 0, EINVAL, 0},
+#ifdef HAVE_DECL_PR_SET_NO_NEW_PRIVS
+	{PR_SET_NO_NEW_PRIVS, 0, 0, EINVAL, 0},
+	{PR_SET_NO_NEW_PRIVS, 1, 1, EINVAL, 0},
+	{PR_GET_NO_NEW_PRIVS, 1, 0, EINVAL, 0},
+#endif
+#ifdef HAVE_DECL_PR_SET_THP_DISABLE
+	{PR_SET_THP_DISABLE, 0, 1, EINVAL, 0},
+	{PR_GET_THP_DISABLE, 1, 0, EINVAL, 0},
+#endif
+#ifdef HAVE_DECL_PR_CAP_AMBIENT
+	{PR_CAP_AMBIENT, 2, 1, EINVAL, 0},
+#endif
+#ifdef HAVE_DECL_PR_GET_SPECULATION_CTR
+	{PR_GET_SPECULATION_CTRL, 1, 0, EINVAL, 0},
+#endif
+	{PR_SET_SECUREBITS, 0, 0, EPERM, 0},
+	{PR_CAPBSET_DROP, 1, 0, EPERM, 0},
 };
 
 static void verify_prctl(unsigned int n)
 {
 	struct tcase *tc = &tcases[n];
 
-	TEST(prctl(tc->option, tc->arg2));
+	if (tc->arg3 == 2)
+		tc->arg3 = (unsigned long)&strict;
+	if (tc->bad_addr) {
+		if (tc->arg2)
+			tc->arg3 = (unsigned long)tst_get_bad_addr(NULL);
+		else
+			tc->arg2 = (unsigned long)tst_get_bad_addr(NULL);
+	}
+	TEST(prctl(tc->option, tc->arg2, tc->arg3));
 	if (TST_RET == 0) {
 		tst_res(TFAIL, "prctl() succeeded unexpectedly");
 		return;
@@ -38,7 +122,10 @@ static void verify_prctl(unsigned int n)
 	if (tc->exp_errno == TST_ERR) {
 		tst_res(TPASS | TTERRNO, "prctl() failed as expected");
 	} else {
-		tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
+		if (tc->option == PR_SET_SECCOMP && TST_ERR == EINVAL)
+			tst_res(TCONF, "current system was not built with CONFIG_SECCOMP.");
+		else
+			tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
 				tst_strerrno(tc->exp_errno));
 	}
 }
@@ -46,4 +133,9 @@ static void verify_prctl(unsigned int n)
 static struct tst_test test = {
 	.tcnt = ARRAY_SIZE(tcases),
 	.test = verify_prctl,
+	.caps = (struct tst_cap []) {
+		TST_CAP(TST_CAP_DROP, CAP_SYS_ADMIN),
+		TST_CAP(TST_CAP_DROP, CAP_SETPCAP),
+		{}
+	},
 };
-- 
2.18.0




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

* [LTP] [PATCH v2] syscalls/prctl02: add more error tests
  2019-10-31  8:59 ` [LTP] [PATCH v2] " Yang Xu
@ 2019-11-01  8:49   ` Petr Vorel
  2019-11-01 11:24     ` Yang Xu
  2019-11-01 12:59     ` [LTP] [PATCH v3] " Yang Xu
  0 siblings, 2 replies; 19+ messages in thread
From: Petr Vorel @ 2019-11-01  8:49 UTC (permalink / raw)
  To: ltp

Hi Xu,

> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>

>  static struct tst_test test = {
>  	.tcnt = ARRAY_SIZE(tcases),
>  	.test = verify_prctl,
> +	.caps = (struct tst_cap []) {
> +		TST_CAP(TST_CAP_DROP, CAP_SYS_ADMIN),
> +		TST_CAP(TST_CAP_DROP, CAP_SETPCAP),
This fails on some old distros (Debian stable [1], CentOS 6 [2]),
but also on new (Fedora latest [3]):

undeclared identifier 'CAP_SETPCAP'

Could you please setup travis for your LTP fork and validate builds before
posting to ML?

BTW it'd be nice to have this feature in our patchwork [4], but not sure if this
is available and configurable on our patchwork instance (we don't host it).

Kind regards,
Petr

[1] https://travis-ci.org/pevik/ltp/jobs/605881703
[2] https://travis-ci.org/pevik/ltp/jobs/605881705
[3] https://travis-ci.org/pevik/ltp/jobs/605881704
[4] https://github.com/linux-test-project/ltp/issues/599

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

* [LTP] [PATCH v2] syscalls/prctl02: add more error tests
  2019-11-01  8:49   ` Petr Vorel
@ 2019-11-01 11:24     ` Yang Xu
  2019-11-01 12:59     ` [LTP] [PATCH v3] " Yang Xu
  1 sibling, 0 replies; 19+ messages in thread
From: Yang Xu @ 2019-11-01 11:24 UTC (permalink / raw)
  To: ltp


on 2019/11/01 16:49, Petr Vorel wrote:

> Hi Xu,
>
>> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
>>   static struct tst_test test = {
>>   	.tcnt = ARRAY_SIZE(tcases),
>>   	.test = verify_prctl,
>> +	.caps = (struct tst_cap []) {
>> +		TST_CAP(TST_CAP_DROP, CAP_SYS_ADMIN),
>> +		TST_CAP(TST_CAP_DROP, CAP_SETPCAP),
> This fails on some old distros (Debian stable [1], CentOS 6 [2]),
> but also on new (Fedora latest [3]):
>
> undeclared identifier 'CAP_SETPCAP'
>
> Could you please setup travis for your LTP fork and validate builds before
> posting to ML?

Hi Petr
Ok. I use travis before sending quotactl patches, but I forgot to use it for prctl02.

Sorry. I will test my patches in my ltp forklater.

ps: I add missing linux/capability.h to fix this build error and this is building in my ltp fork.

Thanks
Yang Xu

>
> BTW it'd be nice to have this feature in our patchwork [4], but not sure if this
> is available and configurable on our patchwork instance (we don't host it).
>
> Kind regards,
> Petr
>
> [1] https://travis-ci.org/pevik/ltp/jobs/605881703
> [2] https://travis-ci.org/pevik/ltp/jobs/605881705
> [3] https://travis-ci.org/pevik/ltp/jobs/605881704
> [4] https://github.com/linux-test-project/ltp/issues/599
>
>


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20191101/838008eb/attachment.htm>

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

* [LTP] [PATCH v3] syscalls/prctl02: add more error tests
  2019-11-01  8:49   ` Petr Vorel
  2019-11-01 11:24     ` Yang Xu
@ 2019-11-01 12:59     ` Yang Xu
  2019-11-07 14:54       ` Cyril Hrubis
  1 sibling, 1 reply; 19+ messages in thread
From: Yang Xu @ 2019-11-01 12:59 UTC (permalink / raw)
  To: ltp

------
v2->v3:
1.add missing <linux/capability.h>
------

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 include/lapi/prctl.h                      |  10 +++
 m4/ltp-prctl.m4                           |   3 +-
 testcases/kernel/syscalls/prctl/prctl02.c | 105 ++++++++++++++++++++--
 3 files changed, 111 insertions(+), 7 deletions(-)

diff --git a/include/lapi/prctl.h b/include/lapi/prctl.h
index 8ee492259..ea52ecac3 100644
--- a/include/lapi/prctl.h
+++ b/include/lapi/prctl.h
@@ -29,6 +29,11 @@
 # define PR_GET_NO_NEW_PRIVS 39
 #endif
 
+#ifndef PR_SET_THP_DISABLE
+# define PR_SET_THP_DISABLE 41
+# define PR_GET_THP_DISABLE 42
+#endif
+
 #ifndef PR_CAP_AMBIENT
 # define PR_CAP_AMBIENT             47
 # define PR_CAP_AMBIENT_IS_SET      1
@@ -37,4 +42,9 @@
 # define PR_CAP_AMBIENT_CLEAR_ALL   4
 #endif
 
+#ifndef PR_GET_SPECULATION_CTRL
+# define PR_GET_SPECULATION_CTRL 52
+# define PR_SET_SPECULATION_CTRL 53
+#endif
+
 #endif /* LAPI_PRCTL_H__ */
diff --git a/m4/ltp-prctl.m4 b/m4/ltp-prctl.m4
index e429db8fe..b592789ee 100644
--- a/m4/ltp-prctl.m4
+++ b/m4/ltp-prctl.m4
@@ -4,7 +4,8 @@ dnl Author: Ngie Cooper <yaneurabeya@gmail.com>
 
 AC_DEFUN([LTP_CHECK_PRCTL_SUPPORT],[
 AC_CHECK_HEADERS(sys/prctl.h,[
-	AC_CHECK_DECLS([PR_CAPBSET_DROP, PR_CAPBSET_READ], [],[],[
+	AC_CHECK_DECLS([PR_CAPBSET_DROP, PR_CAPBSET_READ, PR_CAP_AMBIENT,
+PR_SET_NO_NEW_PRIVS, PR_GET_SPECULATION_CTRL, PR_SET_THP_DISABLE], [],[],[
 #include <sys/prctl.h>
 ]) dnl AC_CHECK_DECLS
 ])]
diff --git a/testcases/kernel/syscalls/prctl/prctl02.c b/testcases/kernel/syscalls/prctl/prctl02.c
index ec45911fd..2e0bbf1dc 100644
--- a/testcases/kernel/syscalls/prctl/prctl02.c
+++ b/testcases/kernel/syscalls/prctl/prctl02.c
@@ -4,32 +4,117 @@
  *
  * 1) prctl() fails with EINVAL when an invalid value is given for option
  * 2) prctl() fails with EINVAL when option is PR_SET_PDEATHSIG & arg2 is
- * not zero or a valid signal number
+ * not zero or a valid signal number.
+ * 3) prctl() fails with EINVAL when option is PR_SET_DUMPABLE & arg2 is
+ * neither SUID_DUMP_DISABLE nor SUID_DUMP_USER.
+ * 4) prctl() fails with EFAULT when arg2 is an invalid address.
+ * 5) prctl() fails with EFAULT when option is PR_SET_SECCOMP & arg2 is
+ * SECCOMP_MODE_FILTER & arg3 is an invalid address.
+ * 6) prctl() fails with EACCES when option is PR_SET_SECCOMP & arg2 is
+ * SECCOMP_MODE_FILTER & the process does not have the CAP_SYS_ADMIN
+ * capability.
+ * 7) prctl() fails with EINVAL when option is PR_SET_TIMING & arg2 is not
+ * not PR_TIMING_STATISTICAL.
+ * 8,9) prctl() fails with EINVAL when option is PR_SET_NO_NEW_PRIVS & arg2
+ * is not equal to 1 or arg3 is nonzero.
+ * 10) prctl() fails with EINVAL when options is PR_GET_NO_NEW_PRIVS & arg2,
+ * arg3, arg4, or arg5 is nonzero.
+ * 11) prctl() fails with EINVAL when options is PR_SET_THP_DISABLE & arg3,
+ * arg4, arg5 is non-zero.
+ * 12) prctl() fails with EINVAL when options is PR_GET_THP_DISABLE & arg2,
+ * arg3, arg4, or arg5 is nonzero.
+ * 13) prctl() fails with EINVAL when options is PR_CAP_AMBIENT & an unused
+ * argument such as arg4 is nonzero.
+ * 14) prctl() fails with EINVAL when option is PR_GET_SPECULATION_CTRL and
+ * unused arguments is nonzero.
+ * 15) prctl() fails with EPERM when option is PR_SET_SECUREBITS and the
+ * caller does not have the CAP_SETPCAP capability.
+ * 16) prctl() fails with EPERM when option is PR_CAPBSET_DROP and the caller
+ * does not have the CAP_SETPCAP capability.
  */
 
 #include <errno.h>
 #include <signal.h>
 #include <sys/prctl.h>
-
+#include <linux/filter.h>
+#include <linux/capability.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include "config.h"
+#include "lapi/prctl.h"
+#include "lapi/seccomp.h"
+#include "lapi/syscalls.h"
 #include "tst_test.h"
+#include "tst_capability.h"
 
 #define OPTION_INVALID 999
 #define INVALID_ARG 999
 
+static const struct sock_filter  strict_filter[] = {
+	BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof (struct seccomp_data, nr))),
+
+	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_close, 5, 0),
+	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_exit,  4, 0),
+	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_wait4, 3, 0),
+	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_write, 2, 0),
+	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_clone, 1, 0),
+
+	BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),
+	BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)
+};
+
+static const struct sock_fprog  strict = {
+	.len = (unsigned short)ARRAY_SIZE(strict_filter),
+	.filter = (struct sock_filter *)strict_filter
+};
+
 static struct tcase {
 	int option;
 	unsigned long arg2;
+	unsigned long arg3;
 	int exp_errno;
+	int bad_addr;
 } tcases[] = {
-	{OPTION_INVALID, 0, EINVAL},
-	{PR_SET_PDEATHSIG, INVALID_ARG, EINVAL},
+	{OPTION_INVALID, 0, 0, EINVAL, 0},
+	{PR_SET_PDEATHSIG, INVALID_ARG, 0, EINVAL, 0},
+	{PR_SET_DUMPABLE, 2, 0, EINVAL, 0},
+	{PR_SET_NAME, 0, 0, EFAULT, 1},
+	{PR_SET_SECCOMP, 2, 0, EFAULT, 1},
+	{PR_SET_SECCOMP, 2, 2, EACCES, 0},
+	{PR_SET_TIMING, 1, 0, EINVAL, 0},
+#ifdef HAVE_DECL_PR_SET_NO_NEW_PRIVS
+	{PR_SET_NO_NEW_PRIVS, 0, 0, EINVAL, 0},
+	{PR_SET_NO_NEW_PRIVS, 1, 1, EINVAL, 0},
+	{PR_GET_NO_NEW_PRIVS, 1, 0, EINVAL, 0},
+#endif
+#ifdef HAVE_DECL_PR_SET_THP_DISABLE
+	{PR_SET_THP_DISABLE, 0, 1, EINVAL, 0},
+	{PR_GET_THP_DISABLE, 1, 0, EINVAL, 0},
+#endif
+#ifdef HAVE_DECL_PR_CAP_AMBIENT
+	{PR_CAP_AMBIENT, 2, 1, EINVAL, 0},
+#endif
+#ifdef HAVE_DECL_PR_GET_SPECULATION_CTR
+	{PR_GET_SPECULATION_CTRL, 1, 0, EINVAL, 0},
+#endif
+	{PR_SET_SECUREBITS, 0, 0, EPERM, 0},
+	{PR_CAPBSET_DROP, 1, 0, EPERM, 0},
 };
 
 static void verify_prctl(unsigned int n)
 {
 	struct tcase *tc = &tcases[n];
 
-	TEST(prctl(tc->option, tc->arg2));
+	if (tc->arg3 == 2)
+		tc->arg3 = (unsigned long)&strict;
+	if (tc->bad_addr) {
+		if (tc->arg2)
+			tc->arg3 = (unsigned long)tst_get_bad_addr(NULL);
+		else
+			tc->arg2 = (unsigned long)tst_get_bad_addr(NULL);
+	}
+	TEST(prctl(tc->option, tc->arg2, tc->arg3));
 	if (TST_RET == 0) {
 		tst_res(TFAIL, "prctl() succeeded unexpectedly");
 		return;
@@ -38,7 +123,10 @@ static void verify_prctl(unsigned int n)
 	if (tc->exp_errno == TST_ERR) {
 		tst_res(TPASS | TTERRNO, "prctl() failed as expected");
 	} else {
-		tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
+		if (tc->option == PR_SET_SECCOMP && TST_ERR == EINVAL)
+			tst_res(TCONF, "current system was not built with CONFIG_SECCOMP.");
+		else
+			tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
 				tst_strerrno(tc->exp_errno));
 	}
 }
@@ -46,4 +134,9 @@ static void verify_prctl(unsigned int n)
 static struct tst_test test = {
 	.tcnt = ARRAY_SIZE(tcases),
 	.test = verify_prctl,
+	.caps = (struct tst_cap []) {
+		TST_CAP(TST_CAP_DROP, CAP_SYS_ADMIN),
+		TST_CAP(TST_CAP_DROP, CAP_SETPCAP),
+		{}
+	},
 };
-- 
2.18.0




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

* [LTP] [PATCH v3] syscalls/prctl02: add more error tests
  2019-11-01 12:59     ` [LTP] [PATCH v3] " Yang Xu
@ 2019-11-07 14:54       ` Cyril Hrubis
  2019-11-08 12:12         ` Yang Xu
  0 siblings, 1 reply; 19+ messages in thread
From: Cyril Hrubis @ 2019-11-07 14:54 UTC (permalink / raw)
  To: ltp

Hi!
>  #include <errno.h>
>  #include <signal.h>
>  #include <sys/prctl.h>
> -
> +#include <linux/filter.h>
> +#include <linux/capability.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <stddef.h>
> +#include "config.h"
> +#include "lapi/prctl.h"
> +#include "lapi/seccomp.h"
> +#include "lapi/syscalls.h"
>  #include "tst_test.h"
> +#include "tst_capability.h"
>  
>  #define OPTION_INVALID 999
>  #define INVALID_ARG 999
>  
> +static const struct sock_filter  strict_filter[] = {
> +	BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof (struct seccomp_data, nr))),
> +
> +	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_close, 5, 0),
> +	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_exit,  4, 0),
> +	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_wait4, 3, 0),
> +	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_write, 2, 0),
> +	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_clone, 1, 0),
> +
> +	BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),
> +	BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)
> +};
> +
> +static const struct sock_fprog  strict = {
> +	.len = (unsigned short)ARRAY_SIZE(strict_filter),
> +	.filter = (struct sock_filter *)strict_filter
> +};

We do have the exact same bytecode in the prctl04.c, can we put it to a
header and include it in both tests?

Or alternatively do we need more than just one-liner with
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW) here?

>  static struct tcase {
>  	int option;
>  	unsigned long arg2;
> +	unsigned long arg3;
>  	int exp_errno;
> +	int bad_addr;
>  } tcases[] = {
> -	{OPTION_INVALID, 0, EINVAL},
> -	{PR_SET_PDEATHSIG, INVALID_ARG, EINVAL},
> +	{OPTION_INVALID, 0, 0, EINVAL, 0},
> +	{PR_SET_PDEATHSIG, INVALID_ARG, 0, EINVAL, 0},
> +	{PR_SET_DUMPABLE, 2, 0, EINVAL, 0},
> +	{PR_SET_NAME, 0, 0, EFAULT, 1},
> +	{PR_SET_SECCOMP, 2, 0, EFAULT, 1},
> +	{PR_SET_SECCOMP, 2, 2, EACCES, 0},
> +	{PR_SET_TIMING, 1, 0, EINVAL, 0},
> +#ifdef HAVE_DECL_PR_SET_NO_NEW_PRIVS
> +	{PR_SET_NO_NEW_PRIVS, 0, 0, EINVAL, 0},
> +	{PR_SET_NO_NEW_PRIVS, 1, 1, EINVAL, 0},
> +	{PR_GET_NO_NEW_PRIVS, 1, 0, EINVAL, 0},
> +#endif
> +#ifdef HAVE_DECL_PR_SET_THP_DISABLE
> +	{PR_SET_THP_DISABLE, 0, 1, EINVAL, 0},
> +	{PR_GET_THP_DISABLE, 1, 0, EINVAL, 0},
> +#endif
> +#ifdef HAVE_DECL_PR_CAP_AMBIENT
> +	{PR_CAP_AMBIENT, 2, 1, EINVAL, 0},
> +#endif
> +#ifdef HAVE_DECL_PR_GET_SPECULATION_CTR
> +	{PR_GET_SPECULATION_CTRL, 1, 0, EINVAL, 0},
> +#endif
> +	{PR_SET_SECUREBITS, 0, 0, EPERM, 0},
> +	{PR_CAPBSET_DROP, 1, 0, EPERM, 0},
>  };
>  
>  static void verify_prctl(unsigned int n)
>  {
>  	struct tcase *tc = &tcases[n];
>  
> -	TEST(prctl(tc->option, tc->arg2));
> +	if (tc->arg3 == 2)
> +		tc->arg3 = (unsigned long)&strict;
> +	if (tc->bad_addr) {
> +		if (tc->arg2)
> +			tc->arg3 = (unsigned long)tst_get_bad_addr(NULL);
> +		else
> +			tc->arg2 = (unsigned long)tst_get_bad_addr(NULL);
> +	}

I do not like this hackery, can't we just change the test to use
pointers to pointers and initialize global variables in the test setup
as we usually do?

> +	TEST(prctl(tc->option, tc->arg2, tc->arg3));
>  	if (TST_RET == 0) {
>  		tst_res(TFAIL, "prctl() succeeded unexpectedly");
>  		return;
> @@ -38,7 +123,10 @@ static void verify_prctl(unsigned int n)
>  	if (tc->exp_errno == TST_ERR) {
>  		tst_res(TPASS | TTERRNO, "prctl() failed as expected");
>  	} else {
> -		tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
> +		if (tc->option == PR_SET_SECCOMP && TST_ERR == EINVAL)
> +			tst_res(TCONF, "current system was not built with CONFIG_SECCOMP.");
> +		else
> +			tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
>  				tst_strerrno(tc->exp_errno));
>  	}
>  }
> @@ -46,4 +134,9 @@ static void verify_prctl(unsigned int n)
>  static struct tst_test test = {
>  	.tcnt = ARRAY_SIZE(tcases),
>  	.test = verify_prctl,
> +	.caps = (struct tst_cap []) {
> +		TST_CAP(TST_CAP_DROP, CAP_SYS_ADMIN),
> +		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] 19+ messages in thread

* [LTP] [PATCH v3] syscalls/prctl02: add more error tests
  2019-11-07 14:54       ` Cyril Hrubis
@ 2019-11-08 12:12         ` Yang Xu
  2019-11-08 13:20           ` Yang Xu
  0 siblings, 1 reply; 19+ messages in thread
From: Yang Xu @ 2019-11-08 12:12 UTC (permalink / raw)
  To: ltp


on 2019/11/07 22:54, Cyril Hrubis wrote:

> Hi!
>>   #include <errno.h>
>>   #include <signal.h>
>>   #include <sys/prctl.h>
>> -
>> +#include <linux/filter.h>
>> +#include <linux/capability.h>
>> +#include <unistd.h>
>> +#include <stdlib.h>
>> +#include <stddef.h>
>> +#include "config.h"
>> +#include "lapi/prctl.h"
>> +#include "lapi/seccomp.h"
>> +#include "lapi/syscalls.h"
>>   #include "tst_test.h"
>> +#include "tst_capability.h"
>>   
>>   #define OPTION_INVALID 999
>>   #define INVALID_ARG 999
>>   
>> +static const struct sock_filter  strict_filter[] = {
>> +	BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof (struct seccomp_data, nr))),
>> +
>> +	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_close, 5, 0),
>> +	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_exit,  4, 0),
>> +	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_wait4, 3, 0),
>> +	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_write, 2, 0),
>> +	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_clone, 1, 0),
>> +
>> +	BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),
>> +	BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)
>> +};
>> +
>> +static const struct sock_fprog  strict = {
>> +	.len = (unsigned short)ARRAY_SIZE(strict_filter),
>> +	.filter = (struct sock_filter *)strict_filter
>> +};
> We do have the exact same bytecode in the prctl04.c, can we put it to a
> header and include it in both tests?
>
> Or alternatively do we need more than just one-liner with
> BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW) here?

we only need one-liner with BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW) here.

>
>>   static struct tcase {
>>   	int option;
>>   	unsigned long arg2;
>> +	unsigned long arg3;
>>   	int exp_errno;
>> +	int bad_addr;
>>   } tcases[] = {
>> -	{OPTION_INVALID, 0, EINVAL},
>> -	{PR_SET_PDEATHSIG, INVALID_ARG, EINVAL},
>> +	{OPTION_INVALID, 0, 0, EINVAL, 0},
>> +	{PR_SET_PDEATHSIG, INVALID_ARG, 0, EINVAL, 0},
>> +	{PR_SET_DUMPABLE, 2, 0, EINVAL, 0},
>> +	{PR_SET_NAME, 0, 0, EFAULT, 1},
>> +	{PR_SET_SECCOMP, 2, 0, EFAULT, 1},
>> +	{PR_SET_SECCOMP, 2, 2, EACCES, 0},
>> +	{PR_SET_TIMING, 1, 0, EINVAL, 0},
>> +#ifdef HAVE_DECL_PR_SET_NO_NEW_PRIVS
>> +	{PR_SET_NO_NEW_PRIVS, 0, 0, EINVAL, 0},
>> +	{PR_SET_NO_NEW_PRIVS, 1, 1, EINVAL, 0},
>> +	{PR_GET_NO_NEW_PRIVS, 1, 0, EINVAL, 0},
>> +#endif
>> +#ifdef HAVE_DECL_PR_SET_THP_DISABLE
>> +	{PR_SET_THP_DISABLE, 0, 1, EINVAL, 0},
>> +	{PR_GET_THP_DISABLE, 1, 0, EINVAL, 0},
>> +#endif
>> +#ifdef HAVE_DECL_PR_CAP_AMBIENT
>> +	{PR_CAP_AMBIENT, 2, 1, EINVAL, 0},
>> +#endif
>> +#ifdef HAVE_DECL_PR_GET_SPECULATION_CTR
>> +	{PR_GET_SPECULATION_CTRL, 1, 0, EINVAL, 0},
>> +#endif
>> +	{PR_SET_SECUREBITS, 0, 0, EPERM, 0},
>> +	{PR_CAPBSET_DROP, 1, 0, EPERM, 0},
>>   };
>>   
>>   static void verify_prctl(unsigned int n)
>>   {
>>   	struct tcase *tc = &tcases[n];
>>   
>> -	TEST(prctl(tc->option, tc->arg2));
>> +	if (tc->arg3 == 2)
>> +		tc->arg3 = (unsigned long)&strict;
>> +	if (tc->bad_addr) {
>> +		if (tc->arg2)
>> +			tc->arg3 = (unsigned long)tst_get_bad_addr(NULL);
>> +		else
>> +			tc->arg2 = (unsigned long)tst_get_bad_addr(NULL);
>> +	}
> I do not like this hackery, can't we just change the test to use
> pointers to pointers and initialize global variables in the test setup
> as we usually do?

Ok. I will do it as we usually do.

>
>> +	TEST(prctl(tc->option, tc->arg2, tc->arg3));
>>   	if (TST_RET == 0) {
>>   		tst_res(TFAIL, "prctl() succeeded unexpectedly");
>>   		return;
>> @@ -38,7 +123,10 @@ static void verify_prctl(unsigned int n)
>>   	if (tc->exp_errno == TST_ERR) {
>>   		tst_res(TPASS | TTERRNO, "prctl() failed as expected");
>>   	} else {
>> -		tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
>> +		if (tc->option == PR_SET_SECCOMP && TST_ERR == EINVAL)
>> +			tst_res(TCONF, "current system was not built with CONFIG_SECCOMP.");
>> +		else
>> +			tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
>>   				tst_strerrno(tc->exp_errno));
>>   	}
>>   }
>> @@ -46,4 +134,9 @@ static void verify_prctl(unsigned int n)
>>   static struct tst_test test = {
>>   	.tcnt = ARRAY_SIZE(tcases),
>>   	.test = verify_prctl,
>> +	.caps = (struct tst_cap []) {
>> +		TST_CAP(TST_CAP_DROP, CAP_SYS_ADMIN),
>> +		TST_CAP(TST_CAP_DROP, CAP_SETPCAP),
>> +		{}
>> +	},
>>   };
>> -- 
>> 2.18.0
>>
>>
>>
>>
>> -- 
>> Mailing list info: https://lists.linux.it/listinfo/ltp


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20191108/19aa2243/attachment.htm>

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

* [LTP] [PATCH v3] syscalls/prctl02: add more error tests
  2019-11-08 12:12         ` Yang Xu
@ 2019-11-08 13:20           ` Yang Xu
  2019-11-08 14:24             ` Cyril Hrubis
  0 siblings, 1 reply; 19+ messages in thread
From: Yang Xu @ 2019-11-08 13:20 UTC (permalink / raw)
  To: ltp


on 2019/11/08 20:12, Yang Xu wrote:

>
> on 2019/11/07 22:54, Cyril Hrubis wrote:
>> Hi!
>>>   #include <errno.h>
>>>   #include <signal.h>
>>>   #include <sys/prctl.h>
>>> -
>>> +#include <linux/filter.h>
>>> +#include <linux/capability.h>
>>> +#include <unistd.h>
>>> +#include <stdlib.h>
>>> +#include <stddef.h>
>>> +#include "config.h"
>>> +#include "lapi/prctl.h"
>>> +#include "lapi/seccomp.h"
>>> +#include "lapi/syscalls.h"
>>>   #include "tst_test.h"
>>> +#include "tst_capability.h"
>>>   
>>>   #define OPTION_INVALID 999
>>>   #define INVALID_ARG 999
>>>   
>>> +static const struct sock_filter  strict_filter[] = {
>>> +	BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof (struct seccomp_data, nr))),
>>> +
>>> +	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_close, 5, 0),
>>> +	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_exit,  4, 0),
>>> +	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_wait4, 3, 0),
>>> +	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_write, 2, 0),
>>> +	BPF_JUMP(BPF_JMP | BPF_JEQ, __NR_clone, 1, 0),
>>> +
>>> +	BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),
>>> +	BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)
>>> +};
>>> +
>>> +static const struct sock_fprog  strict = {
>>> +	.len = (unsigned short)ARRAY_SIZE(strict_filter),
>>> +	.filter = (struct sock_filter *)strict_filter
>>> +};
>> We do have the exact same bytecode in the prctl04.c, can we put it to a
>> header and include it in both tests?
>>
>> Or alternatively do we need more than just one-liner with
>> BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW) here?
> we only need one-liner with BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW) here.
>>>   static struct tcase {
>>>   	int option;
>>>   	unsigned long arg2;
>>> +	unsigned long arg3;
>>>   	int exp_errno;
>>> +	int bad_addr;
>>>   } tcases[] = {
>>> -	{OPTION_INVALID, 0, EINVAL},
>>> -	{PR_SET_PDEATHSIG, INVALID_ARG, EINVAL},
>>> +	{OPTION_INVALID, 0, 0, EINVAL, 0},
>>> +	{PR_SET_PDEATHSIG, INVALID_ARG, 0, EINVAL, 0},
>>> +	{PR_SET_DUMPABLE, 2, 0, EINVAL, 0},
>>> +	{PR_SET_NAME, 0, 0, EFAULT, 1},
>>> +	{PR_SET_SECCOMP, 2, 0, EFAULT, 1},
>>> +	{PR_SET_SECCOMP, 2, 2, EACCES, 0},
>>> +	{PR_SET_TIMING, 1, 0, EINVAL, 0},
>>> +#ifdef HAVE_DECL_PR_SET_NO_NEW_PRIVS
>>> +	{PR_SET_NO_NEW_PRIVS, 0, 0, EINVAL, 0},
>>> +	{PR_SET_NO_NEW_PRIVS, 1, 1, EINVAL, 0},
>>> +	{PR_GET_NO_NEW_PRIVS, 1, 0, EINVAL, 0},
>>> +#endif
>>> +#ifdef HAVE_DECL_PR_SET_THP_DISABLE
>>> +	{PR_SET_THP_DISABLE, 0, 1, EINVAL, 0},
>>> +	{PR_GET_THP_DISABLE, 1, 0, EINVAL, 0},
>>> +#endif
>>> +#ifdef HAVE_DECL_PR_CAP_AMBIENT
>>> +	{PR_CAP_AMBIENT, 2, 1, EINVAL, 0},
>>> +#endif
>>> +#ifdef HAVE_DECL_PR_GET_SPECULATION_CTR
>>> +	{PR_GET_SPECULATION_CTRL, 1, 0, EINVAL, 0},
>>> +#endif
>>> +	{PR_SET_SECUREBITS, 0, 0, EPERM, 0},
>>> +	{PR_CAPBSET_DROP, 1, 0, EPERM, 0},
>>>   };
>>>   
>>>   static void verify_prctl(unsigned int n)
>>>   {
>>>   	struct tcase *tc = &tcases[n];
>>>   
>>> -	TEST(prctl(tc->option, tc->arg2));
>>> +	if (tc->arg3 == 2)
>>> +		tc->arg3 = (unsigned long)&strict;
>>> +	if (tc->bad_addr) {
>>> +		if (tc->arg2)
>>> +			tc->arg3 = (unsigned long)tst_get_bad_addr(NULL);
>>> +		else
>>> +			tc->arg2 = (unsigned long)tst_get_bad_addr(NULL);
>>> +	}
>> I do not like this hackery, can't we just change the test to use
>> pointers to pointers and initialize global variables in the test setup
>> as we usually do?
> Ok. I will do it as we usually do.

 ?I think about it again. The argument of prctl is all unsigned long type. Do we need to use
pointers to pointers? Or, move this code to setup function like above?

>>> +	TEST(prctl(tc->option, tc->arg2, tc->arg3));
>>>   	if (TST_RET == 0) {
>>>   		tst_res(TFAIL, "prctl() succeeded unexpectedly");
>>>   		return;
>>> @@ -38,7 +123,10 @@ static void verify_prctl(unsigned int n)
>>>   	if (tc->exp_errno == TST_ERR) {
>>>   		tst_res(TPASS | TTERRNO, "prctl() failed as expected");
>>>   	} else {
>>> -		tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
>>> +		if (tc->option == PR_SET_SECCOMP && TST_ERR == EINVAL)
>>> +			tst_res(TCONF, "current system was not built with CONFIG_SECCOMP.");
>>> +		else
>>> +			tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
>>>   				tst_strerrno(tc->exp_errno));
>>>   	}
>>>   }
>>> @@ -46,4 +134,9 @@ static void verify_prctl(unsigned int n)
>>>   static struct tst_test test = {
>>>   	.tcnt = ARRAY_SIZE(tcases),
>>>   	.test = verify_prctl,
>>> +	.caps = (struct tst_cap []) {
>>> +		TST_CAP(TST_CAP_DROP, CAP_SYS_ADMIN),
>>> +		TST_CAP(TST_CAP_DROP, CAP_SETPCAP),
>>> +		{}
>>> +	},
>>>   };
>>> -- 
>>> 2.18.0
>>>
>>>
>>>
>>>
>>> -- 
>>> Mailing list info:https://lists.linux.it/listinfo/ltp
>


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20191108/5a18bc04/attachment-0001.htm>

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

* [LTP] [PATCH v3] syscalls/prctl02: add more error tests
  2019-11-08 13:20           ` Yang Xu
@ 2019-11-08 14:24             ` Cyril Hrubis
  2019-11-11  8:59               ` [LTP] [PATCH v4] " Yang Xu
  0 siblings, 1 reply; 19+ messages in thread
From: Cyril Hrubis @ 2019-11-08 14:24 UTC (permalink / raw)
  To: ltp

Hi!
> > Ok. I will do it as we usually do.
> 
>  ??I think about it again. The argument of prctl is all unsigned long type. Do we need to use
> pointers to pointers??? Or, move this code to setup function like above?

Just pointer to unsigned long and do the cast in the test setup as:

static unsigned long bad_addr;

static struct tcase = {
	...
	unsigned long *arg3;
	...
} tcases[] = {
	...
	{..., &bad_addr, ...},
	...
}

static void setup(void)
{
	invalid_addr = (unigned long)tst_get_bad_addr();
}

Then call it as prctl(..., *tc->arg3).

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v4] syscalls/prctl02: add more error tests
  2019-11-08 14:24             ` Cyril Hrubis
@ 2019-11-11  8:59               ` Yang Xu
  2019-11-11 16:31                 ` Cyril Hrubis
  0 siblings, 1 reply; 19+ messages in thread
From: Yang Xu @ 2019-11-11  8:59 UTC (permalink / raw)
  To: ltp

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 include/lapi/prctl.h                      |  10 ++
 m4/ltp-prctl.m4                           |   3 +-
 testcases/kernel/syscalls/prctl/prctl02.c | 106 ++++++++++++++++++++--
 3 files changed, 109 insertions(+), 10 deletions(-)

diff --git a/include/lapi/prctl.h b/include/lapi/prctl.h
index 0b4e196c3..4499df030 100644
--- a/include/lapi/prctl.h
+++ b/include/lapi/prctl.h
@@ -34,6 +34,11 @@
 # define PR_GET_NO_NEW_PRIVS 39
 #endif
 
+#ifndef PR_SET_THP_DISABLE
+# define PR_SET_THP_DISABLE 41
+# define PR_GET_THP_DISABLE 42
+#endif
+
 #ifndef PR_CAP_AMBIENT
 # define PR_CAP_AMBIENT             47
 # define PR_CAP_AMBIENT_IS_SET      1
@@ -42,4 +47,9 @@
 # define PR_CAP_AMBIENT_CLEAR_ALL   4
 #endif
 
+#ifndef PR_GET_SPECULATION_CTRL
+# define PR_GET_SPECULATION_CTRL 52
+# define PR_SET_SPECULATION_CTRL 53
+#endif
+
 #endif /* LAPI_PRCTL_H__ */
diff --git a/m4/ltp-prctl.m4 b/m4/ltp-prctl.m4
index e429db8fe..b592789ee 100644
--- a/m4/ltp-prctl.m4
+++ b/m4/ltp-prctl.m4
@@ -4,7 +4,8 @@ dnl Author: Ngie Cooper <yaneurabeya@gmail.com>
 
 AC_DEFUN([LTP_CHECK_PRCTL_SUPPORT],[
 AC_CHECK_HEADERS(sys/prctl.h,[
-	AC_CHECK_DECLS([PR_CAPBSET_DROP, PR_CAPBSET_READ], [],[],[
+	AC_CHECK_DECLS([PR_CAPBSET_DROP, PR_CAPBSET_READ, PR_CAP_AMBIENT,
+PR_SET_NO_NEW_PRIVS, PR_GET_SPECULATION_CTRL, PR_SET_THP_DISABLE], [],[],[
 #include <sys/prctl.h>
 ]) dnl AC_CHECK_DECLS
 ])]
diff --git a/testcases/kernel/syscalls/prctl/prctl02.c b/testcases/kernel/syscalls/prctl/prctl02.c
index ec45911fd..d266dda3c 100644
--- a/testcases/kernel/syscalls/prctl/prctl02.c
+++ b/testcases/kernel/syscalls/prctl/prctl02.c
@@ -4,46 +4,134 @@
  *
  * 1) prctl() fails with EINVAL when an invalid value is given for option
  * 2) prctl() fails with EINVAL when option is PR_SET_PDEATHSIG & arg2 is
- * not zero or a valid signal number
+ * not zero or a valid signal number.
+ * 3) prctl() fails with EINVAL when option is PR_SET_DUMPABLE & arg2 is
+ * neither SUID_DUMP_DISABLE nor SUID_DUMP_USER.
+ * 4) prctl() fails with EFAULT when arg2 is an invalid address.
+ * 5) prctl() fails with EFAULT when option is PR_SET_SECCOMP & arg2 is
+ * SECCOMP_MODE_FILTER & arg3 is an invalid address.
+ * 6) prctl() fails with EACCES when option is PR_SET_SECCOMP & arg2 is
+ * SECCOMP_MODE_FILTER & the process does not have the CAP_SYS_ADMIN
+ * capability.
+ * 7) prctl() fails with EINVAL when option is PR_SET_TIMING & arg2 is not
+ * not PR_TIMING_STATISTICAL.
+ * 8,9) prctl() fails with EINVAL when option is PR_SET_NO_NEW_PRIVS & arg2
+ * is not equal to 1 or arg3 is nonzero.
+ * 10) prctl() fails with EINVAL when options is PR_GET_NO_NEW_PRIVS & arg2,
+ * arg3, arg4, or arg5 is nonzero.
+ * 11) prctl() fails with EINVAL when options is PR_SET_THP_DISABLE & arg3,
+ * arg4, arg5 is non-zero.
+ * 12) prctl() fails with EINVAL when options is PR_GET_THP_DISABLE & arg2,
+ * arg3, arg4, or arg5 is nonzero.
+ * 13) prctl() fails with EINVAL when options is PR_CAP_AMBIENT & an unused
+ * argument such as arg4 is nonzero.
+ * 14) prctl() fails with EINVAL when option is PR_GET_SPECULATION_CTRL and
+ * unused arguments is nonzero.
+ * 15) prctl() fails with EPERM when option is PR_SET_SECUREBITS and the
+ * caller does not have the CAP_SETPCAP capability.
+ * 16) prctl() fails with EPERM when option is PR_CAPBSET_DROP and the caller
+ * does not have the CAP_SETPCAP capability.
  */
 
 #include <errno.h>
 #include <signal.h>
 #include <sys/prctl.h>
-
+#include <linux/filter.h>
+#include <linux/capability.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include "config.h"
+#include "lapi/prctl.h"
+#include "lapi/seccomp.h"
+#include "lapi/syscalls.h"
 #include "tst_test.h"
+#include "tst_capability.h"
 
 #define OPTION_INVALID 999
-#define INVALID_ARG 999
+
+static const struct sock_filter  strict_filter[] = {
+	BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)
+};
+
+static const struct sock_fprog strict = {
+	.len = (unsigned short)ARRAY_SIZE(strict_filter),
+	.filter = (struct sock_filter *)strict_filter
+};
+
+static const struct sock_fprog *strict_addr = &strict;
+
+static unsigned long bad_addr;
+static unsigned long num_0;
+static unsigned long num_1 = 1;
+static unsigned long num_2 = 2;
+static unsigned long num_invalid = 999;
 
 static struct tcase {
 	int option;
-	unsigned long arg2;
+	unsigned long *arg2;
+	unsigned long *arg3;
 	int exp_errno;
 } tcases[] = {
-	{OPTION_INVALID, 0, EINVAL},
-	{PR_SET_PDEATHSIG, INVALID_ARG, EINVAL},
+	{OPTION_INVALID, &num_1, &num_0, EINVAL},
+	{PR_SET_PDEATHSIG, &num_invalid, &num_0, EINVAL},
+	{PR_SET_DUMPABLE, &num_2, &num_0, EINVAL},
+	{PR_SET_NAME, &bad_addr, &num_0, EFAULT},
+	{PR_SET_SECCOMP, &num_2, &bad_addr, EFAULT},
+	{PR_SET_SECCOMP, &num_2, &strict_addr, EACCES},
+	{PR_SET_TIMING, &num_1, &num_0, EINVAL},
+#ifdef HAVE_DECL_PR_SET_NO_NEW_PRIVS
+	{PR_SET_NO_NEW_PRIVS, &num_0, &num_0, EINVAL},
+	{PR_SET_NO_NEW_PRIVS, &num_1, &num_0, EINVAL},
+	{PR_GET_NO_NEW_PRIVS, &num_1, &num_0, EINVAL},
+#endif
+#ifdef HAVE_DECL_PR_SET_THP_DISABLE
+	{PR_SET_THP_DISABLE, &num_0, &num_1, EINVAL},
+	{PR_GET_THP_DISABLE, &num_1, &num_1, EINVAL},
+#endif
+#ifdef HAVE_DECL_PR_CAP_AMBIENT
+	{PR_CAP_AMBIENT, &num_2, &num_1, EINVAL},
+#endif
+#ifdef HAVE_DECL_PR_GET_SPECULATION_CTRL
+	{PR_GET_SPECULATION_CTRL, &num_1, &num_0, EINVAL},
+#endif
+	{PR_SET_SECUREBITS, &num_0, &num_0, EPERM},
+	{PR_CAPBSET_DROP, &num_1, &num_0, EPERM},
 };
 
 static void verify_prctl(unsigned int n)
 {
 	struct tcase *tc = &tcases[n];
 
-	TEST(prctl(tc->option, tc->arg2));
+	TEST(prctl(tc->option, *tc->arg2, *tc->arg3));
 	if (TST_RET == 0) {
 		tst_res(TFAIL, "prctl() succeeded unexpectedly");
 		return;
 	}
 
 	if (tc->exp_errno == TST_ERR) {
-		tst_res(TPASS | TTERRNO, "prctl() failed as expected");
+		tst_res(TPASS | TTERRNO, "prctl() %d failed as expected", tc->option);
 	} else {
-		tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
+		if (tc->option == PR_SET_SECCOMP && TST_ERR == EINVAL)
+			tst_res(TCONF, "current system was not built with CONFIG_SECCOMP.");
+		else
+			tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
 				tst_strerrno(tc->exp_errno));
 	}
 }
 
+static void setup(void)
+{
+	bad_addr = (unsigned long)tst_get_bad_addr(NULL);
+}
+
 static struct tst_test test = {
+	.setup = setup,
 	.tcnt = ARRAY_SIZE(tcases),
 	.test = verify_prctl,
+	.caps = (struct tst_cap []) {
+		TST_CAP(TST_CAP_DROP, CAP_SYS_ADMIN),
+		TST_CAP(TST_CAP_DROP, CAP_SETPCAP),
+		{}
+	},
 };
-- 
2.18.0




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

* [LTP] [PATCH v4] syscalls/prctl02: add more error tests
  2019-11-11  8:59               ` [LTP] [PATCH v4] " Yang Xu
@ 2019-11-11 16:31                 ` Cyril Hrubis
  2019-11-12  3:02                   ` Yang Xu
  0 siblings, 1 reply; 19+ messages in thread
From: Cyril Hrubis @ 2019-11-11 16:31 UTC (permalink / raw)
  To: ltp

Hi!
> +static const struct sock_fprog strict = {
> +	.len = (unsigned short)ARRAY_SIZE(strict_filter),
> +	.filter = (struct sock_filter *)strict_filter
> +};
> +
> +static const struct sock_fprog *strict_addr = &strict;

This should be:

static unsigned long strict_addr = (unsigned long)&strict;

> +static unsigned long bad_addr;
> +static unsigned long num_0;
> +static unsigned long num_1 = 1;
> +static unsigned long num_2 = 2;
> +static unsigned long num_invalid = 999;
>  
>  static struct tcase {
>  	int option;
> -	unsigned long arg2;
> +	unsigned long *arg2;
> +	unsigned long *arg3;
>  	int exp_errno;
>  } tcases[] = {
> -	{OPTION_INVALID, 0, EINVAL},
> -	{PR_SET_PDEATHSIG, INVALID_ARG, EINVAL},
> +	{OPTION_INVALID, &num_1, &num_0, EINVAL},
> +	{PR_SET_PDEATHSIG, &num_invalid, &num_0, EINVAL},
> +	{PR_SET_DUMPABLE, &num_2, &num_0, EINVAL},
> +	{PR_SET_NAME, &bad_addr, &num_0, EFAULT},
> +	{PR_SET_SECCOMP, &num_2, &bad_addr, EFAULT},
> +	{PR_SET_SECCOMP, &num_2, &strict_addr, EACCES},
> +	{PR_SET_TIMING, &num_1, &num_0, EINVAL},
> +#ifdef HAVE_DECL_PR_SET_NO_NEW_PRIVS
> +	{PR_SET_NO_NEW_PRIVS, &num_0, &num_0, EINVAL},
> +	{PR_SET_NO_NEW_PRIVS, &num_1, &num_0, EINVAL},
> +	{PR_GET_NO_NEW_PRIVS, &num_1, &num_0, EINVAL},
> +#endif
> +#ifdef HAVE_DECL_PR_SET_THP_DISABLE
> +	{PR_SET_THP_DISABLE, &num_0, &num_1, EINVAL},
> +	{PR_GET_THP_DISABLE, &num_1, &num_1, EINVAL},
> +#endif
> +#ifdef HAVE_DECL_PR_CAP_AMBIENT
> +	{PR_CAP_AMBIENT, &num_2, &num_1, EINVAL},
> +#endif
> +#ifdef HAVE_DECL_PR_GET_SPECULATION_CTRL
> +	{PR_GET_SPECULATION_CTRL, &num_1, &num_0, EINVAL},
> +#endif

Why the ifdefs, you have even added a fallback definitions into the lapi
header?

The usuall way how to deal with these is to:

1) Add fallback definitions to lapi
2) Ensure these tests does not fail on older kernels

   We do expect EINVAL in these cases anyways, which is what we would
   get if the prctl() option is unknown to the kernel anyways, so here
   we can just get rid of these ifdefs and things should work fine.

> +	{PR_SET_SECUREBITS, &num_0, &num_0, EPERM},
> +	{PR_CAPBSET_DROP, &num_1, &num_0, EPERM},
>  };
>  
>  static void verify_prctl(unsigned int n)
>  {
>  	struct tcase *tc = &tcases[n];
>  
> -	TEST(prctl(tc->option, tc->arg2));
> +	TEST(prctl(tc->option, *tc->arg2, *tc->arg3));
>  	if (TST_RET == 0) {
>  		tst_res(TFAIL, "prctl() succeeded unexpectedly");
>  		return;
>  	}
>  
>  	if (tc->exp_errno == TST_ERR) {
> -		tst_res(TPASS | TTERRNO, "prctl() failed as expected");
> +		tst_res(TPASS | TTERRNO, "prctl() %d failed as expected", tc->option);
>  	} else {
> -		tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
> +		if (tc->option == PR_SET_SECCOMP && TST_ERR == EINVAL)
> +			tst_res(TCONF, "current system was not built with CONFIG_SECCOMP.");
> +		else
> +			tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
>  				tst_strerrno(tc->exp_errno));
>  	}
>  }
>  
> +static void setup(void)
> +{
> +	bad_addr = (unsigned long)tst_get_bad_addr(NULL);
> +}
> +
>  static struct tst_test test = {
> +	.setup = setup,
>  	.tcnt = ARRAY_SIZE(tcases),
>  	.test = verify_prctl,
> +	.caps = (struct tst_cap []) {
> +		TST_CAP(TST_CAP_DROP, CAP_SYS_ADMIN),
> +		TST_CAP(TST_CAP_DROP, CAP_SETPCAP),
> +		{}
> +	},
>  };
> -- 
> 2.18.0
> 
> 
> 

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v4] syscalls/prctl02: add more error tests
  2019-11-11 16:31                 ` Cyril Hrubis
@ 2019-11-12  3:02                   ` Yang Xu
       [not found]                     ` <5DCA5206.3040508@cn.fujitsu.com>
  2019-11-12 10:10                     ` [LTP] [PATCH v4] " Cyril Hrubis
  0 siblings, 2 replies; 19+ messages in thread
From: Yang Xu @ 2019-11-12  3:02 UTC (permalink / raw)
  To: ltp


on 2019/11/12 0:31, Cyril Hrubis wrote:

> Hi!
>> +static const struct sock_fprog strict = {
>> +	.len = (unsigned short)ARRAY_SIZE(strict_filter),
>> +	.filter = (struct sock_filter *)strict_filter
>> +};
>> +
>> +static const struct sock_fprog *strict_addr = &strict;
> This should be:
>
> static unsigned long strict_addr = (unsigned long)&strict;

OK.

>
>> +static unsigned long bad_addr;
>> +static unsigned long num_0;
>> +static unsigned long num_1 = 1;
>> +static unsigned long num_2 = 2;
>> +static unsigned long num_invalid = 999;
>>   
>>   static struct tcase {
>>   	int option;
>> -	unsigned long arg2;
>> +	unsigned long *arg2;
>> +	unsigned long *arg3;
>>   	int exp_errno;
>>   } tcases[] = {
>> -	{OPTION_INVALID, 0, EINVAL},
>> -	{PR_SET_PDEATHSIG, INVALID_ARG, EINVAL},
>> +	{OPTION_INVALID, &num_1, &num_0, EINVAL},
>> +	{PR_SET_PDEATHSIG, &num_invalid, &num_0, EINVAL},
>> +	{PR_SET_DUMPABLE, &num_2, &num_0, EINVAL},
>> +	{PR_SET_NAME, &bad_addr, &num_0, EFAULT},
>> +	{PR_SET_SECCOMP, &num_2, &bad_addr, EFAULT},
>> +	{PR_SET_SECCOMP, &num_2, &strict_addr, EACCES},
>> +	{PR_SET_TIMING, &num_1, &num_0, EINVAL},
>> +#ifdef HAVE_DECL_PR_SET_NO_NEW_PRIVS
>> +	{PR_SET_NO_NEW_PRIVS, &num_0, &num_0, EINVAL},
>> +	{PR_SET_NO_NEW_PRIVS, &num_1, &num_0, EINVAL},
>> +	{PR_GET_NO_NEW_PRIVS, &num_1, &num_0, EINVAL},
>> +#endif
>> +#ifdef HAVE_DECL_PR_SET_THP_DISABLE
>> +	{PR_SET_THP_DISABLE, &num_0, &num_1, EINVAL},
>> +	{PR_GET_THP_DISABLE, &num_1, &num_1, EINVAL},
>> +#endif
>> +#ifdef HAVE_DECL_PR_CAP_AMBIENT
>> +	{PR_CAP_AMBIENT, &num_2, &num_1, EINVAL},
>> +#endif
>> +#ifdef HAVE_DECL_PR_GET_SPECULATION_CTRL
>> +	{PR_GET_SPECULATION_CTRL, &num_1, &num_0, EINVAL},
>> +#endif
> Why the ifdefs, you have even added a fallback definitions into the lapi
> header?
>
> The usuall way how to deal with these is to:
>
> 1) Add fallback definitions to lapi
> 2) Ensure these tests does not fail on older kernels
>
>     We do expect EINVAL in these cases anyways, which is what we would
>     get if the prctl() option is unknown to the kernel anyways, so here
>     we can just get rid of these ifdefs and things should work fine.

For me, a fallback definitions into the lapi header is only for fixing undefined error on old kernel.

IMO, we only test options that kernel supports.
If we test an unsupported option, our case reports EINVAL that will give user a false impression(kernel
supports it, but argument or environment is bad). I think we should check they whether supported before run
(ifdef is a way).

ps: If we test EPERM error(cap is not in PI or PP) of PR_CAP_AMBIENT on old kernel,  they will report EINVAL.
So, I think ifdef is needed.

>
>> +	{PR_SET_SECUREBITS, &num_0, &num_0, EPERM},
>> +	{PR_CAPBSET_DROP, &num_1, &num_0, EPERM},
>>   };
>>   
>>   static void verify_prctl(unsigned int n)
>>   {
>>   	struct tcase *tc = &tcases[n];
>>   
>> -	TEST(prctl(tc->option, tc->arg2));
>> +	TEST(prctl(tc->option, *tc->arg2, *tc->arg3));
>>   	if (TST_RET == 0) {
>>   		tst_res(TFAIL, "prctl() succeeded unexpectedly");
>>   		return;
>>   	}
>>   
>>   	if (tc->exp_errno == TST_ERR) {
>> -		tst_res(TPASS | TTERRNO, "prctl() failed as expected");
>> +		tst_res(TPASS | TTERRNO, "prctl() %d failed as expected", tc->option);
>>   	} else {
>> -		tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
>> +		if (tc->option == PR_SET_SECCOMP && TST_ERR == EINVAL)
>> +			tst_res(TCONF, "current system was not built with CONFIG_SECCOMP.");
>> +		else
>> +			tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
>>   				tst_strerrno(tc->exp_errno));
>>   	}
>>   }
>>   
>> +static void setup(void)
>> +{
>> +	bad_addr = (unsigned long)tst_get_bad_addr(NULL);
>> +}
>> +
>>   static struct tst_test test = {
>> +	.setup = setup,
>>   	.tcnt = ARRAY_SIZE(tcases),
>>   	.test = verify_prctl,
>> +	.caps = (struct tst_cap []) {
>> +		TST_CAP(TST_CAP_DROP, CAP_SYS_ADMIN),
>> +		TST_CAP(TST_CAP_DROP, CAP_SETPCAP),
>> +		{}
>> +	},
>>   };
>> -- 
>> 2.18.0
>>
>>
>>


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20191112/7d08e222/attachment.htm>

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

* [LTP] [PATCH v4] syscalls/prctl02: add more error tests
       [not found]                     ` <5DCA5206.3040508@cn.fujitsu.com>
@ 2019-11-12  7:27                       ` Yang Xu
  2019-11-12 10:15                         ` Cyril Hrubis
  0 siblings, 1 reply; 19+ messages in thread
From: Yang Xu @ 2019-11-12  7:27 UTC (permalink / raw)
  To: ltp


on 2019/11/12 14:32, Xiao Yang wrote:

> On 2019/11/12 11:02, Yang Xu wrote:
>>
>>
>> on 2019/11/12 0:31, Cyril Hrubis wrote:
>>> Hi!
>>>> +static const struct sock_fprog strict = {
>>>> +	.len = (unsigned short)ARRAY_SIZE(strict_filter),
>>>> +	.filter = (struct sock_filter *)strict_filter
>>>> +};
>>>> +
>>>> +static const struct sock_fprog *strict_addr = &strict;
>>> This should be:
>>>
>>> static unsigned long strict_addr = (unsigned long)&strict;
>> OK.
>>>> +static unsigned long bad_addr;
>>>> +static unsigned long num_0;
>>>> +static unsigned long num_1 = 1;
>>>> +static unsigned long num_2 = 2;
>>>> +static unsigned long num_invalid = 999;
>>>>   
>>>>   static struct tcase {
>>>>   	int option;
>>>> -	unsigned long arg2;
>>>> +	unsigned long *arg2;
>>>> +	unsigned long *arg3;
>>>>   	int exp_errno;
>>>>   } tcases[] = {
>>>> -	{OPTION_INVALID, 0, EINVAL},
>>>> -	{PR_SET_PDEATHSIG, INVALID_ARG, EINVAL},
>>>> +	{OPTION_INVALID, &num_1, &num_0, EINVAL},
>>>> +	{PR_SET_PDEATHSIG, &num_invalid, &num_0, EINVAL},
>>>> +	{PR_SET_DUMPABLE, &num_2, &num_0, EINVAL},
>>>> +	{PR_SET_NAME, &bad_addr, &num_0, EFAULT},
>>>> +	{PR_SET_SECCOMP, &num_2, &bad_addr, EFAULT},
>>>> +	{PR_SET_SECCOMP, &num_2, &strict_addr, EACCES},
>>>> +	{PR_SET_TIMING, &num_1, &num_0, EINVAL},
>>>> +#ifdef HAVE_DECL_PR_SET_NO_NEW_PRIVS
>>>> +	{PR_SET_NO_NEW_PRIVS, &num_0, &num_0, EINVAL},
>>>> +	{PR_SET_NO_NEW_PRIVS, &num_1, &num_0, EINVAL},
>>>> +	{PR_GET_NO_NEW_PRIVS, &num_1, &num_0, EINVAL},
>>>> +#endif
>>>> +#ifdef HAVE_DECL_PR_SET_THP_DISABLE
>>>> +	{PR_SET_THP_DISABLE, &num_0, &num_1, EINVAL},
>>>> +	{PR_GET_THP_DISABLE, &num_1, &num_1, EINVAL},
>>>> +#endif
>>>> +#ifdef HAVE_DECL_PR_CAP_AMBIENT
>>>> +	{PR_CAP_AMBIENT, &num_2, &num_1, EINVAL},
>>>> +#endif
>>>> +#ifdef HAVE_DECL_PR_GET_SPECULATION_CTRL
>>>> +	{PR_GET_SPECULATION_CTRL, &num_1, &num_0, EINVAL},
>>>> +#endif
>>> Why the ifdefs, you have even added a fallback definitions into the lapi
>>> header?
>>>
>>> The usuall way how to deal with these is to:
>>>
>>> 1) Add fallback definitions to lapi
>>> 2) Ensure these tests does not fail on older kernels
>>>
>>>     We do expect EINVAL in these cases anyways, which is what we would
>>>     get if the prctl() option is unknown to the kernel anyways, so here
>>>     we can just get rid of these ifdefs and things should work fine.
>> For me, a fallback definitions into the lapi header is only for fixing undefined error on old kernel.
> Hi Yang,
>
> 1) Can undefined error be triggered on old kernel if you use ifdef?  It seems unnecessary for ifdef method to include lapi header.

Yes. It can be triggered and it should use #if HAVE_DECL_PR_GET_SPECULATION_CTRL instead of #ifdef.
Yes. And we should add more check( such as PR_SET_SECCOMP undefined 2.6.18-398.el5) in m4/ltp-prctl.m4 so that we cannot include lapi header.

> 2) Undfined option in glibc doesn't mean that kernel doesn't support it as well.

options definitions is in linux/prctl.h. For most distributions, I think if it is in supported in kernel-header, it should also been
supported on kernel.

>> IMO, we only test options that kernel supports.
>> If we test an unsupported option, our case reports EINVAL that will give user a false impression(kernel
>> supports it, but argument or environment is bad). I think we should check they whether supported before run
>> (ifdef is a way).
>>
>> ps: If we test EPERM error(cap is not in PI or PP) of PR_CAP_AMBIENT on old kernel,  they will report EINVAL.
>> So, I think ifdef is needed.
> Why don't we check if the specified option is supported by calling it 
> with correct args?(i.e. don't mix unsupported option up with wrong args).
>
It sounds reasonable.  I will try it in verify_prctl function if you and cyril have strong opposition to #if.

>
> Best Regards,
> Xiao Yang
>>>> +	{PR_SET_SECUREBITS, &num_0, &num_0, EPERM},
>>>> +	{PR_CAPBSET_DROP, &num_1, &num_0, EPERM},
>>>>   };
>>>>   
>>>>   static void verify_prctl(unsigned int n)
>>>>   {
>>>>   	struct tcase *tc = &tcases[n];
>>>>   
>>>> -	TEST(prctl(tc->option, tc->arg2));
>>>> +	TEST(prctl(tc->option, *tc->arg2, *tc->arg3));
>>>>   	if (TST_RET == 0) {
>>>>   		tst_res(TFAIL, "prctl() succeeded unexpectedly");
>>>>   		return;
>>>>   	}
>>>>   
>>>>   	if (tc->exp_errno == TST_ERR) {
>>>> -		tst_res(TPASS | TTERRNO, "prctl() failed as expected");
>>>> +		tst_res(TPASS | TTERRNO, "prctl() %d failed as expected", tc->option);
>>>>   	} else {
>>>> -		tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
>>>> +		if (tc->option == PR_SET_SECCOMP && TST_ERR == EINVAL)
>>>> +			tst_res(TCONF, "current system was not built with CONFIG_SECCOMP.");
>>>> +		else
>>>> +			tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
>>>>   				tst_strerrno(tc->exp_errno));
>>>>   	}
>>>>   }
>>>>   
>>>> +static void setup(void)
>>>> +{
>>>> +	bad_addr = (unsigned long)tst_get_bad_addr(NULL);
>>>> +}
>>>> +
>>>>   static struct tst_test test = {
>>>> +	.setup = setup,
>>>>   	.tcnt = ARRAY_SIZE(tcases),
>>>>   	.test = verify_prctl,
>>>> +	.caps = (struct tst_cap []) {
>>>> +		TST_CAP(TST_CAP_DROP, CAP_SYS_ADMIN),
>>>> +		TST_CAP(TST_CAP_DROP, CAP_SETPCAP),
>>>> +		{}
>>>> +	},
>>>>   };
>>>> -- 
>>>> 2.18.0
>>>>
>>>>
>>>>
>>
>>
>


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20191112/40f74356/attachment-0001.htm>

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

* [LTP] [PATCH v4] syscalls/prctl02: add more error tests
  2019-11-12  3:02                   ` Yang Xu
       [not found]                     ` <5DCA5206.3040508@cn.fujitsu.com>
@ 2019-11-12 10:10                     ` Cyril Hrubis
  2019-11-12 10:25                       ` Yang Xu
  1 sibling, 1 reply; 19+ messages in thread
From: Cyril Hrubis @ 2019-11-12 10:10 UTC (permalink / raw)
  To: ltp

Hi!
> > 1) Add fallback definitions to lapi
> > 2) Ensure these tests does not fail on older kernels
> >
> >     We do expect EINVAL in these cases anyways, which is what we would
> >     get if the prctl() option is unknown to the kernel anyways, so here
> >     we can just get rid of these ifdefs and things should work fine.
> 
> For me, a fallback definitions into the lapi header is only for fixing undefined error on old kernel.
> 
> IMO, we only test options that kernel supports.
> If we test an unsupported option, our case reports EINVAL that will give user a false impression(kernel
> supports it, but argument or environment is bad). I think we should check they whether supported before run
> (ifdef is a way).

However using ifdefs to assert kernel features never worked at all. The
kernel headers usally lag behind the installed kernel in distribution
and it's even more wrong when you are testing latest kernel on any given
distro.

If you want to check for kernel support the best thing is to use the
tst_kvercmp() that checks the kernel version and even that does not work
100% reliably.

> ps: If we test EPERM error(cap is not in PI or PP) of PR_CAP_AMBIENT on old kernel,  they will report EINVAL.
> So, I think ifdef is needed.

No, ifdefs are never solution here. It will still fail if you compiled
the test on newer distro and booted it up with older kernel.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v4] syscalls/prctl02: add more error tests
  2019-11-12  7:27                       ` Yang Xu
@ 2019-11-12 10:15                         ` Cyril Hrubis
  2019-11-12 10:31                           ` Yang Xu
  2019-11-13  5:23                           ` [LTP] [PATCH v5] " Yang Xu
  0 siblings, 2 replies; 19+ messages in thread
From: Cyril Hrubis @ 2019-11-12 10:15 UTC (permalink / raw)
  To: ltp

Hi!
> > 1) Can undefined error be triggered on old kernel if you use ifdef?  It seems unnecessary for ifdef method to include lapi header.
> 
> Yes. It can be triggered and it should use #if HAVE_DECL_PR_GET_SPECULATION_CTRL instead of #ifdef.
> Yes. And we should add more check( such as PR_SET_SECCOMP undefined 2.6.18-398.el5) in m4/ltp-prctl.m4 so that we cannot include lapi header.
> 
> > 2) Undfined option in glibc doesn't mean that kernel doesn't support it as well.
> 
> options definitions is in linux/prctl.h. For most distributions, I think if it is in supported in kernel-header, it should also been
> supported on kernel.

That is usually the case, but there are cons that I explained in the
previous email.

> >> IMO, we only test options that kernel supports.
> >> If we test an unsupported option, our case reports EINVAL that will give user a false impression(kernel
> >> supports it, but argument or environment is bad). I think we should check they whether supported before run
> >> (ifdef is a way).
> >>
> >> ps: If we test EPERM error(cap is not in PI or PP) of PR_CAP_AMBIENT on old kernel,  they will report EINVAL.
> >> So, I think ifdef is needed.
> > Why don't we check if the specified option is supported by calling it 
> > with correct args?(i.e. don't mix unsupported option up with wrong args).
> >
> It sounds reasonable.  I will try it in verify_prctl function if you and cyril have strong opposition to #if.

Okay, that will work. Calling it with correct parameters in test setup
is 100% correct way how to find out if kernel implements the
functionality.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v4] syscalls/prctl02: add more error tests
  2019-11-12 10:10                     ` [LTP] [PATCH v4] " Cyril Hrubis
@ 2019-11-12 10:25                       ` Yang Xu
  0 siblings, 0 replies; 19+ messages in thread
From: Yang Xu @ 2019-11-12 10:25 UTC (permalink / raw)
  To: ltp

on 2019/11/12 18:10, Cyril Hrubis wrote:

> Hi!
>>> 1) Add fallback definitions to lapi
>>> 2) Ensure these tests does not fail on older kernels
>>>
>>>      We do expect EINVAL in these cases anyways, which is what we would
>>>      get if the prctl() option is unknown to the kernel anyways, so here
>>>      we can just get rid of these ifdefs and things should work fine.
>> For me, a fallback definitions into the lapi header is only for fixing undefined error on old kernel.
>>
>> IMO, we only test options that kernel supports.
>> If we test an unsupported option, our case reports EINVAL that will give user a false impression(kernel
>> supports it, but argument or environment is bad). I think we should check they whether supported before run
>> (ifdef is a way).
> However using ifdefs to assert kernel features never worked at all. The
> kernel headers usally lag behind the installed kernel in distribution
> and it's even more wrong when you are testing latest kernel on any given
> distro.
>
> If you want to check for kernel support the best thing is to use the
> tst_kvercmp() that checks the kernel version and even that does not work
> 100% reliably.

Yes. most distros backport upstream kernel patch and tst_kvercmp maybe useless.

>> ps: If we test EPERM error(cap is not in PI or PP) of PR_CAP_AMBIENT on old kernel,  they will report EINVAL.
>> So, I think ifdef is needed.
> No, ifdefs are never solution here. It will still fail if you compiled
> the test on newer distro and booted it up with older kernel.

Now, I agree with you. If new distro and booted it with older kernel, the ifdef is useless. I think we should use correct argument
as xiao said to check whether kernel supports these options.

>


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20191112/0bf02da8/attachment-0001.htm>

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

* [LTP] [PATCH v4] syscalls/prctl02: add more error tests
  2019-11-12 10:15                         ` Cyril Hrubis
@ 2019-11-12 10:31                           ` Yang Xu
  2019-11-13  5:23                           ` [LTP] [PATCH v5] " Yang Xu
  1 sibling, 0 replies; 19+ messages in thread
From: Yang Xu @ 2019-11-12 10:31 UTC (permalink / raw)
  To: ltp


on 2019/11/12 18:15, Cyril Hrubis wrote:

> Hi!
>>> 1) Can undefined error be triggered on old kernel if you use ifdef?  It seems unnecessary for ifdef method to include lapi header.
>> Yes. It can be triggered and it should use #if HAVE_DECL_PR_GET_SPECULATION_CTRL instead of #ifdef.
>> Yes. And we should add more check( such as PR_SET_SECCOMP undefined 2.6.18-398.el5) in m4/ltp-prctl.m4 so that we cannot include lapi header.
>>
>>> 2) Undfined option in glibc doesn't mean that kernel doesn't support it as well.
>> options definitions is in linux/prctl.h. For most distributions, I think if it is in supported in kernel-header, it should also been
>> supported on kernel.
> That is usually the case, but there are cons that I explained in the
> previous email.

OK.

>
>>>> IMO, we only test options that kernel supports.
>>>> If we test an unsupported option, our case reports EINVAL that will give user a false impression(kernel
>>>> supports it, but argument or environment is bad). I think we should check they whether supported before run
>>>> (ifdef is a way).
>>>>
>>>> ps: If we test EPERM error(cap is not in PI or PP) of PR_CAP_AMBIENT on old kernel,  they will report EINVAL.
>>>> So, I think ifdef is needed.
>>> Why don't we check if the specified option is supported by calling it
>>> with correct args?(i.e. don't mix unsupported option up with wrong args).
>>>
>> It sounds reasonable.  I will try it in verify_prctl function if you and cyril have strong opposition to #if.
> Okay, that will work. Calling it with correct parameters in test setup
> is 100% correct way how to find out if kernel implements the
> functionality.

OK. I will use correct parameters to check whether kernel implements the functionality in setup.
Thanks for your patiently explation.

ps: I will make v5 patch tomorrow.

>


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20191112/c64c5257/attachment.htm>

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

* [LTP] [PATCH v5] syscalls/prctl02: add more error tests
  2019-11-12 10:15                         ` Cyril Hrubis
  2019-11-12 10:31                           ` Yang Xu
@ 2019-11-13  5:23                           ` Yang Xu
  2019-11-13 10:33                             ` Cyril Hrubis
  1 sibling, 1 reply; 19+ messages in thread
From: Yang Xu @ 2019-11-13  5:23 UTC (permalink / raw)
  To: ltp

I check these new options(PR_GET_SECCOMP,PR_GET_NO_NEW_PRIVS,PR_GET_THP_DISABLE,
PR_GET_SPECULATION_CTRL) whether support on current kernel. If it is non-supported,
skip it. For some old options(PR_SET_PDEATHSIG,PR_SET_DUMPABLE,PR_SET_NAME,PR_SET_TIMING),
I don't check them because they are supported since prctl was introduced on v2.6.12-rc2.
For remaining options(PR_SET_SECUREBITS,PR_CAPBSET_DROP), they are supported since
Linux 2.6.26. I think we also don't need to check them because they are too old(It was 11
years old).

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 include/lapi/prctl.h                      |  10 ++
 testcases/kernel/syscalls/prctl/prctl02.c | 161 ++++++++++++++++++++--
 2 files changed, 163 insertions(+), 8 deletions(-)

diff --git a/include/lapi/prctl.h b/include/lapi/prctl.h
index 0b4e196c3..4499df030 100644
--- a/include/lapi/prctl.h
+++ b/include/lapi/prctl.h
@@ -34,6 +34,11 @@
 # define PR_GET_NO_NEW_PRIVS 39
 #endif
 
+#ifndef PR_SET_THP_DISABLE
+# define PR_SET_THP_DISABLE 41
+# define PR_GET_THP_DISABLE 42
+#endif
+
 #ifndef PR_CAP_AMBIENT
 # define PR_CAP_AMBIENT             47
 # define PR_CAP_AMBIENT_IS_SET      1
@@ -42,4 +47,9 @@
 # define PR_CAP_AMBIENT_CLEAR_ALL   4
 #endif
 
+#ifndef PR_GET_SPECULATION_CTRL
+# define PR_GET_SPECULATION_CTRL 52
+# define PR_SET_SPECULATION_CTRL 53
+#endif
+
 #endif /* LAPI_PRCTL_H__ */
diff --git a/testcases/kernel/syscalls/prctl/prctl02.c b/testcases/kernel/syscalls/prctl/prctl02.c
index ec45911fd..93f30b54a 100644
--- a/testcases/kernel/syscalls/prctl/prctl02.c
+++ b/testcases/kernel/syscalls/prctl/prctl02.c
@@ -4,32 +4,143 @@
  *
  * 1) prctl() fails with EINVAL when an invalid value is given for option
  * 2) prctl() fails with EINVAL when option is PR_SET_PDEATHSIG & arg2 is
- * not zero or a valid signal number
+ * not zero or a valid signal number.
+ * 3) prctl() fails with EINVAL when option is PR_SET_DUMPABLE & arg2 is
+ * neither SUID_DUMP_DISABLE nor SUID_DUMP_USER.
+ * 4) prctl() fails with EFAULT when arg2 is an invalid address.
+ * 5) prctl() fails with EFAULT when option is PR_SET_SECCOMP & arg2 is
+ * SECCOMP_MODE_FILTER & arg3 is an invalid address.
+ * 6) prctl() fails with EACCES when option is PR_SET_SECCOMP & arg2 is
+ * SECCOMP_MODE_FILTER & the process does not have the CAP_SYS_ADMIN
+ * capability.
+ * 7) prctl() fails with EINVAL when option is PR_SET_TIMING & arg2 is not
+ * not PR_TIMING_STATISTICAL.
+ * 8,9) prctl() fails with EINVAL when option is PR_SET_NO_NEW_PRIVS & arg2
+ * is not equal to 1 or arg3 is nonzero.
+ * 10) prctl() fails with EINVAL when options is PR_GET_NO_NEW_PRIVS & arg2,
+ * arg3, arg4, or arg5 is nonzero.
+ * 11) prctl() fails with EINVAL when options is PR_SET_THP_DISABLE & arg3,
+ * arg4, arg5 is non-zero.
+ * 12) prctl() fails with EINVAL when options is PR_GET_THP_DISABLE & arg2,
+ * arg3, arg4, or arg5 is nonzero.
+ * 13) prctl() fails with EINVAL when options is PR_CAP_AMBIENT & an unused
+ * argument such as arg4 is nonzero.
+ * 14) prctl() fails with EINVAL when option is PR_GET_SPECULATION_CTRL and
+ * unused arguments is nonzero.
+ * 15) prctl() fails with EPERM when option is PR_SET_SECUREBITS and the
+ * caller does not have the CAP_SETPCAP capability.
+ * 16) prctl() fails with EPERM when option is PR_CAPBSET_DROP and the caller
+ * does not have the CAP_SETPCAP capability.
  */
 
 #include <errno.h>
 #include <signal.h>
 #include <sys/prctl.h>
-
+#include <linux/filter.h>
+#include <linux/capability.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include "config.h"
+#include "lapi/prctl.h"
+#include "lapi/seccomp.h"
+#include "lapi/syscalls.h"
 #include "tst_test.h"
+#include "tst_capability.h"
 
 #define OPTION_INVALID 999
-#define INVALID_ARG 999
+#define unsup_string "prctl() doesn't support this option, skip it"
+static const struct sock_filter  strict_filter[] = {
+	BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)
+};
+
+static const struct sock_fprog strict = {
+	.len = (unsigned short)ARRAY_SIZE(strict_filter),
+	.filter = (struct sock_filter *)strict_filter
+};
+
+static unsigned long strict_addr = (unsigned long)&strict;
+
+static unsigned long bad_addr;
+static unsigned long num_0;
+static unsigned long num_1 = 1;
+static unsigned long num_2 = 2;
+static unsigned long num_invalid = 999;
+static int seccomp_nsup;
+static int nonewprivs_nsup;
+static int thpdisable_nsup;
+static int capambient_nsup;
+static int speculationctrl_nsup;
 
 static struct tcase {
 	int option;
-	unsigned long arg2;
+	unsigned long *arg2;
+	unsigned long *arg3;
 	int exp_errno;
+	char *tname;
 } tcases[] = {
-	{OPTION_INVALID, 0, EINVAL},
-	{PR_SET_PDEATHSIG, INVALID_ARG, EINVAL},
+	{OPTION_INVALID, &num_1, &num_0, EINVAL, "invalid option"},
+	{PR_SET_PDEATHSIG, &num_invalid, &num_0, EINVAL, "PR_SET_PDEATHSIG"},
+	{PR_SET_DUMPABLE, &num_2, &num_0, EINVAL, "PR_SET_DUMPABLE"},
+	{PR_SET_NAME, &bad_addr, &num_0, EFAULT, "PR_SET_NAME"},
+	{PR_SET_SECCOMP, &num_2, &bad_addr, EFAULT, "PR_SET_SECCOMP"},
+	{PR_SET_SECCOMP, &num_2, &strict_addr, EACCES, "PR_SET_SECCOMP"},
+	{PR_SET_TIMING, &num_1, &num_0, EINVAL, "PR_SET_TIMING"},
+	{PR_SET_NO_NEW_PRIVS, &num_0, &num_0, EINVAL, "PR_SET_NO_NEW_PRIVS"},
+	{PR_SET_NO_NEW_PRIVS, &num_1, &num_0, EINVAL, "PR_SET_NO_NEW_PRIVS"},
+	{PR_GET_NO_NEW_PRIVS, &num_1, &num_0, EINVAL, "PR_GET_NO_NEW_PRIVS"},
+	{PR_SET_THP_DISABLE, &num_0, &num_1, EINVAL, "PR_SET_THP_DISABLE"},
+	{PR_GET_THP_DISABLE, &num_1, &num_1, EINVAL, "PR_GET_THP_DISABLE"},
+	{PR_CAP_AMBIENT, &num_2, &num_1, EINVAL, "PR_CAP_AMBIENT"},
+	{PR_GET_SPECULATION_CTRL, &num_1, &num_0, EINVAL, "PR_GET_SPECULATION_CTRL"},
+	{PR_SET_SECUREBITS, &num_0, &num_0, EPERM, "PR_SET_SECUREBITS"},
+	{PR_CAPBSET_DROP, &num_1, &num_0, EPERM, "PR_CAPBSET_DROP"},
 };
 
 static void verify_prctl(unsigned int n)
 {
 	struct tcase *tc = &tcases[n];
 
-	TEST(prctl(tc->option, tc->arg2));
+	tst_res(TINFO, "Test #%d: %s", n, tc->tname);
+
+	switch (tc->option) {
+	case PR_SET_SECCOMP:
+		if (seccomp_nsup) {
+			tst_res(TCONF, "%s", unsup_string);
+			return;
+		}
+	break;
+	case PR_GET_NO_NEW_PRIVS:
+	case PR_SET_NO_NEW_PRIVS:
+		if (nonewprivs_nsup) {
+			tst_res(TCONF, "%s", unsup_string);
+			return;
+		}
+	break;
+	case PR_SET_THP_DISABLE:
+	case PR_GET_THP_DISABLE:
+		if (thpdisable_nsup) {
+			tst_res(TCONF, "%s", unsup_string);
+			return;
+		}
+	break;
+	case PR_CAP_AMBIENT:
+		if (capambient_nsup) {
+			tst_res(TCONF, "%s", unsup_string);
+			return;
+		}
+	break;
+	case PR_GET_SPECULATION_CTRL:
+		if (speculationctrl_nsup) {
+			tst_res(TCONF, "%s", unsup_string);
+			return;
+		}
+	break;
+	default:
+	break;
+	}
+
+	TEST(prctl(tc->option, *tc->arg2, *tc->arg3));
 	if (TST_RET == 0) {
 		tst_res(TFAIL, "prctl() succeeded unexpectedly");
 		return;
@@ -38,12 +149,46 @@ static void verify_prctl(unsigned int n)
 	if (tc->exp_errno == TST_ERR) {
 		tst_res(TPASS | TTERRNO, "prctl() failed as expected");
 	} else {
-		tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
+		if (tc->option == PR_SET_SECCOMP && TST_ERR == EINVAL)
+			tst_res(TCONF, "current system was not built with CONFIG_SECCOMP_FILTER.");
+		else
+			tst_res(TFAIL | TTERRNO, "prctl() failed unexpectedly, expected %s",
 				tst_strerrno(tc->exp_errno));
 	}
 }
 
+static void setup(void)
+{
+	bad_addr = (unsigned long)tst_get_bad_addr(NULL);
+
+	TEST(prctl(PR_GET_SECCOMP));
+	if (TST_ERR == EINVAL)
+		seccomp_nsup = 1;
+
+	TEST(prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0));
+	if (TST_ERR == EINVAL)
+		nonewprivs_nsup = 1;
+
+	TEST(prctl(PR_GET_THP_DISABLE, 0, 0, 0, 0));
+	if (TST_ERR == EINVAL)
+		thpdisable_nsup = 1;
+
+	TEST(prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0, 0));
+	if (TST_ERR == EINVAL)
+		capambient_nsup = 1;
+
+	TEST(prctl(PR_GET_SPECULATION_CTRL, 0, 0, 0, 0));
+	if (TST_ERR == EINVAL)
+		speculationctrl_nsup = 1;
+}
+
 static struct tst_test test = {
+	.setup = setup,
 	.tcnt = ARRAY_SIZE(tcases),
 	.test = verify_prctl,
+	.caps = (struct tst_cap []) {
+		TST_CAP(TST_CAP_DROP, CAP_SYS_ADMIN),
+		TST_CAP(TST_CAP_DROP, CAP_SETPCAP),
+		{}
+	},
 };
-- 
2.18.0




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

* [LTP] [PATCH v5] syscalls/prctl02: add more error tests
  2019-11-13  5:23                           ` [LTP] [PATCH v5] " Yang Xu
@ 2019-11-13 10:33                             ` Cyril Hrubis
  0 siblings, 0 replies; 19+ messages in thread
From: Cyril Hrubis @ 2019-11-13 10:33 UTC (permalink / raw)
  To: ltp

Hi!
Pushed, thanks.

-- 
Cyril Hrubis
chrubis@suse.cz

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

end of thread, other threads:[~2019-11-13 10:33 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-25 12:39 [LTP] [PATCH] syscalls/prctl02: add more error tests Yang Xu
2019-10-31  8:59 ` [LTP] [PATCH v2] " Yang Xu
2019-11-01  8:49   ` Petr Vorel
2019-11-01 11:24     ` Yang Xu
2019-11-01 12:59     ` [LTP] [PATCH v3] " Yang Xu
2019-11-07 14:54       ` Cyril Hrubis
2019-11-08 12:12         ` Yang Xu
2019-11-08 13:20           ` Yang Xu
2019-11-08 14:24             ` Cyril Hrubis
2019-11-11  8:59               ` [LTP] [PATCH v4] " Yang Xu
2019-11-11 16:31                 ` Cyril Hrubis
2019-11-12  3:02                   ` Yang Xu
     [not found]                     ` <5DCA5206.3040508@cn.fujitsu.com>
2019-11-12  7:27                       ` Yang Xu
2019-11-12 10:15                         ` Cyril Hrubis
2019-11-12 10:31                           ` Yang Xu
2019-11-13  5:23                           ` [LTP] [PATCH v5] " Yang Xu
2019-11-13 10:33                             ` Cyril Hrubis
2019-11-12 10:10                     ` [LTP] [PATCH v4] " Cyril Hrubis
2019-11-12 10:25                       ` 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.