All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH v1 1/4] syscalls/shmget01: Remove it
@ 2021-05-12  8:52 Yang Xu
  2021-05-12  8:52 ` [LTP] [PATCH v1 2/4] syscalls/shmget*: Convert into new api Yang Xu
                   ` (3 more replies)
  0 siblings, 4 replies; 21+ messages in thread
From: Yang Xu @ 2021-05-12  8:52 UTC (permalink / raw)
  To: ltp

Since shmct01.c and shmctl08.c has covered this case, we don't need this any more.

Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
---
 runtest/syscalls                              |   1 -
 runtest/syscalls-ipc                          |   1 -
 .../kernel/syscalls/ipc/shmget/.gitignore     |   1 -
 .../kernel/syscalls/ipc/shmget/shmget01.c     | 171 ------------------
 4 files changed, 174 deletions(-)
 delete mode 100644 testcases/kernel/syscalls/ipc/shmget/shmget01.c

diff --git a/runtest/syscalls b/runtest/syscalls
index aa7fa24dd..63d821e53 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1399,7 +1399,6 @@ shmctl08 shmctl08
 shmdt01 shmdt01
 shmdt02 shmdt02
 
-shmget01 shmget01
 shmget02 shmget02
 shmget03 shmget03
 shmget04 shmget04
diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
index 68fff4038..ff0364704 100644
--- a/runtest/syscalls-ipc
+++ b/runtest/syscalls-ipc
@@ -64,7 +64,6 @@ shmctl08 shmctl08
 shmdt01 shmdt01
 shmdt02 shmdt02
 
-shmget01 shmget01
 shmget02 shmget02
 shmget03 shmget03
 shmget04 shmget04
diff --git a/testcases/kernel/syscalls/ipc/shmget/.gitignore b/testcases/kernel/syscalls/ipc/shmget/.gitignore
index 728e4344f..6f08529f8 100644
--- a/testcases/kernel/syscalls/ipc/shmget/.gitignore
+++ b/testcases/kernel/syscalls/ipc/shmget/.gitignore
@@ -1,4 +1,3 @@
-/shmget01
 /shmget02
 /shmget03
 /shmget04
diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget01.c b/testcases/kernel/syscalls/ipc/shmget/shmget01.c
deleted file mode 100644
index 586f4c263..000000000
--- a/testcases/kernel/syscalls/ipc/shmget/shmget01.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- *
- *   Copyright (c) International Business Machines  Corp., 2001
- *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * NAME
- *	shmget01.c
- *
- * DESCRIPTION
- *	shmget01 - test that shmget() correctly creates a shared memory segment
- *
- * ALGORITHM
- *	loop if that option was specified
- *	use the TEST() macro to call shmget()
- *	check the return code
- *	  if failure, issue a FAIL message.
- *	otherwise,
- *	  if doing functionality testing
- *		stat the shared memory resource
- *		check the size, creator pid and mode
- *	  	if correct,
- *			issue a PASS message
- *		otherwise
- *			issue a FAIL message
- *	  else issue a PASS message
- *	call cleanup
- *
- * USAGE:  <for command-line>
- *  shmget01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
- *     where,  -c n : Run n copies concurrently.
- *             -f   : Turn off functionality Testing.
- *	       -i n : Execute test n times.
- *	       -I x : Execute test for x seconds.
- *	       -P x : Pause for x seconds between iterations.
- *	       -t   : Turn on syscall timing.
- *
- * HISTORY
- *	03/2001 - Written by Wayne Boyer
- *
- * RESTRICTIONS
- *	none
- */
-
-#include "ipcshm.h"
-
-char *TCID = "shmget01";
-int TST_TOTAL = 1;
-
-int shm_id_1 = -1;
-
-int main(int ac, char **av)
-{
-	int lc;
-	struct shmid_ds buf;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();		/* global setup */
-
-	/* The following loop checks looping state if -i option given */
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		/*
-		 * Use TEST macro to make the call
-		 */
-
-		TEST(shmget(shmkey, SHM_SIZE, (IPC_CREAT | IPC_EXCL | SHM_RW)));
-
-		if (TEST_RETURN == -1) {
-			tst_resm(TFAIL, "%s call failed - errno = %d : %s",
-				 TCID, TEST_ERRNO, strerror(TEST_ERRNO));
-		} else {
-			shm_id_1 = TEST_RETURN;
-			/* do a STAT and check some info */
-			if (shmctl(shm_id_1, IPC_STAT, &buf) == -1) {
-				tst_resm(TBROK, "shmctl failed in "
-					 "functional test");
-				continue;
-			}
-			/* check the seqment size */
-			if (buf.shm_segsz != SHM_SIZE) {
-				tst_resm(TFAIL, "seqment size is not "
-					 "correct");
-				continue;
-			}
-			/* check the pid of the creator */
-			if (buf.shm_cpid != getpid()) {
-				tst_resm(TFAIL, "creator pid is not "
-					 "correct");
-				continue;
-			}
-			/*
-			 * check the mode of the seqment
-			 * mask out all but the lower 9 bits
-			 */
-			if ((buf.shm_perm.mode & MODE_MASK) !=
-			    ((SHM_RW) & MODE_MASK)) {
-				tst_resm(TFAIL, "segment mode is not "
-					 "correct");
-				continue;
-			}
-			/* if we get here, everything looks good */
-			tst_resm(TPASS, "size, pid & mode are correct");
-		}
-
-		/*
-		 * clean up things in case we are looping
-		 */
-		if (shmctl(shm_id_1, IPC_RMID, NULL) == -1) {
-			tst_resm(TBROK, "couldn't remove shared memory");
-		} else {
-			shm_id_1 = -1;
-		}
-	}
-
-	cleanup();
-
-	tst_exit();
-}
-
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
-{
-
-	tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
-
-	/*
-	 * Create a temporary directory and cd into it.
-	 * This helps to ensure that a unique msgkey is created.
-	 * See libs/libltpipc/libipc.c for more information.
-	 */
-	tst_tmpdir();
-
-	/* get an IPC resource key */
-	shmkey = getipckey();
-}
-
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * 	       or premature exit.
- */
-void cleanup(void)
-{
-	/* if it exists, remove the shared memory resource */
-	rm_shm(shm_id_1);
-
-	tst_rmdir();
-
-}
-- 
2.23.0


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

* [LTP] [PATCH v1 2/4] syscalls/shmget*: Convert into new api
  2021-05-12  8:52 [LTP] [PATCH v1 1/4] syscalls/shmget01: Remove it Yang Xu
@ 2021-05-12  8:52 ` Yang Xu
  2021-05-12 10:44   ` xuyang2018.jy
  2021-06-18 14:28   ` Cyril Hrubis
  2021-05-12  8:52 ` [LTP] [PATCH v1 3/4] syscalls/shmget05: Add test for /proc/sys/kernel/shm_next_id Yang Xu
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 21+ messages in thread
From: Yang Xu @ 2021-05-12  8:52 UTC (permalink / raw)
  To: ltp

1) merge shmget05.c into shmget02.c
2) Use SHMMIN -1 and SHMMAX + 1 to trigger EINVAL error
3) Use SHM_RD, SHM_WR, SHM_RW to trigger EACCES error under unpriviledged user

Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
---
 include/lapi/shm.h                            |  14 +
 runtest/syscalls                              |   1 -
 runtest/syscalls-ipc                          |   1 -
 .../kernel/syscalls/ipc/shmget/.gitignore     |   1 -
 testcases/kernel/syscalls/ipc/shmget/Makefile |   4 +-
 .../kernel/syscalls/ipc/shmget/shmget02.c     | 243 +++++++-----------
 .../kernel/syscalls/ipc/shmget/shmget03.c     | 199 ++++----------
 .../kernel/syscalls/ipc/shmget/shmget04.c     | 193 +++++---------
 .../kernel/syscalls/ipc/shmget/shmget05.c     | 185 -------------
 9 files changed, 209 insertions(+), 632 deletions(-)
 delete mode 100644 testcases/kernel/syscalls/ipc/shmget/shmget05.c

diff --git a/include/lapi/shm.h b/include/lapi/shm.h
index 61c4e37bf..bb280fc44 100644
--- a/include/lapi/shm.h
+++ b/include/lapi/shm.h
@@ -6,8 +6,22 @@
 #ifndef LAPI_SHM_H__
 #define LAPI_SHM_H__
 
+#include <limits.h>
+
 #ifndef SHM_STAT_ANY
 # define SHM_STAT_ANY 15
 #endif
 
+#ifndef SHMMIN
+# define SHMMIN 1
+#endif
+
+#ifndef SHMMAX
+# define SHMMAX (ULONG_MAX - (1UL << 24))
+#endif
+
+#ifndef SHMMNI
+# define SHMMNI 4096
+#endif
+
 #endif /* LAPI_SHM_H__ */
diff --git a/runtest/syscalls b/runtest/syscalls
index 63d821e53..2dff25984 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1402,7 +1402,6 @@ shmdt02 shmdt02
 shmget02 shmget02
 shmget03 shmget03
 shmget04 shmget04
-shmget05 shmget05
 
 sigaction01 sigaction01
 sigaction02 sigaction02
diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
index ff0364704..b3bd37923 100644
--- a/runtest/syscalls-ipc
+++ b/runtest/syscalls-ipc
@@ -67,4 +67,3 @@ shmdt02 shmdt02
 shmget02 shmget02
 shmget03 shmget03
 shmget04 shmget04
-shmget05 shmget05
diff --git a/testcases/kernel/syscalls/ipc/shmget/.gitignore b/testcases/kernel/syscalls/ipc/shmget/.gitignore
index 6f08529f8..c57df68f5 100644
--- a/testcases/kernel/syscalls/ipc/shmget/.gitignore
+++ b/testcases/kernel/syscalls/ipc/shmget/.gitignore
@@ -1,4 +1,3 @@
 /shmget02
 /shmget03
 /shmget04
-/shmget05
diff --git a/testcases/kernel/syscalls/ipc/shmget/Makefile b/testcases/kernel/syscalls/ipc/shmget/Makefile
index 26b9f264d..b1201281d 100644
--- a/testcases/kernel/syscalls/ipc/shmget/Makefile
+++ b/testcases/kernel/syscalls/ipc/shmget/Makefile
@@ -3,10 +3,10 @@
 
 top_srcdir              ?= ../../../../..
 
-LTPLIBS = ltpipc
+LTPLIBS = ltpnewipc
 
 include $(top_srcdir)/include/mk/testcases.mk
 
-LTPLDLIBS  = -lltpipc
+LTPLDLIBS = -lltpnewipc
 
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget02.c b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
index 4436ca7f8..a57904ce9 100644
--- a/testcases/kernel/syscalls/ipc/shmget/shmget02.c
+++ b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
@@ -1,184 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
+ * Copyright (c) International Business Machines  Corp., 2001
+ *  03/2001 - Written by Wayne Boyer
  *
- *   Copyright (c) International Business Machines  Corp., 2001
- *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) 2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
  */
 
-/*
- * NAME
- *	shmget02.c
- *
- * DESCRIPTION
- *	shmget02 - check for ENOENT, EEXIST and EINVAL errors
+/*\
+ * [Description]
  *
- * ALGORITHM
- *	create a shared memory segment with read & write permissions
- *	loop if that option was specified
- *	  call shmget() using five different invalid cases
- *	  check the errno value
- *	    issue a PASS message if we get ENOENT, EEXIST or EINVAL
- *	  otherwise, the tests fails
- *	    issue a FAIL message
- *	call cleanup
+ * Test for ENOENT, EEXIST, EINVAL, EACCES errors.
  *
- * USAGE:  <for command-line>
- *  shmget02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- *     where,  -c n : Run n copies concurrently.
- *             -e   : Turn on errno logging.
- *	       -i n : Execute test n times.
- *	       -I x : Execute test for x seconds.
- *	       -P x : Pause for x seconds between iterations.
- *	       -t   : Turn on syscall timing.
- *
- * HISTORY
- *	03/2001 - Written by Wayne Boyer
- *
- *      06/03/2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
- *      - Fix concurrency issue. The second key used for this test could
- *        conflict with the key from another task.
- *
- * RESTRICTIONS
- *	none
+ * ENOENT - No segment exists for the given key and IPC_CREAT was not specified.
+ * EEXIST - the segment exists and IPC_CREAT | IPC_EXCL is given.
+ * EINVAL - A new segment was to be created and size is less than SHMMIN or
+ * greater than SHMMAX. Or a segment for the given key exists, but size is
+ * greater than the size of that segment.
+ * EACCES - The user does not have permission to access the shared memory segment.
  */
-
-#include "ipcshm.h"
-
-char *TCID = "shmget02";
-int TST_TOTAL = 4;
-
-int shm_id_1 = -1;
-int shm_nonexisting_key = -1;
-key_t shmkey2;
-
-struct test_case_t {
-	int *skey;
-	int size;
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <stdlib.h>
+#include <pwd.h>
+#include <sys/shm.h>
+#include "tst_safe_sysv_ipc.h"
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "lapi/shm.h"
+
+static int shm_id = -1;
+static key_t shmkey, shmkey1;
+static struct passwd *pw;
+
+static struct tcase {
+	int *shmkey;
+	size_t size;
 	int flags;
-	int error;
-} TC[] = {
-	/* EINVAL - size is 0 */
-	{
-	&shmkey2, 0, IPC_CREAT | IPC_EXCL | SHM_RW, EINVAL},
-	    /* EINVAL - size is negative */
-//      {&shmkey2, -1, IPC_CREAT | IPC_EXCL | SHM_RW, EINVAL},
-	    /* EINVAL - size is larger than created segment */
-	{
-	&shmkey, SHM_SIZE * 2, SHM_RW, EINVAL},
-	    /* EEXIST - the segment exists and IPC_CREAT | IPC_EXCL is given */
-	{
-	&shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW, EEXIST},
-	    /* ENOENT - no segment exists for the key and IPC_CREAT is not given */
-	    /* use shm_id_2 (-1) as the key */
-	{
-	&shm_nonexisting_key, SHM_SIZE, SHM_RW, ENOENT}
+	/*1: nobody expected  0: root expected */
+	int exp_user;
+	int exp_err;
+} tcases[] = {
+	{&shmkey1, SHM_SIZE, IPC_EXCL, 0, ENOENT},
+	{&shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL, 0, EEXIST},
+	{&shmkey1, SHMMIN - 1, IPC_CREAT | IPC_EXCL, 0, EINVAL},
+	{&shmkey1, SHMMAX + 1, IPC_CREAT | IPC_EXCL, 0, EINVAL},
+	{&shmkey, SHM_SIZE * 2, IPC_EXCL, 0, EINVAL},
+	{&shmkey, SHM_SIZE, SHM_RD, 1, EACCES},
 };
 
-int main(int ac, char **av)
+static void verify_shmget(struct tcase *tc)
 {
-	int lc;
-	int i;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();		/* global setup */
-
-	/* The following loop checks looping state if -i option given */
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		/* loop through the test cases */
-		for (i = 0; i < TST_TOTAL; i++) {
-			/*
-			 * Look for a failure ...
-			 */
-
-			TEST(shmget(*(TC[i].skey), TC[i].size, TC[i].flags));
-
-			if (TEST_RETURN != -1) {
-				tst_resm(TFAIL, "call succeeded unexpectedly");
-				continue;
-			}
-
-			if (TEST_ERRNO == TC[i].error) {
-				tst_resm(TPASS, "expected failure - errno = "
-					 "%d : %s", TEST_ERRNO,
-					 strerror(TEST_ERRNO));
-			} else {
-				tst_resm(TFAIL, "call failed with an "
-					 "unexpected error - %d : %s",
-					 TEST_ERRNO, strerror(TEST_ERRNO));
-			}
-		}
+	TEST(shmget(*tc->shmkey, tc->size, tc->flags));
+	if (TST_RET != -1) {
+		tst_res(TFAIL, "shmget() returned %li", TST_RET);
+		return;
 	}
 
-	cleanup();
+	if (TST_ERR == tc->exp_err) {
+		tst_res(TPASS | TTERRNO, "shmget(%i, %lu, %i)",
+			*tc->shmkey, tc->size, tc->flags);
+		return;
+	}
 
-	tst_exit();
+	tst_res(TFAIL | TTERRNO, "shmget(%i, %lu, %i) expected %s",
+		*tc->shmkey, tc->size, tc->flags, tst_strerrno(tc->exp_err));
 }
 
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
+static void do_test(unsigned int n)
 {
+	struct tcase *tc = &tcases[n];
+	pid_t pid;
 
-	tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
-
-	/*
-	 * Create a temporary directory and cd into it.
-	 * This helps to ensure that a unique msgkey is created.
-	 * See libs/libltpipc/libipc.c for more information.
-	 */
-	tst_tmpdir();
-
-	/* get an IPC resource key */
-	shmkey = getipckey();
-
-	/* Get an new IPC resource key. */
-	shmkey2 = getipckey();
-
-	if ((shm_id_1 = shmget(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL |
-			       SHM_RW)) == -1) {
-		tst_brkm(TBROK, cleanup, "couldn't create shared memory "
-			 "segment in setup()");
+	if (tc->exp_user == 0) {
+		verify_shmget(tc);
+		return;
 	}
 
-	/* Make sure shm_nonexisting_key is a nonexisting key */
-	while (1) {
-		while (-1 != shmget(shm_nonexisting_key, 1, SHM_RD)) {
-			shm_nonexisting_key--;
-		}
-		if (errno == ENOENT)
-			break;
+	pid = SAFE_FORK();
+	if (pid == 0) {
+		SAFE_SETUID(pw->pw_uid);
+		verify_shmget(tc);
+		exit(0);
 	}
+	tst_reap_children();
 }
 
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * 	       or premature exit.
- */
-void cleanup(void)
+static void setup(void)
 {
-	/* if it exists, remove the shared memory resource */
-	rm_shm(shm_id_1);
+	shmkey = GETIPCKEY();
+	shmkey1 = GETIPCKEY();
 
-	tst_rmdir();
+	shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL);
+	pw = SAFE_GETPWNAM("nobody");
+	tst_res(TINFO, "%d %d", shmkey, shmkey1);
+}
 
+static void cleanup(void)
+{
+	if (shm_id >= 0)
+		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
 }
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.needs_root = 1,
+	.forks_child = 1,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test = do_test,
+	.tcnt = ARRAY_SIZE(tcases),
+};
diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget03.c b/testcases/kernel/syscalls/ipc/shmget/shmget03.c
index 96ebf3608..c74fe241d 100644
--- a/testcases/kernel/syscalls/ipc/shmget/shmget03.c
+++ b/testcases/kernel/syscalls/ipc/shmget/shmget03.c
@@ -1,171 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
- *
- *   Copyright (c) International Business Machines  Corp., 2001
- *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines  Corp., 2001
+ *  03/2001 - Written by Wayne Boyer
  */
 
-/*
- * NAME
- *	shmget03.c
+/*\
+ * [Description]
  *
- * DESCRIPTION
- *	shmget03 - test for ENOSPC error
+ * Test for ENOSPC error.
  *
- * ALGORITHM
- *	create shared memory segments in a loop until reaching the system limit
- *	loop if that option was specified
- *	  attempt to create yet another shared memory segment
- *	  check the errno value
- *	    issue a PASS message if we get ENOSPC
- *	  otherwise, the tests fails
- *	    issue a FAIL message
- *	call cleanup
- *
- * USAGE:  <for command-line>
- *  shmget03 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- *     where,  -c n : Run n copies concurrently.
- *             -e   : Turn on errno logging.
- *	       -i n : Execute test n times.
- *	       -I x : Execute test for x seconds.
- *	       -P x : Pause for x seconds between iterations.
- *	       -t   : Turn on syscall timing.
- *
- * HISTORY
- *	03/2001 - Written by Wayne Boyer
- *
- * RESTRICTIONS
- *	none
- */
-
-#include "ipcshm.h"
-
-char *TCID = "shmget03";
-int TST_TOTAL = 1;
-
-/*
- * The MAXIDS value is somewhat arbitrary and may need to be increased
- * depending on the system being tested.
+ * ENOSPC -  All possible shared memory IDs have been taken (SHMMNI).
  */
-#define MAXIDS	8192
-
-int shm_id_1 = -1;
-int num_shms = 0;
-
-int shm_id_arr[MAXIDS];
-
-int main(int ac, char **av)
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <stdlib.h>
+#include <pwd.h>
+#include <sys/shm.h>
+#include "tst_safe_sysv_ipc.h"
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "lapi/shm.h"
+
+static int shm_id_arr[SHMMNI] = {-1};
+
+static void verify_shmget(void)
 {
-	int lc;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();		/* global setup */
-
-	/* The following loop checks looping state if -i option given */
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		/*
-		 * use the TEST() macro to make the call
-		 */
-
-		TEST(shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | IPC_EXCL
-			    | SHM_RW));
-
-		if (TEST_RETURN != -1) {
-			tst_resm(TFAIL, "call succeeded when error expected");
-			continue;
-		}
-
-		switch (TEST_ERRNO) {
-		case ENOSPC:
-			tst_resm(TPASS, "expected failure - errno = "
-				 "%d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
-			break;
-		default:
-			tst_resm(TFAIL, "call failed with an "
-				 "unexpected error - %d : %s",
-				 TEST_ERRNO, strerror(TEST_ERRNO));
-			break;
-		}
+	TEST(shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW));
+	if (TST_RET != -1) {
+		tst_res(TFAIL, "shmget() returned %li", TST_RET);
+		return;
 	}
-
-	cleanup();
-
-	tst_exit();
+	if (TST_ERR == ENOSPC)
+		tst_res(TPASS | TTERRNO, "shmget() failed as expected");
+	else
+		tst_res(TFAIL | TTERRNO, "shmget() failed unexpectedly, expected ENOSPC, bug got");
 }
 
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
+static void setup(void)
 {
+	int res, num;
 
-	tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
-
-	/*
-	 * Create a temporary directory and cd into it.
-	 * This helps to ensure that a unique msgkey is created.
-	 * See libs/libltpipc/libipc.c for more information.
-	 */
-	tst_tmpdir();
-
-	/* get an IPC resource key */
-	shmkey = getipckey();
-
-	/*
-	 * Use a while loop to create the maximum number of memory segments.
-	 * If the loop exceeds MAXIDS, then break the test and cleanup.
-	 */
-	while ((shm_id_1 = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT |
-				  IPC_EXCL | SHM_RW)) != -1) {
-		shm_id_arr[num_shms++] = shm_id_1;
-		if (num_shms == MAXIDS) {
-			tst_brkm(TBROK, cleanup, "The maximum number of shared "
-				 "memory ID's has been\n\t reached.  Please "
-				 "increase the MAXIDS value in the test.");
-		}
-	}
-
-	/*
-	 * If the errno is other than ENOSPC, then something else is wrong.
-	 */
-	if (errno != ENOSPC) {
-		tst_resm(TINFO, "errno = %d : %s", errno, strerror(errno));
-		tst_brkm(TBROK, cleanup, "Didn't get ENOSPC in test setup");
+	for (num = 0; num < SHMMNI; num++) {
+		res = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW);
+		if (res != -1)
+			shm_id_arr[num] = res;
 	}
+	tst_res(TINFO, "The maximum number(%d) of memory ID's has been reached",
+		SHMMNI);
 }
 
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test@completion
- * 	       or premature exit.
- */
-void cleanup(void)
+
+static void cleanup(void)
 {
 	int i;
 
-	/* remove the shared memory resources that were created */
-	for (i = 0; i < num_shms; i++) {
-		rm_shm(shm_id_arr[i]);
+	for (i = 0; i < SHMMNI; i++) {
+		if (shm_id_arr[i] >= 0)
+			SAFE_SHMCTL(shm_id_arr[i], IPC_RMID, NULL);
 	}
-
-	tst_rmdir();
-
 }
+
+static struct tst_test test = {
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = verify_shmget,
+};
diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget04.c b/testcases/kernel/syscalls/ipc/shmget/shmget04.c
index 60a263c77..fe611b306 100644
--- a/testcases/kernel/syscalls/ipc/shmget/shmget04.c
+++ b/testcases/kernel/syscalls/ipc/shmget/shmget04.c
@@ -1,153 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
- *
- *   Copyright (c) International Business Machines  Corp., 2001
- *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines  Corp., 2001
+ *  03/2001 - Written by Wayne Boyer
  */
 
-/*
- * NAME
- *	shmget04.c
+/*\
+ * [Description]
  *
- * DESCRIPTION
- *	shmget04 - test for EACCES error
+ * Test for EACCES error.
  *
- * ALGORITHM
- *	create a shared memory segment without read or write permissions
- *	loop if that option was specified
- *	  call shmget() with SHM_RW flag using TEST() macro
- *	  check the errno value
- *	    issue a PASS message if we get EACCES
- *	  otherwise, the tests fails
- *	    issue a FAIL message
- *	call cleanup
- *
- * USAGE:  <for command-line>
- *  shmget04 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- *     where,  -c n : Run n copies concurrently.
- *             -e   : Turn on errno logging.
- *	       -i n : Execute test n times.
- *	       -I x : Execute test for x seconds.
- *	       -P x : Pause for x seconds between iterations.
- *	       -t   : Turn on syscall timing.
- *
- * HISTORY
- *	03/2001 - Written by Wayne Boyer
- *
- * RESTRICTIONS
- *	none
+ * Create a shared memory segment without read or write permissions under
+ * unpriviledged user and call shmget() with SHM_RD/SHM_WR/SHM_RW flag to
+ * trigger EACCES error.
  */
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <stdlib.h>
 #include <pwd.h>
-#include "ipcshm.h"
-
-char *TCID = "shmget04";
-int TST_TOTAL = 1;
-
-char nobody_uid[] = "nobody";
-struct passwd *ltpuser;
-
-int shm_id_1 = -1;
-
-int main(int ac, char **av)
+#include <sys/shm.h>
+#include "tst_safe_sysv_ipc.h"
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "lapi/shm.h"
+
+static int shm_id = -1;
+static key_t shmkey;
+static struct tcase {
+	char *message;
+	int flag;
+} tcases[] = {
+	{"Testing SHM_RD flag", SHM_RD},
+	{"Testing SHM_WR flag", SHM_WR},
+	{"Testing SHM_RW flag", SHM_RW},
+};
+
+static void verify_shmget(unsigned int n)
 {
-	int lc;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();		/* global setup */
-
-	/* The following loop checks looping state if -i option given */
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		/*
-		 * use the TEST() macro to make the call
-		 */
+	struct tcase *tc = &tcases[n];
 
-		TEST(shmget(shmkey, SHM_SIZE, SHM_RW));
-
-		if (TEST_RETURN != -1) {
-			tst_resm(TFAIL, "call succeeded when error expected");
-			continue;
-		}
-
-		switch (TEST_ERRNO) {
-		case EACCES:
-			tst_resm(TPASS, "expected failure - errno = "
-				 "%d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
-			break;
-		default:
-			tst_resm(TFAIL, "call failed with an "
-				 "unexpected error - %d : %s",
-				 TEST_ERRNO, strerror(TEST_ERRNO));
-			break;
-		}
+	tst_res(TINFO, "%s", tc->message);
+	TEST(shmget(shmkey, SHM_SIZE, tc->flag));
+	if (TST_RET != -1) {
+		tst_res(TFAIL, "shmget() returned %li", TST_RET);
+		return;
 	}
-
-	cleanup();
-
-	tst_exit();
+	if (TST_ERR == EACCES)
+		tst_res(TPASS | TTERRNO, "shmget() failed as expected");
+	else
+		tst_res(TFAIL | TTERRNO, "shmget() failed unexpectedly, expected EACCES, bug got");
 }
 
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
+static void setup(void)
 {
-	tst_require_root();
-
-	tst_sig(NOFORK, DEF_HANDLER, cleanup);
+	struct passwd *pw;
 
-	TEST_PAUSE;
-
-	/* Switch to nobody user for correct error code collection */
-	ltpuser = getpwnam(nobody_uid);
-	if (setuid(ltpuser->pw_uid) == -1) {
-		tst_resm(TINFO, "setuid failed to "
-			 "to set the effective uid to %d", ltpuser->pw_uid);
-		perror("setuid");
-	}
+	pw = SAFE_GETPWNAM("nobody");
+	SAFE_SETUID(pw->pw_uid);
+	shmkey = GETIPCKEY();
 
-	/*
-	 * Create a temporary directory and cd into it.
-	 * This helps to ensure that a unique msgkey is created.
-	 * See libs/libltpipc/libipc.c for more information.
-	 */
-	tst_tmpdir();
-
-	/* get an IPC resource key */
-	shmkey = getipckey();
-
-	/* create a shared memory segment without read or access permissions */
-	if ((shm_id_1 = shmget(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL)) == -1) {
-		tst_brkm(TBROK, cleanup, "Failed to create shared memory "
-			 "segment in setup");
-	}
+	shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL);
 }
 
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * 	       or premature exit.
- */
-void cleanup(void)
+static void cleanup(void)
 {
-	/* if it exists, remove the shared memory resource */
-	rm_shm(shm_id_1);
-
-	tst_rmdir();
-
+	if (shm_id >= 0)
+		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
 }
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.needs_root = 1,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test = verify_shmget,
+	.tcnt = ARRAY_SIZE(tcases),
+};
diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget05.c b/testcases/kernel/syscalls/ipc/shmget/shmget05.c
deleted file mode 100644
index de9544591..000000000
--- a/testcases/kernel/syscalls/ipc/shmget/shmget05.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- *
- *   Copyright (c) International Business Machines  Corp., 2001
- *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * NAME
- *	shmget05.c
- *
- * DESCRIPTION
- *	shmget05 - test for EACCES error
- *
- * ALGORITHM
- *	create a shared memory segment with root only read & write permissions
- *	fork a child process
- *	if child
- *	  set the ID of the child process to that of "nobody"
- *	  loop if that option was specified
- *	    call shmget() using the TEST() macro
- *	    check the errno value
- *	      issue a PASS message if we get EACCES
- *	    otherwise, the tests fails
- *	      issue a FAIL message
- *	  call cleanup
- *	if parent
- *	  wait for child to exit
- *	  remove the shared memory segment
- *
- * USAGE:  <for command-line>
- *  shmget05 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- *     where,  -c n : Run n copies concurrently.
- *             -e   : Turn on errno logging.
- *	       -i n : Execute test n times.
- *	       -I x : Execute test for x seconds.
- *	       -P x : Pause for x seconds between iterations.
- *	       -t   : Turn on syscall timing.
- *
- * HISTORY
- *	03/2001 - Written by Wayne Boyer
- *
- * RESTRICTIONS
- *	test must be run at root
- */
-
-#include "ipcshm.h"
-#include <sys/types.h>
-#include <sys/wait.h>
-#include "safe_macros.h"
-
-char *TCID = "shmget05";
-int TST_TOTAL = 1;
-
-int shm_id_1 = -1;
-
-uid_t ltp_uid;
-char *ltp_user = "nobody";
-
-int main(int ac, char **av)
-{
-	int pid;
-	void do_child(void);
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();		/* global setup */
-
-	if ((pid = FORK_OR_VFORK()) == -1) {
-		tst_brkm(TBROK, cleanup, "could not fork");
-	}
-
-	if (pid == 0) {		/* child */
-		/* set the user ID of the child to the non root user */
-		if (setuid(ltp_uid) == -1) {
-			tst_resm(TBROK, "setuid() failed");
-			exit(1);
-		}
-
-		do_child();
-
-		cleanup();
-
-	} else {		/* parent */
-		/* wait for the child to return */
-		SAFE_WAITPID(cleanup, pid, NULL, 0);
-
-		/* if it exists, remove the shared memory resource */
-		rm_shm(shm_id_1);
-
-		tst_rmdir();
-	}
-	tst_exit();
-}
-
-/*
- * do_child - make the TEST call as the child process
- */
-void do_child(void)
-{
-	int lc;
-
-	/* The following loop checks looping state if -i option given */
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		/*
-		 * Look for a failure ...
-		 */
-
-		TEST(shmget(shmkey, SHM_SIZE, SHM_RW));
-
-		if (TEST_RETURN != -1) {
-			tst_resm(TFAIL, "call succeeded when error expected");
-			continue;
-		}
-
-		switch (TEST_ERRNO) {
-		case EACCES:
-			tst_resm(TPASS, "expected failure - errno = "
-				 "%d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
-			break;
-		default:
-			tst_resm(TFAIL, "call failed with an "
-				 "unexpected error - %d : %s",
-				 TEST_ERRNO, strerror(TEST_ERRNO));
-			break;
-		}
-	}
-}
-
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
-{
-	tst_require_root();
-
-	tst_sig(FORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
-
-	/*
-	 * Create a temporary directory and cd into it.
-	 * This helps to ensure that a unique msgkey is created.
-	 * See libs/libltpipc/libipc.c for more information.
-	 */
-	tst_tmpdir();
-
-	/* get an IPC resource key */
-	shmkey = getipckey();
-
-	/* create a shared memory segment with read and write permissions */
-	if ((shm_id_1 = shmget(shmkey, SHM_SIZE,
-			       SHM_RW | IPC_CREAT | IPC_EXCL)) == -1) {
-		tst_brkm(TBROK, cleanup, "Failed to create shared memory "
-			 "segment in setup");
-	}
-
-	/* get the userid for a non root user */
-	ltp_uid = getuserid(ltp_user);
-}
-
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * 	       or premature exit.
- */
-void cleanup(void)
-{
-
-}
-- 
2.23.0


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

* [LTP] [PATCH v1 3/4] syscalls/shmget05: Add test for /proc/sys/kernel/shm_next_id
  2021-05-12  8:52 [LTP] [PATCH v1 1/4] syscalls/shmget01: Remove it Yang Xu
  2021-05-12  8:52 ` [LTP] [PATCH v1 2/4] syscalls/shmget*: Convert into new api Yang Xu
@ 2021-05-12  8:52 ` Yang Xu
  2021-06-29  3:25   ` xuyang2018.jy
  2021-07-22 11:52   ` Cyril Hrubis
  2021-05-12  8:52 ` [LTP] [PATCH v1 4/4] syscalls/shmget06: Add test when the id of shm_next_id has existed Yang Xu
  2021-06-18 12:54 ` [LTP] [PATCH v1 1/4] syscalls/shmget01: Remove it Cyril Hrubis
  3 siblings, 2 replies; 21+ messages in thread
From: Yang Xu @ 2021-05-12  8:52 UTC (permalink / raw)
  To: ltp

This case is similar to msgget04.c.

Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
---
 runtest/syscalls                              |  1 +
 runtest/syscalls-ipc                          |  1 +
 .../kernel/syscalls/ipc/shmget/.gitignore     |  1 +
 .../kernel/syscalls/ipc/shmget/shmget05.c     | 69 +++++++++++++++++++
 4 files changed, 72 insertions(+)
 create mode 100644 testcases/kernel/syscalls/ipc/shmget/shmget05.c

diff --git a/runtest/syscalls b/runtest/syscalls
index 2dff25984..63d821e53 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1402,6 +1402,7 @@ shmdt02 shmdt02
 shmget02 shmget02
 shmget03 shmget03
 shmget04 shmget04
+shmget05 shmget05
 
 sigaction01 sigaction01
 sigaction02 sigaction02
diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
index b3bd37923..ff0364704 100644
--- a/runtest/syscalls-ipc
+++ b/runtest/syscalls-ipc
@@ -67,3 +67,4 @@ shmdt02 shmdt02
 shmget02 shmget02
 shmget03 shmget03
 shmget04 shmget04
+shmget05 shmget05
diff --git a/testcases/kernel/syscalls/ipc/shmget/.gitignore b/testcases/kernel/syscalls/ipc/shmget/.gitignore
index c57df68f5..6f08529f8 100644
--- a/testcases/kernel/syscalls/ipc/shmget/.gitignore
+++ b/testcases/kernel/syscalls/ipc/shmget/.gitignore
@@ -1,3 +1,4 @@
 /shmget02
 /shmget03
 /shmget04
+/shmget05
diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget05.c b/testcases/kernel/syscalls/ipc/shmget/shmget05.c
new file mode 100644
index 000000000..601609648
--- /dev/null
+++ b/testcases/kernel/syscalls/ipc/shmget/shmget05.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2021 FUJITSU LIMITED. All rights reserved.
+ * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * It is a basic test about shm_next_id.
+ *
+ * shm_next_id specifies desired id for next allocated IPC shared memory. By
+ * default they are equal to -1, which means generic allocation logic.
+ * Possible values to set are in range {0..INT_MAX}.
+ * Toggle with non-default value will be set back to -1 by kernel after
+ * successful IPC object allocation.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
+#include "libnewipc.h"
+
+#define NEXT_ID_PATH "/proc/sys/kernel/shm_next_id"
+static int shm_id, pid;
+static key_t shmkey;
+
+static void verify_shmget(void)
+{
+	SAFE_FILE_PRINTF(NEXT_ID_PATH, "%d", pid);
+
+	shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, SHM_RW | IPC_CREAT);
+	if (shm_id == pid)
+		tst_res(TPASS, "shm_next_id succeeded, shm id %d", pid);
+	else
+		tst_res(TFAIL, "shm_next_id failed, expected id %d, but got %d", pid, shm_id);
+
+	TST_ASSERT_INT(NEXT_ID_PATH, -1);
+	SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
+	pid++;
+}
+
+static void setup(void)
+{
+	shmkey = GETIPCKEY();
+	pid = getpid();
+}
+
+static void cleanup(void)
+{
+	if (shm_id != -1)
+		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
+}
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = verify_shmget,
+	.needs_kconfigs = (const char *[]) {
+		"CONFIG_CHECKPOINT_RESTORE=y",
+		NULL
+	},
+	.needs_root = 1,
+};
-- 
2.23.0


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

* [LTP] [PATCH v1 4/4] syscalls/shmget06: Add test when the id of shm_next_id has existed
  2021-05-12  8:52 [LTP] [PATCH v1 1/4] syscalls/shmget01: Remove it Yang Xu
  2021-05-12  8:52 ` [LTP] [PATCH v1 2/4] syscalls/shmget*: Convert into new api Yang Xu
  2021-05-12  8:52 ` [LTP] [PATCH v1 3/4] syscalls/shmget05: Add test for /proc/sys/kernel/shm_next_id Yang Xu
@ 2021-05-12  8:52 ` Yang Xu
  2021-07-22 12:08   ` Cyril Hrubis
  2021-06-18 12:54 ` [LTP] [PATCH v1 1/4] syscalls/shmget01: Remove it Cyril Hrubis
  3 siblings, 1 reply; 21+ messages in thread
From: Yang Xu @ 2021-05-12  8:52 UTC (permalink / raw)
  To: ltp

When the identifier of the System V shared memory segment that shm_next_id has
existed, shmget() with different key will return the another shm id. But kernel
doesn't guarantee desired id, I just compare with existed id, if not equal, the
test succeeded.

This case is similar to msgget05.c.

Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
---
 runtest/syscalls                              |  1 +
 runtest/syscalls-ipc                          |  1 +
 .../kernel/syscalls/ipc/shmget/.gitignore     |  1 +
 .../kernel/syscalls/ipc/shmget/shmget06.c     | 77 +++++++++++++++++++
 4 files changed, 80 insertions(+)
 create mode 100644 testcases/kernel/syscalls/ipc/shmget/shmget06.c

diff --git a/runtest/syscalls b/runtest/syscalls
index 63d821e53..3a1731685 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1403,6 +1403,7 @@ shmget02 shmget02
 shmget03 shmget03
 shmget04 shmget04
 shmget05 shmget05
+shmget06 shmget06
 
 sigaction01 sigaction01
 sigaction02 sigaction02
diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
index ff0364704..b758158c3 100644
--- a/runtest/syscalls-ipc
+++ b/runtest/syscalls-ipc
@@ -68,3 +68,4 @@ shmget02 shmget02
 shmget03 shmget03
 shmget04 shmget04
 shmget05 shmget05
+shmget06 shmget06
diff --git a/testcases/kernel/syscalls/ipc/shmget/.gitignore b/testcases/kernel/syscalls/ipc/shmget/.gitignore
index 6f08529f8..768d1c69d 100644
--- a/testcases/kernel/syscalls/ipc/shmget/.gitignore
+++ b/testcases/kernel/syscalls/ipc/shmget/.gitignore
@@ -2,3 +2,4 @@
 /shmget03
 /shmget04
 /shmget05
+/shmget06
diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget06.c b/testcases/kernel/syscalls/ipc/shmget/shmget06.c
new file mode 100644
index 000000000..3138d4482
--- /dev/null
+++ b/testcases/kernel/syscalls/ipc/shmget/shmget06.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2021 FUJITSU LIMITED. All rights reserved.
+ * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * It is a basic test about shm_next_id.
+ *
+ * When the shared memory segment identifier that shm_next_id stored has
+ * existed, call shmget with different key just use another unused value in range
+ * [0,INT_MAX]. kernel doesn't guarantee the desired id.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
+#include "libnewipc.h"
+
+#define NEXT_ID_PATH "/proc/sys/kernel/shm_next_id"
+
+static int shm_id[2], pid;
+static key_t shmkey[2];
+
+static void verify_shmget(void)
+{
+	SAFE_FILE_PRINTF(NEXT_ID_PATH, "%d", shm_id[0]);
+
+	shm_id[1] = SAFE_SHMGET(shmkey[1], SHM_SIZE, IPC_CREAT | SHM_RW);
+	if (shm_id[1] == shm_id[0])
+		tst_res(TFAIL, "shm id %d has existed, shmget() returns the"
+			" same shm id unexpectedly", shm_id[0]);
+	else
+		tst_res(TPASS, "shm id %d has existed, shmget() returns the"
+			" new shm id %d", shm_id[0], shm_id[1]);
+
+	SAFE_SHMCTL(shm_id[1], IPC_RMID, NULL);
+}
+
+static void setup(void)
+{
+	shmkey[0] = GETIPCKEY();
+	shmkey[1] = GETIPCKEY();
+	pid = getpid();
+	SAFE_FILE_PRINTF(NEXT_ID_PATH, "%d", pid);
+	shm_id[0] = SAFE_SHMGET(shmkey[0], SHM_SIZE, IPC_CREAT | SHM_RW);
+	tst_res(TINFO, "Test shm_next_id effects on shmget(different key) "
+		"when this identifier of shared memory segment has existed");
+}
+
+static void cleanup(void)
+{
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		if (shm_id[i] != -1)
+			SAFE_SHMCTL(shm_id[i], IPC_RMID, NULL);
+	}
+}
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = verify_shmget,
+	.needs_kconfigs = (const char *[]) {
+		"CONFIG_CHECKPOINT_RESTORE=y",
+		NULL
+	},
+	.needs_root = 1,
+};
-- 
2.23.0


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

* [LTP] [PATCH v1 2/4] syscalls/shmget*: Convert into new api
  2021-05-12  8:52 ` [LTP] [PATCH v1 2/4] syscalls/shmget*: Convert into new api Yang Xu
@ 2021-05-12 10:44   ` xuyang2018.jy
  2021-06-03  9:49     ` xuyang2018.jy
  2021-06-18 14:28   ` Cyril Hrubis
  1 sibling, 1 reply; 21+ messages in thread
From: xuyang2018.jy @ 2021-05-12 10:44 UTC (permalink / raw)
  To: ltp

Hi ALL
> 1) merge shmget05.c into shmget02.c
> 2) Use SHMMIN -1 and SHMMAX + 1 to trigger EINVAL error
> 3) Use SHM_RD, SHM_WR, SHM_RW to trigger EACCES error under unpriviledged user

Sorry for missing EPERM error in shmget02.c(I will add it in v2 when you
have comment on rest patches)

diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget02.c
b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
index a57904ce9..319d1e972 100644
--- a/testcases/kernel/syscalls/ipc/shmget/shmget02.c
+++ b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
@@ -17,6 +17,9 @@
  * greater than SHMMAX. Or a segment for the given key exists, but size is
  * greater than the size of that segment.
  * EACCES - The user does not have permission to access the shared
memory segment.
+ * EPERM - The SHM_HUGETLB flag was specified, but the caller was not
privileged
+ * (did not have the CAP_IPC_LOCK capability). Also the caller's group
id should
+ * be not in hugetlb_shm_group proc file.
  */
 #include <errno.h>
 #include <sys/types.h>
@@ -47,6 +50,7 @@ static struct tcase {
        {&shmkey1, SHMMAX + 1, IPC_CREAT | IPC_EXCL, 0, EINVAL},
        {&shmkey, SHM_SIZE * 2, IPC_EXCL, 0, EINVAL},
        {&shmkey, SHM_SIZE, SHM_RD, 1, EACCES},
+       {&shmkey1, SHM_SIZE, IPC_CREAT | SHM_HUGETLB, 1, EPERM}
 };

 static void verify_shmget(struct tcase *tc)
@@ -91,6 +95,7 @@ static void setup(void)
        shmkey = GETIPCKEY();
        shmkey1 = GETIPCKEY();

+       SAFE_FILE_PRINTF("/proc/sys/vm/hugetlb_shm_group", "1");
        shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL);
        pw = SAFE_GETPWNAM("nobody");
        tst_res(TINFO, "%d %d", shmkey, shmkey1);
@@ -110,4 +115,8 @@ static struct tst_test test = {
        .cleanup = cleanup,
        .test = do_test,
        .tcnt = ARRAY_SIZE(tcases),
+       .save_restore = (const char * const[]) {
+                "?/proc/sys/vm/hugetlb_shm_group",
+               NULL,
+       }
 };


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

* [LTP] [PATCH v1 2/4] syscalls/shmget*: Convert into new api
  2021-05-12 10:44   ` xuyang2018.jy
@ 2021-06-03  9:49     ` xuyang2018.jy
  0 siblings, 0 replies; 21+ messages in thread
From: xuyang2018.jy @ 2021-06-03  9:49 UTC (permalink / raw)
  To: ltp

Hi!
Ping. Also add a url[1] for the missing EPRERM error(should see lastest
man-page).

[1]https://github.com/mkerrisk/man-pages/commit/090fdddb4342f92a1dbeba687462f4bcee816232

Best Regards
Yang Xu
> Hi ALL
>> 1) merge shmget05.c into shmget02.c
>> 2) Use SHMMIN -1 and SHMMAX + 1 to trigger EINVAL error
>> 3) Use SHM_RD, SHM_WR, SHM_RW to trigger EACCES error under unpriviledged user
> 
> Sorry for missing EPERM error in shmget02.c(I will add it in v2 when you
> have comment on rest patches)
> 
> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget02.c
> b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
> index a57904ce9..319d1e972 100644
> --- a/testcases/kernel/syscalls/ipc/shmget/shmget02.c
> +++ b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
> @@ -17,6 +17,9 @@
>    * greater than SHMMAX. Or a segment for the given key exists, but size is
>    * greater than the size of that segment.
>    * EACCES - The user does not have permission to access the shared
> memory segment.
> + * EPERM - The SHM_HUGETLB flag was specified, but the caller was not
> privileged
> + * (did not have the CAP_IPC_LOCK capability). Also the caller's group
> id should
> + * be not in hugetlb_shm_group proc file.
>    */
>   #include<errno.h>
>   #include<sys/types.h>
> @@ -47,6 +50,7 @@ static struct tcase {
>          {&shmkey1, SHMMAX + 1, IPC_CREAT | IPC_EXCL, 0, EINVAL},
>          {&shmkey, SHM_SIZE * 2, IPC_EXCL, 0, EINVAL},
>          {&shmkey, SHM_SIZE, SHM_RD, 1, EACCES},
> +       {&shmkey1, SHM_SIZE, IPC_CREAT | SHM_HUGETLB, 1, EPERM}
>   };
> 
>   static void verify_shmget(struct tcase *tc)
> @@ -91,6 +95,7 @@ static void setup(void)
>          shmkey = GETIPCKEY();
>          shmkey1 = GETIPCKEY();
> 
> +       SAFE_FILE_PRINTF("/proc/sys/vm/hugetlb_shm_group", "1");
>          shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL);
>          pw = SAFE_GETPWNAM("nobody");
>          tst_res(TINFO, "%d %d", shmkey, shmkey1);
> @@ -110,4 +115,8 @@ static struct tst_test test = {
>          .cleanup = cleanup,
>          .test = do_test,
>          .tcnt = ARRAY_SIZE(tcases),
> +       .save_restore = (const char * const[]) {
> +                "?/proc/sys/vm/hugetlb_shm_group",
> +               NULL,
> +       }
>   };
> 

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

* [LTP] [PATCH v1 1/4] syscalls/shmget01: Remove it
  2021-05-12  8:52 [LTP] [PATCH v1 1/4] syscalls/shmget01: Remove it Yang Xu
                   ` (2 preceding siblings ...)
  2021-05-12  8:52 ` [LTP] [PATCH v1 4/4] syscalls/shmget06: Add test when the id of shm_next_id has existed Yang Xu
@ 2021-06-18 12:54 ` Cyril Hrubis
  3 siblings, 0 replies; 21+ messages in thread
From: Cyril Hrubis @ 2021-06-18 12:54 UTC (permalink / raw)
  To: ltp

Hi!
Applied, thanks.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v1 2/4] syscalls/shmget*: Convert into new api
  2021-05-12  8:52 ` [LTP] [PATCH v1 2/4] syscalls/shmget*: Convert into new api Yang Xu
  2021-05-12 10:44   ` xuyang2018.jy
@ 2021-06-18 14:28   ` Cyril Hrubis
  2021-06-21  9:48     ` xuyang2018.jy
  2021-06-22  8:31     ` [LTP] [PATCH v2] " Yang Xu
  1 sibling, 2 replies; 21+ messages in thread
From: Cyril Hrubis @ 2021-06-18 14:28 UTC (permalink / raw)
  To: ltp

Hi!
> 1) merge shmget05.c into shmget02.c
> 2) Use SHMMIN -1 and SHMMAX + 1 to trigger EINVAL error
> 3) Use SHM_RD, SHM_WR, SHM_RW to trigger EACCES error under unpriviledged user
> 
> Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
> ---
>  include/lapi/shm.h                            |  14 +
>  runtest/syscalls                              |   1 -
>  runtest/syscalls-ipc                          |   1 -
>  .../kernel/syscalls/ipc/shmget/.gitignore     |   1 -
>  testcases/kernel/syscalls/ipc/shmget/Makefile |   4 +-
>  .../kernel/syscalls/ipc/shmget/shmget02.c     | 243 +++++++-----------
>  .../kernel/syscalls/ipc/shmget/shmget03.c     | 199 ++++----------
>  .../kernel/syscalls/ipc/shmget/shmget04.c     | 193 +++++---------
>  .../kernel/syscalls/ipc/shmget/shmget05.c     | 185 -------------
>  9 files changed, 209 insertions(+), 632 deletions(-)
>  delete mode 100644 testcases/kernel/syscalls/ipc/shmget/shmget05.c
> 
> diff --git a/include/lapi/shm.h b/include/lapi/shm.h
> index 61c4e37bf..bb280fc44 100644
> --- a/include/lapi/shm.h
> +++ b/include/lapi/shm.h
> @@ -6,8 +6,22 @@
>  #ifndef LAPI_SHM_H__
>  #define LAPI_SHM_H__
>  
> +#include <limits.h>
> +
>  #ifndef SHM_STAT_ANY
>  # define SHM_STAT_ANY 15
>  #endif
>  
> +#ifndef SHMMIN
> +# define SHMMIN 1
> +#endif
> +
> +#ifndef SHMMAX
> +# define SHMMAX (ULONG_MAX - (1UL << 24))
> +#endif
> +
> +#ifndef SHMMNI
> +# define SHMMNI 4096
> +#endif
> +
>  #endif /* LAPI_SHM_H__ */
> diff --git a/runtest/syscalls b/runtest/syscalls
> index 63d821e53..2dff25984 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -1402,7 +1402,6 @@ shmdt02 shmdt02
>  shmget02 shmget02
>  shmget03 shmget03
>  shmget04 shmget04
> -shmget05 shmget05
>  
>  sigaction01 sigaction01
>  sigaction02 sigaction02
> diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
> index ff0364704..b3bd37923 100644
> --- a/runtest/syscalls-ipc
> +++ b/runtest/syscalls-ipc
> @@ -67,4 +67,3 @@ shmdt02 shmdt02
>  shmget02 shmget02
>  shmget03 shmget03
>  shmget04 shmget04
> -shmget05 shmget05
> diff --git a/testcases/kernel/syscalls/ipc/shmget/.gitignore b/testcases/kernel/syscalls/ipc/shmget/.gitignore
> index 6f08529f8..c57df68f5 100644
> --- a/testcases/kernel/syscalls/ipc/shmget/.gitignore
> +++ b/testcases/kernel/syscalls/ipc/shmget/.gitignore
> @@ -1,4 +1,3 @@
>  /shmget02
>  /shmget03
>  /shmget04
> -/shmget05
> diff --git a/testcases/kernel/syscalls/ipc/shmget/Makefile b/testcases/kernel/syscalls/ipc/shmget/Makefile
> index 26b9f264d..b1201281d 100644
> --- a/testcases/kernel/syscalls/ipc/shmget/Makefile
> +++ b/testcases/kernel/syscalls/ipc/shmget/Makefile
> @@ -3,10 +3,10 @@
>  
>  top_srcdir              ?= ../../../../..
>  
> -LTPLIBS = ltpipc
> +LTPLIBS = ltpnewipc
>  
>  include $(top_srcdir)/include/mk/testcases.mk
>  
> -LTPLDLIBS  = -lltpipc
> +LTPLDLIBS = -lltpnewipc
>  
>  include $(top_srcdir)/include/mk/generic_leaf_target.mk
> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget02.c b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
> index 4436ca7f8..a57904ce9 100644
> --- a/testcases/kernel/syscalls/ipc/shmget/shmget02.c
> +++ b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
> @@ -1,184 +1,113 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
>  /*
> + * Copyright (c) International Business Machines  Corp., 2001
> + *  03/2001 - Written by Wayne Boyer
>   *
> - *   Copyright (c) International Business Machines  Corp., 2001
> - *
> - *   This program is free software;  you can redistribute it and/or modify
> - *   it under the terms of the GNU General Public License as published by
> - *   the Free Software Foundation; either version 2 of the License, or
> - *   (at your option) any later version.
> - *
> - *   This program is distributed in the hope that it will be useful,
> - *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
> - *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
> - *   the GNU General Public License for more details.
> - *
> - *   You should have received a copy of the GNU General Public License
> - *   along with this program;  if not, write to the Free Software
> - *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + * Copyright (c) 2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
>   */
>  
> -/*
> - * NAME
> - *	shmget02.c
> - *
> - * DESCRIPTION
> - *	shmget02 - check for ENOENT, EEXIST and EINVAL errors
> +/*\
> + * [Description]
>   *
> - * ALGORITHM
> - *	create a shared memory segment with read & write permissions
> - *	loop if that option was specified
> - *	  call shmget() using five different invalid cases
> - *	  check the errno value
> - *	    issue a PASS message if we get ENOENT, EEXIST or EINVAL
> - *	  otherwise, the tests fails
> - *	    issue a FAIL message
> - *	call cleanup
> + * Test for ENOENT, EEXIST, EINVAL, EACCES errors.
>   *
> - * USAGE:  <for command-line>
> - *  shmget02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
> - *     where,  -c n : Run n copies concurrently.
> - *             -e   : Turn on errno logging.
> - *	       -i n : Execute test n times.
> - *	       -I x : Execute test for x seconds.
> - *	       -P x : Pause for x seconds between iterations.
> - *	       -t   : Turn on syscall timing.
> - *
> - * HISTORY
> - *	03/2001 - Written by Wayne Boyer
> - *
> - *      06/03/2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
> - *      - Fix concurrency issue. The second key used for this test could
> - *        conflict with the key from another task.
> - *
> - * RESTRICTIONS
> - *	none
> + * ENOENT - No segment exists for the given key and IPC_CREAT was not specified.
> + * EEXIST - the segment exists and IPC_CREAT | IPC_EXCL is given.
> + * EINVAL - A new segment was to be created and size is less than SHMMIN or
> + * greater than SHMMAX. Or a segment for the given key exists, but size is
> + * greater than the size of that segment.
> + * EACCES - The user does not have permission to access the shared memory segment.
>   */
> -
> -#include "ipcshm.h"
> -
> -char *TCID = "shmget02";
> -int TST_TOTAL = 4;
> -
> -int shm_id_1 = -1;
> -int shm_nonexisting_key = -1;
> -key_t shmkey2;
> -
> -struct test_case_t {
> -	int *skey;
> -	int size;
> +#include <errno.h>
> +#include <sys/types.h>
> +#include <sys/ipc.h>
> +#include <stdlib.h>
> +#include <pwd.h>
> +#include <sys/shm.h>
> +#include "tst_safe_sysv_ipc.h"
> +#include "tst_test.h"
> +#include "libnewipc.h"
> +#include "lapi/shm.h"
> +
> +static int shm_id = -1;
> +static key_t shmkey, shmkey1;
> +static struct passwd *pw;
> +
> +static struct tcase {
> +	int *shmkey;
> +	size_t size;
>  	int flags;
> -	int error;
> -} TC[] = {
> -	/* EINVAL - size is 0 */
> -	{
> -	&shmkey2, 0, IPC_CREAT | IPC_EXCL | SHM_RW, EINVAL},
> -	    /* EINVAL - size is negative */
> -//      {&shmkey2, -1, IPC_CREAT | IPC_EXCL | SHM_RW, EINVAL},
> -	    /* EINVAL - size is larger than created segment */
> -	{
> -	&shmkey, SHM_SIZE * 2, SHM_RW, EINVAL},
> -	    /* EEXIST - the segment exists and IPC_CREAT | IPC_EXCL is given */
> -	{
> -	&shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW, EEXIST},
> -	    /* ENOENT - no segment exists for the key and IPC_CREAT is not given */
> -	    /* use shm_id_2 (-1) as the key */
> -	{
> -	&shm_nonexisting_key, SHM_SIZE, SHM_RW, ENOENT}
> +	/*1: nobody expected  0: root expected */
> +	int exp_user;
> +	int exp_err;
> +} tcases[] = {
> +	{&shmkey1, SHM_SIZE, IPC_EXCL, 0, ENOENT},
> +	{&shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL, 0, EEXIST},
> +	{&shmkey1, SHMMIN - 1, IPC_CREAT | IPC_EXCL, 0, EINVAL},
> +	{&shmkey1, SHMMAX + 1, IPC_CREAT | IPC_EXCL, 0, EINVAL},

Can we please add the zero size EINVAL test as well?

> +	{&shmkey, SHM_SIZE * 2, IPC_EXCL, 0, EINVAL},
> +	{&shmkey, SHM_SIZE, SHM_RD, 1, EACCES},
>  };

...

> +static void do_test(unsigned int n)
>  {
> +	struct tcase *tc = &tcases[n];
> +	pid_t pid;
>  
> -	tst_sig(NOFORK, DEF_HANDLER, cleanup);
> -
> -	TEST_PAUSE;
> -
> -	/*
> -	 * Create a temporary directory and cd into it.
> -	 * This helps to ensure that a unique msgkey is created.
> -	 * See libs/libltpipc/libipc.c for more information.
> -	 */
> -	tst_tmpdir();
> -
> -	/* get an IPC resource key */
> -	shmkey = getipckey();
> -
> -	/* Get an new IPC resource key. */
> -	shmkey2 = getipckey();
> -
> -	if ((shm_id_1 = shmget(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL |
> -			       SHM_RW)) == -1) {
> -		tst_brkm(TBROK, cleanup, "couldn't create shared memory "
> -			 "segment in setup()");
> +	if (tc->exp_user == 0) {
> +		verify_shmget(tc);

Just use the TST_EXP_FAIL() macro here instead, no need to reinvent the
wheel.

> +		return;
>  	}
>  
> -	/* Make sure shm_nonexisting_key is a nonexisting key */
> -	while (1) {
> -		while (-1 != shmget(shm_nonexisting_key, 1, SHM_RD)) {
> -			shm_nonexisting_key--;
> -		}
> -		if (errno == ENOENT)
> -			break;
> +	pid = SAFE_FORK();
> +	if (pid == 0) {
> +		SAFE_SETUID(pw->pw_uid);
> +		verify_shmget(tc);

And here as well.

> +		exit(0);
>  	}
> +	tst_reap_children();
>  }
>  
> -/*
> - * cleanup() - performs all the ONE TIME cleanup for this test at completion
> - * 	       or premature exit.
> - */
> -void cleanup(void)
> +static void setup(void)
>  {
> -	/* if it exists, remove the shared memory resource */
> -	rm_shm(shm_id_1);
> +	shmkey = GETIPCKEY();
> +	shmkey1 = GETIPCKEY();
>  
> -	tst_rmdir();
> +	shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL);
> +	pw = SAFE_GETPWNAM("nobody");
> +	tst_res(TINFO, "%d %d", shmkey, shmkey1);

I'm not sure if this message is useful.

> +}
>  
> +static void cleanup(void)
> +{
> +	if (shm_id >= 0)
> +		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
>  }
> +
> +static struct tst_test test = {
> +	.needs_tmpdir = 1,
> +	.needs_root = 1,
> +	.forks_child = 1,
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.test = do_test,
> +	.tcnt = ARRAY_SIZE(tcases),
> +};
> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget03.c b/testcases/kernel/syscalls/ipc/shmget/shmget03.c
> index 96ebf3608..c74fe241d 100644
> --- a/testcases/kernel/syscalls/ipc/shmget/shmget03.c
> +++ b/testcases/kernel/syscalls/ipc/shmget/shmget03.c
> @@ -1,171 +1,68 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later

...

> +static int shm_id_arr[SHMMNI] = {-1};

The SHMMNI is just default value, it could be adjusted at runtime by
setting /proc/sys/kernel/shmmni

So we should ideally fix the test to read that value in the test setup
and allocate the array based on the value.

> +static void verify_shmget(void)
>  {
> -	int lc;
> -
> -	tst_parse_opts(ac, av, NULL, NULL);
> -
> -	setup();		/* global setup */
> -
> -	/* The following loop checks looping state if -i option given */
> -
> -	for (lc = 0; TEST_LOOPING(lc); lc++) {
> -		/* reset tst_count in case we are looping */
> -		tst_count = 0;
> -
> -		/*
> -		 * use the TEST() macro to make the call
> -		 */
> -
> -		TEST(shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | IPC_EXCL
> -			    | SHM_RW));
> -
> -		if (TEST_RETURN != -1) {
> -			tst_resm(TFAIL, "call succeeded when error expected");
> -			continue;
> -		}
> -
> -		switch (TEST_ERRNO) {
> -		case ENOSPC:
> -			tst_resm(TPASS, "expected failure - errno = "
> -				 "%d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
> -			break;
> -		default:
> -			tst_resm(TFAIL, "call failed with an "
> -				 "unexpected error - %d : %s",
> -				 TEST_ERRNO, strerror(TEST_ERRNO));
> -			break;
> -		}
> +	TEST(shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW));
> +	if (TST_RET != -1) {
> +		tst_res(TFAIL, "shmget() returned %li", TST_RET);
> +		return;
>  	}
> -
> -	cleanup();
> -
> -	tst_exit();
> +	if (TST_ERR == ENOSPC)
> +		tst_res(TPASS | TTERRNO, "shmget() failed as expected");
> +	else
> +		tst_res(TFAIL | TTERRNO, "shmget() failed unexpectedly, expected ENOSPC, bug got");

This should be TST_EXP_FAIL() as well.

>  }
>  
> -/*
> - * setup() - performs all the ONE TIME setup for this test.
> - */
> -void setup(void)
> +static void setup(void)
>  {
> +	int res, num;
>  
> -	tst_sig(NOFORK, DEF_HANDLER, cleanup);
> -
> -	TEST_PAUSE;
> -
> -	/*
> -	 * Create a temporary directory and cd into it.
> -	 * This helps to ensure that a unique msgkey is created.
> -	 * See libs/libltpipc/libipc.c for more information.
> -	 */
> -	tst_tmpdir();
> -
> -	/* get an IPC resource key */
> -	shmkey = getipckey();
> -
> -	/*
> -	 * Use a while loop to create the maximum number of memory segments.
> -	 * If the loop exceeds MAXIDS, then break the test and cleanup.
> -	 */
> -	while ((shm_id_1 = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT |
> -				  IPC_EXCL | SHM_RW)) != -1) {
> -		shm_id_arr[num_shms++] = shm_id_1;
> -		if (num_shms == MAXIDS) {
> -			tst_brkm(TBROK, cleanup, "The maximum number of shared "
> -				 "memory ID's has been\n\t reached.  Please "
> -				 "increase the MAXIDS value in the test.");
> -		}
> -	}
> -
> -	/*
> -	 * If the errno is other than ENOSPC, then something else is wrong.
> -	 */
> -	if (errno != ENOSPC) {
> -		tst_resm(TINFO, "errno = %d : %s", errno, strerror(errno));
> -		tst_brkm(TBROK, cleanup, "Didn't get ENOSPC in test setup");
> +	for (num = 0; num < SHMMNI; num++) {
> +		res = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW);
> +		if (res != -1)
> +			shm_id_arr[num] = res;
>  	}

So we attempt to allocate SHMMNI shared memory segemnts and the last
call will fail.

I guess that we can as well attempt to allocate SHMMNI-1 segemnts and
expect them to all pass. I do not like ignore any failures that may
happen here and cary on with the test. It would be better to TBROK here
instead.

> +	tst_res(TINFO, "The maximum number(%d) of memory ID's has been reached",
> +		SHMMNI);
>  }
>  
> -/*
> - * cleanup() - performs all the ONE TIME cleanup for this test at completion
> - * 	       or premature exit.
> - */
> -void cleanup(void)
> +
> +static void cleanup(void)
>  {
>  	int i;
>  
> -	/* remove the shared memory resources that were created */
> -	for (i = 0; i < num_shms; i++) {
> -		rm_shm(shm_id_arr[i]);
> +	for (i = 0; i < SHMMNI; i++) {
> +		if (shm_id_arr[i] >= 0)

This is actually not correct, since there are possibly zeros in the
array (just because it's global variable and only first position is
intialized wiht -1) and we could incorrectly attempt to remove sement
with id 0.

I guess that the cleanest way how to handle this would be having global
counter for the number of created semgents:


static key_t *keys;
static unsigned int max_key;

setup()
{
	...
	keys = SAFE_MALLOC(sizeof(key_t) * shmmni);
	...

	for (;;) {
		if (max_key >= shmni)
			break;


		keys[max_key] = shmget(...);

		if (keys[max_key] < 0)
			tst_brk(TBROK, ...);

		max_key++;
	}
}

cleanup()
{
	key_t key;

	for (key = 0; key < max_key; key++)
		SAFE_SHMCTL(keys[key], IPC_RMID, NULL);
}



> +			SAFE_SHMCTL(shm_id_arr[i], IPC_RMID, NULL);
>  	}
> -
> -	tst_rmdir();
> -
>  }
> +
> +static struct tst_test test = {
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.test_all = verify_shmget,
> +};
> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget04.c b/testcases/kernel/syscalls/ipc/shmget/shmget04.c
> index 60a263c77..fe611b306 100644

...

> +	tst_res(TINFO, "%s", tc->message);
> +	TEST(shmget(shmkey, SHM_SIZE, tc->flag));
> +	if (TST_RET != -1) {
> +		tst_res(TFAIL, "shmget() returned %li", TST_RET);
> +		return;
>  	}
> -
> -	cleanup();
> -
> -	tst_exit();
> +	if (TST_ERR == EACCES)
> +		tst_res(TPASS | TTERRNO, "shmget() failed as expected");
> +	else
> +		tst_res(TFAIL | TTERRNO, "shmget() failed unexpectedly, expected EACCES, bug got");

TST_EXP_FAIL() here as well.

>  }
>  
> -/*
> - * setup() - performs all the ONE TIME setup for this test.
> - */
> -void setup(void)
> +static void setup(void)
>  {
> -	tst_require_root();
> -
> -	tst_sig(NOFORK, DEF_HANDLER, cleanup);
> +	struct passwd *pw;
>  
> -	TEST_PAUSE;
> -
> -	/* Switch to nobody user for correct error code collection */
> -	ltpuser = getpwnam(nobody_uid);
> -	if (setuid(ltpuser->pw_uid) == -1) {
> -		tst_resm(TINFO, "setuid failed to "
> -			 "to set the effective uid to %d", ltpuser->pw_uid);
> -		perror("setuid");
> -	}
> +	pw = SAFE_GETPWNAM("nobody");
> +	SAFE_SETUID(pw->pw_uid);
> +	shmkey = GETIPCKEY();
>  
> -	/*
> -	 * Create a temporary directory and cd into it.
> -	 * This helps to ensure that a unique msgkey is created.
> -	 * See libs/libltpipc/libipc.c for more information.
> -	 */
> -	tst_tmpdir();
> -
> -	/* get an IPC resource key */
> -	shmkey = getipckey();
> -
> -	/* create a shared memory segment without read or access permissions */
> -	if ((shm_id_1 = shmget(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL)) == -1) {
> -		tst_brkm(TBROK, cleanup, "Failed to create shared memory "
> -			 "segment in setup");
> -	}
> +	shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL);
>  }
>  
> -/*
> - * cleanup() - performs all the ONE TIME cleanup for this test at completion
> - * 	       or premature exit.
> - */
> -void cleanup(void)
> +static void cleanup(void)
>  {
> -	/* if it exists, remove the shared memory resource */
> -	rm_shm(shm_id_1);
> -
> -	tst_rmdir();
> -
> +	if (shm_id >= 0)
> +		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
>  }
> +
> +static struct tst_test test = {
> +	.needs_tmpdir = 1,
> +	.needs_root = 1,
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.test = verify_shmget,
> +	.tcnt = ARRAY_SIZE(tcases),
> +};

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v1 2/4] syscalls/shmget*: Convert into new api
  2021-06-18 14:28   ` Cyril Hrubis
@ 2021-06-21  9:48     ` xuyang2018.jy
  2021-06-22  8:31     ` [LTP] [PATCH v2] " Yang Xu
  1 sibling, 0 replies; 21+ messages in thread
From: xuyang2018.jy @ 2021-06-21  9:48 UTC (permalink / raw)
  To: ltp

Hi Cyril
Thanks for your review, will fix these comments on v2.
> Hi!
>> 1) merge shmget05.c into shmget02.c
>> 2) Use SHMMIN -1 and SHMMAX + 1 to trigger EINVAL error
>> 3) Use SHM_RD, SHM_WR, SHM_RW to trigger EACCES error under unpriviledged user
>>
>> Signed-off-by: Yang Xu<xuyang2018.jy@fujitsu.com>
>> ---
>>   include/lapi/shm.h                            |  14 +
>>   runtest/syscalls                              |   1 -
>>   runtest/syscalls-ipc                          |   1 -
>>   .../kernel/syscalls/ipc/shmget/.gitignore     |   1 -
>>   testcases/kernel/syscalls/ipc/shmget/Makefile |   4 +-
>>   .../kernel/syscalls/ipc/shmget/shmget02.c     | 243 +++++++-----------
>>   .../kernel/syscalls/ipc/shmget/shmget03.c     | 199 ++++----------
>>   .../kernel/syscalls/ipc/shmget/shmget04.c     | 193 +++++---------
>>   .../kernel/syscalls/ipc/shmget/shmget05.c     | 185 -------------
>>   9 files changed, 209 insertions(+), 632 deletions(-)
>>   delete mode 100644 testcases/kernel/syscalls/ipc/shmget/shmget05.c
>>
>> diff --git a/include/lapi/shm.h b/include/lapi/shm.h
>> index 61c4e37bf..bb280fc44 100644
>> --- a/include/lapi/shm.h
>> +++ b/include/lapi/shm.h
>> @@ -6,8 +6,22 @@
>>   #ifndef LAPI_SHM_H__
>>   #define LAPI_SHM_H__
>>
>> +#include<limits.h>
>> +
>>   #ifndef SHM_STAT_ANY
>>   # define SHM_STAT_ANY 15
>>   #endif
>>
>> +#ifndef SHMMIN
>> +# define SHMMIN 1
>> +#endif
>> +
>> +#ifndef SHMMAX
>> +# define SHMMAX (ULONG_MAX - (1UL<<  24))
>> +#endif
>> +
>> +#ifndef SHMMNI
>> +# define SHMMNI 4096
>> +#endif
>> +
>>   #endif /* LAPI_SHM_H__ */
>> diff --git a/runtest/syscalls b/runtest/syscalls
>> index 63d821e53..2dff25984 100644
>> --- a/runtest/syscalls
>> +++ b/runtest/syscalls
>> @@ -1402,7 +1402,6 @@ shmdt02 shmdt02
>>   shmget02 shmget02
>>   shmget03 shmget03
>>   shmget04 shmget04
>> -shmget05 shmget05
>>
>>   sigaction01 sigaction01
>>   sigaction02 sigaction02
>> diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
>> index ff0364704..b3bd37923 100644
>> --- a/runtest/syscalls-ipc
>> +++ b/runtest/syscalls-ipc
>> @@ -67,4 +67,3 @@ shmdt02 shmdt02
>>   shmget02 shmget02
>>   shmget03 shmget03
>>   shmget04 shmget04
>> -shmget05 shmget05
>> diff --git a/testcases/kernel/syscalls/ipc/shmget/.gitignore b/testcases/kernel/syscalls/ipc/shmget/.gitignore
>> index 6f08529f8..c57df68f5 100644
>> --- a/testcases/kernel/syscalls/ipc/shmget/.gitignore
>> +++ b/testcases/kernel/syscalls/ipc/shmget/.gitignore
>> @@ -1,4 +1,3 @@
>>   /shmget02
>>   /shmget03
>>   /shmget04
>> -/shmget05
>> diff --git a/testcases/kernel/syscalls/ipc/shmget/Makefile b/testcases/kernel/syscalls/ipc/shmget/Makefile
>> index 26b9f264d..b1201281d 100644
>> --- a/testcases/kernel/syscalls/ipc/shmget/Makefile
>> +++ b/testcases/kernel/syscalls/ipc/shmget/Makefile
>> @@ -3,10 +3,10 @@
>>
>>   top_srcdir              ?= ../../../../..
>>
>> -LTPLIBS = ltpipc
>> +LTPLIBS = ltpnewipc
>>
>>   include $(top_srcdir)/include/mk/testcases.mk
>>
>> -LTPLDLIBS  = -lltpipc
>> +LTPLDLIBS = -lltpnewipc
>>
>>   include $(top_srcdir)/include/mk/generic_leaf_target.mk
>> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget02.c b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
>> index 4436ca7f8..a57904ce9 100644
>> --- a/testcases/kernel/syscalls/ipc/shmget/shmget02.c
>> +++ b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
>> @@ -1,184 +1,113 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>>   /*
>> + * Copyright (c) International Business Machines  Corp., 2001
>> + *  03/2001 - Written by Wayne Boyer
>>    *
>> - *   Copyright (c) International Business Machines  Corp., 2001
>> - *
>> - *   This program is free software;  you can redistribute it and/or modify
>> - *   it under the terms of the GNU General Public License as published by
>> - *   the Free Software Foundation; either version 2 of the License, or
>> - *   (at your option) any later version.
>> - *
>> - *   This program is distributed in the hope that it will be useful,
>> - *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
>> - *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
>> - *   the GNU General Public License for more details.
>> - *
>> - *   You should have received a copy of the GNU General Public License
>> - *   along with this program;  if not, write to the Free Software
>> - *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>> + * Copyright (c) 2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
>>    */
>>
>> -/*
>> - * NAME
>> - *	shmget02.c
>> - *
>> - * DESCRIPTION
>> - *	shmget02 - check for ENOENT, EEXIST and EINVAL errors
>> +/*\
>> + * [Description]
>>    *
>> - * ALGORITHM
>> - *	create a shared memory segment with read&  write permissions
>> - *	loop if that option was specified
>> - *	  call shmget() using five different invalid cases
>> - *	  check the errno value
>> - *	    issue a PASS message if we get ENOENT, EEXIST or EINVAL
>> - *	  otherwise, the tests fails
>> - *	    issue a FAIL message
>> - *	call cleanup
>> + * Test for ENOENT, EEXIST, EINVAL, EACCES errors.
>>    *
>> - * USAGE:<for command-line>
>> - *  shmget02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
>> - *     where,  -c n : Run n copies concurrently.
>> - *             -e   : Turn on errno logging.
>> - *	       -i n : Execute test n times.
>> - *	       -I x : Execute test for x seconds.
>> - *	       -P x : Pause for x seconds between iterations.
>> - *	       -t   : Turn on syscall timing.
>> - *
>> - * HISTORY
>> - *	03/2001 - Written by Wayne Boyer
>> - *
>> - *      06/03/2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
>> - *      - Fix concurrency issue. The second key used for this test could
>> - *        conflict with the key from another task.
>> - *
>> - * RESTRICTIONS
>> - *	none
>> + * ENOENT - No segment exists for the given key and IPC_CREAT was not specified.
>> + * EEXIST - the segment exists and IPC_CREAT | IPC_EXCL is given.
>> + * EINVAL - A new segment was to be created and size is less than SHMMIN or
>> + * greater than SHMMAX. Or a segment for the given key exists, but size is
>> + * greater than the size of that segment.
>> + * EACCES - The user does not have permission to access the shared memory segment.
>>    */
>> -
>> -#include "ipcshm.h"
>> -
>> -char *TCID = "shmget02";
>> -int TST_TOTAL = 4;
>> -
>> -int shm_id_1 = -1;
>> -int shm_nonexisting_key = -1;
>> -key_t shmkey2;
>> -
>> -struct test_case_t {
>> -	int *skey;
>> -	int size;
>> +#include<errno.h>
>> +#include<sys/types.h>
>> +#include<sys/ipc.h>
>> +#include<stdlib.h>
>> +#include<pwd.h>
>> +#include<sys/shm.h>
>> +#include "tst_safe_sysv_ipc.h"
>> +#include "tst_test.h"
>> +#include "libnewipc.h"
>> +#include "lapi/shm.h"
>> +
>> +static int shm_id = -1;
>> +static key_t shmkey, shmkey1;
>> +static struct passwd *pw;
>> +
>> +static struct tcase {
>> +	int *shmkey;
>> +	size_t size;
>>   	int flags;
>> -	int error;
>> -} TC[] = {
>> -	/* EINVAL - size is 0 */
>> -	{
>> -	&shmkey2, 0, IPC_CREAT | IPC_EXCL | SHM_RW, EINVAL},
>> -	    /* EINVAL - size is negative */
>> -//      {&shmkey2, -1, IPC_CREAT | IPC_EXCL | SHM_RW, EINVAL},
>> -	    /* EINVAL - size is larger than created segment */
>> -	{
>> -	&shmkey, SHM_SIZE * 2, SHM_RW, EINVAL},
>> -	    /* EEXIST - the segment exists and IPC_CREAT | IPC_EXCL is given */
>> -	{
>> -	&shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW, EEXIST},
>> -	    /* ENOENT - no segment exists for the key and IPC_CREAT is not given */
>> -	    /* use shm_id_2 (-1) as the key */
>> -	{
>> -	&shm_nonexisting_key, SHM_SIZE, SHM_RW, ENOENT}
>> +	/*1: nobody expected  0: root expected */
>> +	int exp_user;
>> +	int exp_err;
>> +} tcases[] = {
>> +	{&shmkey1, SHM_SIZE, IPC_EXCL, 0, ENOENT},
>> +	{&shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL, 0, EEXIST},
>> +	{&shmkey1, SHMMIN - 1, IPC_CREAT | IPC_EXCL, 0, EINVAL},
>> +	{&shmkey1, SHMMAX + 1, IPC_CREAT | IPC_EXCL, 0, EINVAL},
>
> Can we please add the zero size EINVAL test as well?
SHMMIN is equal to 1, so we have tested zero size EINVAL test.
>
>> +	{&shmkey, SHM_SIZE * 2, IPC_EXCL, 0, EINVAL},
>> +	{&shmkey, SHM_SIZE, SHM_RD, 1, EACCES},
>>   };
>
> ...
>
>> +static void do_test(unsigned int n)
>>   {
>> +	struct tcase *tc =&tcases[n];
>> +	pid_t pid;
>>
>> -	tst_sig(NOFORK, DEF_HANDLER, cleanup);
>> -
>> -	TEST_PAUSE;
>> -
>> -	/*
>> -	 * Create a temporary directory and cd into it.
>> -	 * This helps to ensure that a unique msgkey is created.
>> -	 * See libs/libltpipc/libipc.c for more information.
>> -	 */
>> -	tst_tmpdir();
>> -
>> -	/* get an IPC resource key */
>> -	shmkey = getipckey();
>> -
>> -	/* Get an new IPC resource key. */
>> -	shmkey2 = getipckey();
>> -
>> -	if ((shm_id_1 = shmget(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL |
>> -			       SHM_RW)) == -1) {
>> -		tst_brkm(TBROK, cleanup, "couldn't create shared memory "
>> -			 "segment in setup()");
>> +	if (tc->exp_user == 0) {
>> +		verify_shmget(tc);
>
> Just use the TST_EXP_FAIL() macro here instead, no need to reinvent the
> wheel.
Yes, use TST_EXP_FAIL(shmget(*tc->shmkey, tc->size, tc->flags), 
tc->exp_err, "shmget(%i, %lu, %i)",*tc->shmkey, tc->size, tc->flags) to 
replace.
>
>> +		return;
>>   	}
>>
>> -	/* Make sure shm_nonexisting_key is a nonexisting key */
>> -	while (1) {
>> -		while (-1 != shmget(shm_nonexisting_key, 1, SHM_RD)) {
>> -			shm_nonexisting_key--;
>> -		}
>> -		if (errno == ENOENT)
>> -			break;
>> +	pid = SAFE_FORK();
>> +	if (pid == 0) {
>> +		SAFE_SETUID(pw->pw_uid);
>> +		verify_shmget(tc);
>
> And here as well.
OK.
>
>> +		exit(0);
>>   	}
>> +	tst_reap_children();
>>   }
>>
>> -/*
>> - * cleanup() - performs all the ONE TIME cleanup for this test at completion
>> - * 	       or premature exit.
>> - */
>> -void cleanup(void)
>> +static void setup(void)
>>   {
>> -	/* if it exists, remove the shared memory resource */
>> -	rm_shm(shm_id_1);
>> +	shmkey = GETIPCKEY();
>> +	shmkey1 = GETIPCKEY();
>>
>> -	tst_rmdir();
>> +	shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL);
>> +	pw = SAFE_GETPWNAM("nobody");
>> +	tst_res(TINFO, "%d %d", shmkey, shmkey1);
>
> I'm not sure if this message is useful.
It is debug message, will remove it.
>
>> +}
>>
>> +static void cleanup(void)
>> +{
>> +	if (shm_id>= 0)
>> +		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
>>   }
>> +
>> +static struct tst_test test = {
>> +	.needs_tmpdir = 1,
>> +	.needs_root = 1,
>> +	.forks_child = 1,
>> +	.setup = setup,
>> +	.cleanup = cleanup,
>> +	.test = do_test,
>> +	.tcnt = ARRAY_SIZE(tcases),
>> +};
>> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget03.c b/testcases/kernel/syscalls/ipc/shmget/shmget03.c
>> index 96ebf3608..c74fe241d 100644
>> --- a/testcases/kernel/syscalls/ipc/shmget/shmget03.c
>> +++ b/testcases/kernel/syscalls/ipc/shmget/shmget03.c
>> @@ -1,171 +1,68 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>
> ...
>
>> +static int shm_id_arr[SHMMNI] = {-1};
>
> The SHMMNI is just default value, it could be adjusted at runtime by
> setting /proc/sys/kernel/shmmni
>
> So we should ideally fix the test to read that value in the test setup
> and allocate the array based on the value.
Agree.
>
>> +static void verify_shmget(void)
>>   {
>> -	int lc;
>> -
>> -	tst_parse_opts(ac, av, NULL, NULL);
>> -
>> -	setup();		/* global setup */
>> -
>> -	/* The following loop checks looping state if -i option given */
>> -
>> -	for (lc = 0; TEST_LOOPING(lc); lc++) {
>> -		/* reset tst_count in case we are looping */
>> -		tst_count = 0;
>> -
>> -		/*
>> -		 * use the TEST() macro to make the call
>> -		 */
>> -
>> -		TEST(shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | IPC_EXCL
>> -			    | SHM_RW));
>> -
>> -		if (TEST_RETURN != -1) {
>> -			tst_resm(TFAIL, "call succeeded when error expected");
>> -			continue;
>> -		}
>> -
>> -		switch (TEST_ERRNO) {
>> -		case ENOSPC:
>> -			tst_resm(TPASS, "expected failure - errno = "
>> -				 "%d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
>> -			break;
>> -		default:
>> -			tst_resm(TFAIL, "call failed with an "
>> -				 "unexpected error - %d : %s",
>> -				 TEST_ERRNO, strerror(TEST_ERRNO));
>> -			break;
>> -		}
>> +	TEST(shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW));
>> +	if (TST_RET != -1) {
>> +		tst_res(TFAIL, "shmget() returned %li", TST_RET);
>> +		return;
>>   	}
>> -
>> -	cleanup();
>> -
>> -	tst_exit();
>> +	if (TST_ERR == ENOSPC)
>> +		tst_res(TPASS | TTERRNO, "shmget() failed as expected");
>> +	else
>> +		tst_res(TFAIL | TTERRNO, "shmget() failed unexpectedly, expected ENOSPC, bug got");
>
> This should be TST_EXP_FAIL() as well.
Will do it.
>
>>   }
>>
>> -/*
>> - * setup() - performs all the ONE TIME setup for this test.
>> - */
>> -void setup(void)
>> +static void setup(void)
>>   {
>> +	int res, num;
>>
>> -	tst_sig(NOFORK, DEF_HANDLER, cleanup);
>> -
>> -	TEST_PAUSE;
>> -
>> -	/*
>> -	 * Create a temporary directory and cd into it.
>> -	 * This helps to ensure that a unique msgkey is created.
>> -	 * See libs/libltpipc/libipc.c for more information.
>> -	 */
>> -	tst_tmpdir();
>> -
>> -	/* get an IPC resource key */
>> -	shmkey = getipckey();
>> -
>> -	/*
>> -	 * Use a while loop to create the maximum number of memory segments.
>> -	 * If the loop exceeds MAXIDS, then break the test and cleanup.
>> -	 */
>> -	while ((shm_id_1 = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT |
>> -				  IPC_EXCL | SHM_RW)) != -1) {
>> -		shm_id_arr[num_shms++] = shm_id_1;
>> -		if (num_shms == MAXIDS) {
>> -			tst_brkm(TBROK, cleanup, "The maximum number of shared "
>> -				 "memory ID's has been\n\t reached.  Please "
>> -				 "increase the MAXIDS value in the test.");
>> -		}
>> -	}
>> -
>> -	/*
>> -	 * If the errno is other than ENOSPC, then something else is wrong.
>> -	 */
>> -	if (errno != ENOSPC) {
>> -		tst_resm(TINFO, "errno = %d : %s", errno, strerror(errno));
>> -		tst_brkm(TBROK, cleanup, "Didn't get ENOSPC in test setup");
>> +	for (num = 0; num<  SHMMNI; num++) {
>> +		res = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW);
>> +		if (res != -1)
>> +			shm_id_arr[num] = res;
>>   	}
>
> So we attempt to allocate SHMMNI shared memory segemnts and the last
> call will fail.
>
> I guess that we can as well attempt to allocate SHMMNI-1 segemnts and
> expect them to all pass. I do not like ignore any failures that may
> happen here and cary on with the test. It would be better to TBROK here
> instead.
>
Sounds reansonable. Will do it.
>> +	tst_res(TINFO, "The maximum number(%d) of memory ID's has been reached",
>> +		SHMMNI);
>>   }
>>
>> -/*
>> - * cleanup() - performs all the ONE TIME cleanup for this test at completion
>> - * 	       or premature exit.
>> - */
>> -void cleanup(void)
>> +
>> +static void cleanup(void)
>>   {
>>   	int i;
>>
>> -	/* remove the shared memory resources that were created */
>> -	for (i = 0; i<  num_shms; i++) {
>> -		rm_shm(shm_id_arr[i]);
>> +	for (i = 0; i<  SHMMNI; i++) {
>> +		if (shm_id_arr[i]>= 0)
>
> This is actually not correct, since there are possibly zeros in the
> array (just because it's global variable and only first position is
> intialized wiht -1) and we could incorrectly attempt to remove sement
> with id 0.
>
> I guess that the cleanest way how to handle this would be having global
> counter for the number of created semgents:
>
>
> static key_t *keys;
> static unsigned int max_key;
>
> setup()
> {
> 	...
> 	keys = SAFE_MALLOC(sizeof(key_t) * shmmni);
> 	...
>
> 	for (;;) {
> 		if (max_key>= shmni)
> 			break;
>
>
> 		keys[max_key] = shmget(...);
>
> 		if (keys[max_key]<  0)
> 			tst_brk(TBROK, ...);
>
> 		max_key++;
> 	}
> }
>
> cleanup()
> {
> 	key_t key;
>
> 	for (key = 0; key<  max_key; key++)
> 		SAFE_SHMCTL(keys[key], IPC_RMID, NULL);
> }
>
>
>
Yes, Will do it in v2.
>> +			SAFE_SHMCTL(shm_id_arr[i], IPC_RMID, NULL);
>>   	}
>> -
>> -	tst_rmdir();
>> -
>>   }
>> +
>> +static struct tst_test test = {
>> +	.setup = setup,
>> +	.cleanup = cleanup,
>> +	.test_all = verify_shmget,
>> +};
>> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget04.c b/testcases/kernel/syscalls/ipc/shmget/shmget04.c
>> index 60a263c77..fe611b306 100644
>
> ...
>
>> +	tst_res(TINFO, "%s", tc->message);
>> +	TEST(shmget(shmkey, SHM_SIZE, tc->flag));
>> +	if (TST_RET != -1) {
>> +		tst_res(TFAIL, "shmget() returned %li", TST_RET);
>> +		return;
>>   	}
>> -
>> -	cleanup();
>> -
>> -	tst_exit();
>> +	if (TST_ERR == EACCES)
>> +		tst_res(TPASS | TTERRNO, "shmget() failed as expected");
>> +	else
>> +		tst_res(TFAIL | TTERRNO, "shmget() failed unexpectedly, expected EACCES, bug got");
>
> TST_EXP_FAIL() here as well.
Will do it.

Best Regards
Yang Xu
>
>>   }
>>
>> -/*
>> - * setup() - performs all the ONE TIME setup for this test.
>> - */
>> -void setup(void)
>> +static void setup(void)
>>   {
>> -	tst_require_root();
>> -
>> -	tst_sig(NOFORK, DEF_HANDLER, cleanup);
>> +	struct passwd *pw;
>>
>> -	TEST_PAUSE;
>> -
>> -	/* Switch to nobody user for correct error code collection */
>> -	ltpuser = getpwnam(nobody_uid);
>> -	if (setuid(ltpuser->pw_uid) == -1) {
>> -		tst_resm(TINFO, "setuid failed to "
>> -			 "to set the effective uid to %d", ltpuser->pw_uid);
>> -		perror("setuid");
>> -	}
>> +	pw = SAFE_GETPWNAM("nobody");
>> +	SAFE_SETUID(pw->pw_uid);
>> +	shmkey = GETIPCKEY();
>>
>> -	/*
>> -	 * Create a temporary directory and cd into it.
>> -	 * This helps to ensure that a unique msgkey is created.
>> -	 * See libs/libltpipc/libipc.c for more information.
>> -	 */
>> -	tst_tmpdir();
>> -
>> -	/* get an IPC resource key */
>> -	shmkey = getipckey();
>> -
>> -	/* create a shared memory segment without read or access permissions */
>> -	if ((shm_id_1 = shmget(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL)) == -1) {
>> -		tst_brkm(TBROK, cleanup, "Failed to create shared memory "
>> -			 "segment in setup");
>> -	}
>> +	shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL);
>>   }
>>
>> -/*
>> - * cleanup() - performs all the ONE TIME cleanup for this test at completion
>> - * 	       or premature exit.
>> - */
>> -void cleanup(void)
>> +static void cleanup(void)
>>   {
>> -	/* if it exists, remove the shared memory resource */
>> -	rm_shm(shm_id_1);
>> -
>> -	tst_rmdir();
>> -
>> +	if (shm_id>= 0)
>> +		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
>>   }
>> +
>> +static struct tst_test test = {
>> +	.needs_tmpdir = 1,
>> +	.needs_root = 1,
>> +	.setup = setup,
>> +	.cleanup = cleanup,
>> +	.test = verify_shmget,
>> +	.tcnt = ARRAY_SIZE(tcases),
>> +};
>

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

* [LTP] [PATCH v2] syscalls/shmget*: Convert into new api
  2021-06-18 14:28   ` Cyril Hrubis
  2021-06-21  9:48     ` xuyang2018.jy
@ 2021-06-22  8:31     ` Yang Xu
  2021-06-23 13:35       ` Cyril Hrubis
  1 sibling, 1 reply; 21+ messages in thread
From: Yang Xu @ 2021-06-22  8:31 UTC (permalink / raw)
  To: ltp

1) merge shmget05.c into shmget02.c
2) Use SHMMIN -1 and SHMMAX + 1 to trigger EINVAL error
3) Use SHM_RD, SHM_WR, SHM_RW to trigger EACCES error under unpriviledged user
4) add EPERM error test
5) Use TST_EXP_FAIL macro

Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
---
 include/lapi/shm.h                            |  14 +
 runtest/syscalls                              |   1 -
 runtest/syscalls-ipc                          |   1 -
 .../kernel/syscalls/ipc/shmget/.gitignore     |   1 -
 testcases/kernel/syscalls/ipc/shmget/Makefile |   4 +-
 .../kernel/syscalls/ipc/shmget/shmget02.c     | 244 ++++++------------
 .../kernel/syscalls/ipc/shmget/shmget03.c     | 204 ++++-----------
 .../kernel/syscalls/ipc/shmget/shmget04.c     | 188 ++++----------
 .../kernel/syscalls/ipc/shmget/shmget05.c     | 185 -------------
 9 files changed, 206 insertions(+), 636 deletions(-)
 delete mode 100644 testcases/kernel/syscalls/ipc/shmget/shmget05.c

diff --git a/include/lapi/shm.h b/include/lapi/shm.h
index 61c4e37bf..bb280fc44 100644
--- a/include/lapi/shm.h
+++ b/include/lapi/shm.h
@@ -6,8 +6,22 @@
 #ifndef LAPI_SHM_H__
 #define LAPI_SHM_H__
 
+#include <limits.h>
+
 #ifndef SHM_STAT_ANY
 # define SHM_STAT_ANY 15
 #endif
 
+#ifndef SHMMIN
+# define SHMMIN 1
+#endif
+
+#ifndef SHMMAX
+# define SHMMAX (ULONG_MAX - (1UL << 24))
+#endif
+
+#ifndef SHMMNI
+# define SHMMNI 4096
+#endif
+
 #endif /* LAPI_SHM_H__ */
diff --git a/runtest/syscalls b/runtest/syscalls
index c989427c0..e1e932836 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1407,7 +1407,6 @@ shmdt02 shmdt02
 shmget02 shmget02
 shmget03 shmget03
 shmget04 shmget04
-shmget05 shmget05
 
 sigaction01 sigaction01
 sigaction02 sigaction02
diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
index ff0364704..b3bd37923 100644
--- a/runtest/syscalls-ipc
+++ b/runtest/syscalls-ipc
@@ -67,4 +67,3 @@ shmdt02 shmdt02
 shmget02 shmget02
 shmget03 shmget03
 shmget04 shmget04
-shmget05 shmget05
diff --git a/testcases/kernel/syscalls/ipc/shmget/.gitignore b/testcases/kernel/syscalls/ipc/shmget/.gitignore
index 6f08529f8..c57df68f5 100644
--- a/testcases/kernel/syscalls/ipc/shmget/.gitignore
+++ b/testcases/kernel/syscalls/ipc/shmget/.gitignore
@@ -1,4 +1,3 @@
 /shmget02
 /shmget03
 /shmget04
-/shmget05
diff --git a/testcases/kernel/syscalls/ipc/shmget/Makefile b/testcases/kernel/syscalls/ipc/shmget/Makefile
index 26b9f264d..b1201281d 100644
--- a/testcases/kernel/syscalls/ipc/shmget/Makefile
+++ b/testcases/kernel/syscalls/ipc/shmget/Makefile
@@ -3,10 +3,10 @@
 
 top_srcdir              ?= ../../../../..
 
-LTPLIBS = ltpipc
+LTPLIBS = ltpnewipc
 
 include $(top_srcdir)/include/mk/testcases.mk
 
-LTPLDLIBS  = -lltpipc
+LTPLDLIBS = -lltpnewipc
 
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget02.c b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
index 4436ca7f8..46ebea118 100644
--- a/testcases/kernel/syscalls/ipc/shmget/shmget02.c
+++ b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
@@ -1,184 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
+ * Copyright (c) International Business Machines  Corp., 2001
+ *  03/2001 - Written by Wayne Boyer
  *
- *   Copyright (c) International Business Machines  Corp., 2001
- *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) 2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
  */
 
-/*
- * NAME
- *	shmget02.c
- *
- * DESCRIPTION
- *	shmget02 - check for ENOENT, EEXIST and EINVAL errors
+/*\
+ * [Description]
  *
- * ALGORITHM
- *	create a shared memory segment with read & write permissions
- *	loop if that option was specified
- *	  call shmget() using five different invalid cases
- *	  check the errno value
- *	    issue a PASS message if we get ENOENT, EEXIST or EINVAL
- *	  otherwise, the tests fails
- *	    issue a FAIL message
- *	call cleanup
+ * Test for ENOENT, EEXIST, EINVAL, EACCES, EPERM errors.
  *
- * USAGE:  <for command-line>
- *  shmget02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- *     where,  -c n : Run n copies concurrently.
- *             -e   : Turn on errno logging.
- *	       -i n : Execute test n times.
- *	       -I x : Execute test for x seconds.
- *	       -P x : Pause for x seconds between iterations.
- *	       -t   : Turn on syscall timing.
- *
- * HISTORY
- *	03/2001 - Written by Wayne Boyer
- *
- *      06/03/2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
- *      - Fix concurrency issue. The second key used for this test could
- *        conflict with the key from another task.
- *
- * RESTRICTIONS
- *	none
+ * ENOENT - No segment exists for the given key and IPC_CREAT was not specified.
+ * EEXIST - the segment exists and IPC_CREAT | IPC_EXCL is given.
+ * EINVAL - A new segment was to be created and size is less than SHMMIN or
+ * greater than SHMMAX. Or a segment for the given key exists, but size is
+ * gran eater than the size of that segment.
+ * EACCES - The user does not have permission to access the shared memory segment.
+ * EPERM - The SHM_HUGETLB flag was specified, but the caller was not privileged
+ * (did not have the CAP_IPC_LOCK capability) and is not a member of the
+ * sysctl_hugetlb_shm_group group.
  */
 
-#include "ipcshm.h"
-
-char *TCID = "shmget02";
-int TST_TOTAL = 4;
-
-int shm_id_1 = -1;
-int shm_nonexisting_key = -1;
-key_t shmkey2;
-
-struct test_case_t {
-	int *skey;
-	int size;
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <stdlib.h>
+#include <pwd.h>
+#include <sys/shm.h>
+#include "tst_safe_sysv_ipc.h"
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "lapi/shm.h"
+
+static int shm_id = -1;
+static key_t shmkey, shmkey1;
+static struct passwd *pw;
+
+static struct tcase {
+	int *shmkey;
+	size_t size;
 	int flags;
-	int error;
-} TC[] = {
-	/* EINVAL - size is 0 */
-	{
-	&shmkey2, 0, IPC_CREAT | IPC_EXCL | SHM_RW, EINVAL},
-	    /* EINVAL - size is negative */
-//      {&shmkey2, -1, IPC_CREAT | IPC_EXCL | SHM_RW, EINVAL},
-	    /* EINVAL - size is larger than created segment */
-	{
-	&shmkey, SHM_SIZE * 2, SHM_RW, EINVAL},
-	    /* EEXIST - the segment exists and IPC_CREAT | IPC_EXCL is given */
-	{
-	&shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW, EEXIST},
-	    /* ENOENT - no segment exists for the key and IPC_CREAT is not given */
-	    /* use shm_id_2 (-1) as the key */
-	{
-	&shm_nonexisting_key, SHM_SIZE, SHM_RW, ENOENT}
+	/*1: nobody expected  0: root expected */
+	int exp_user;
+	int exp_err;
+} tcases[] = {
+	{&shmkey1, SHM_SIZE, IPC_EXCL, 0, ENOENT},
+	{&shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL, 0, EEXIST},
+	{&shmkey1, SHMMIN - 1, IPC_CREAT | IPC_EXCL, 0, EINVAL},
+	{&shmkey1, SHMMAX + 1, IPC_CREAT | IPC_EXCL, 0, EINVAL},
+	{&shmkey, SHM_SIZE * 2, IPC_EXCL, 0, EINVAL},
+	{&shmkey, SHM_SIZE, SHM_RD, 1, EACCES},
+	{&shmkey1, SHM_SIZE, IPC_CREAT | SHM_HUGETLB, 1, EPERM}
 };
 
-int main(int ac, char **av)
+static void do_test(unsigned int n)
 {
-	int lc;
-	int i;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();		/* global setup */
-
-	/* The following loop checks looping state if -i option given */
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
+	struct tcase *tc = &tcases[n];
+	pid_t pid;
 
-		/* loop through the test cases */
-		for (i = 0; i < TST_TOTAL; i++) {
-			/*
-			 * Look for a failure ...
-			 */
-
-			TEST(shmget(*(TC[i].skey), TC[i].size, TC[i].flags));
-
-			if (TEST_RETURN != -1) {
-				tst_resm(TFAIL, "call succeeded unexpectedly");
-				continue;
-			}
-
-			if (TEST_ERRNO == TC[i].error) {
-				tst_resm(TPASS, "expected failure - errno = "
-					 "%d : %s", TEST_ERRNO,
-					 strerror(TEST_ERRNO));
-			} else {
-				tst_resm(TFAIL, "call failed with an "
-					 "unexpected error - %d : %s",
-					 TEST_ERRNO, strerror(TEST_ERRNO));
-			}
-		}
+	if (tc->exp_user == 0) {
+		TST_EXP_FAIL(shmget(*tc->shmkey, tc->size, tc->flags), tc->exp_err,
+			"shmget(%i, %lu, %i)", *tc->shmkey, tc->size, tc->flags);
+		return;
 	}
 
-	cleanup();
-
-	tst_exit();
+	pid = SAFE_FORK();
+	if (pid == 0) {
+		SAFE_SETUID(pw->pw_uid);
+		TST_EXP_FAIL(shmget(*tc->shmkey, tc->size, tc->flags), tc->exp_err,
+			"shmget(%i, %lu, %i)", *tc->shmkey, tc->size, tc->flags);
+		exit(0);
+	}
+	tst_reap_children();
 }
 
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
+static void setup(void)
 {
+	shmkey = GETIPCKEY();
+	shmkey1 = GETIPCKEY();
 
-	tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
-
-	/*
-	 * Create a temporary directory and cd into it.
-	 * This helps to ensure that a unique msgkey is created.
-	 * See libs/libltpipc/libipc.c for more information.
-	 */
-	tst_tmpdir();
-
-	/* get an IPC resource key */
-	shmkey = getipckey();
-
-	/* Get an new IPC resource key. */
-	shmkey2 = getipckey();
-
-	if ((shm_id_1 = shmget(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL |
-			       SHM_RW)) == -1) {
-		tst_brkm(TBROK, cleanup, "couldn't create shared memory "
-			 "segment in setup()");
-	}
-
-	/* Make sure shm_nonexisting_key is a nonexisting key */
-	while (1) {
-		while (-1 != shmget(shm_nonexisting_key, 1, SHM_RD)) {
-			shm_nonexisting_key--;
-		}
-		if (errno == ENOENT)
-			break;
-	}
+	SAFE_FILE_PRINTF("/proc/sys/vm/hugetlb_shm_group", "1");
+	shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL);
+	pw = SAFE_GETPWNAM("nobody");
 }
 
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * 	       or premature exit.
- */
-void cleanup(void)
+static void cleanup(void)
 {
-	/* if it exists, remove the shared memory resource */
-	rm_shm(shm_id_1);
-
-	tst_rmdir();
-
+	if (shm_id >= 0)
+		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
 }
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.needs_root = 1,
+	.forks_child = 1,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test = do_test,
+	.tcnt = ARRAY_SIZE(tcases),
+	.save_restore = (const char * const[]) {
+		"?/proc/sys/vm/hugetlb_shm_group",
+		NULL,
+	}
+};
diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget03.c b/testcases/kernel/syscalls/ipc/shmget/shmget03.c
index 96ebf3608..d2e850b2a 100644
--- a/testcases/kernel/syscalls/ipc/shmget/shmget03.c
+++ b/testcases/kernel/syscalls/ipc/shmget/shmget03.c
@@ -1,171 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
- *
- *   Copyright (c) International Business Machines  Corp., 2001
- *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines  Corp., 2001
+ *  03/2001 - Written by Wayne Boyer
  */
 
-/*
- * NAME
- *	shmget03.c
+/*\
+ * [Description]
  *
- * DESCRIPTION
- *	shmget03 - test for ENOSPC error
+ * Test for ENOSPC error.
  *
- * ALGORITHM
- *	create shared memory segments in a loop until reaching the system limit
- *	loop if that option was specified
- *	  attempt to create yet another shared memory segment
- *	  check the errno value
- *	    issue a PASS message if we get ENOSPC
- *	  otherwise, the tests fails
- *	    issue a FAIL message
- *	call cleanup
- *
- * USAGE:  <for command-line>
- *  shmget03 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- *     where,  -c n : Run n copies concurrently.
- *             -e   : Turn on errno logging.
- *	       -i n : Execute test n times.
- *	       -I x : Execute test for x seconds.
- *	       -P x : Pause for x seconds between iterations.
- *	       -t   : Turn on syscall timing.
- *
- * HISTORY
- *	03/2001 - Written by Wayne Boyer
- *
- * RESTRICTIONS
- *	none
+ * ENOSPC -  All possible shared memory segments have been taken (SHMMNI).
  */
-
-#include "ipcshm.h"
-
-char *TCID = "shmget03";
-int TST_TOTAL = 1;
-
-/*
- * The MAXIDS value is somewhat arbitrary and may need to be increased
- * depending on the system being tested.
- */
-#define MAXIDS	8192
-
-int shm_id_1 = -1;
-int num_shms = 0;
-
-int shm_id_arr[MAXIDS];
-
-int main(int ac, char **av)
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <stdlib.h>
+#include <pwd.h>
+#include <sys/shm.h>
+#include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
+#include "libnewipc.h"
+
+static int *queues;
+static int maxshms;
+static key_t shmkey;
+
+static void verify_shmget(void)
 {
-	int lc;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();		/* global setup */
-
-	/* The following loop checks looping state if -i option given */
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		/*
-		 * use the TEST() macro to make the call
-		 */
-
-		TEST(shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | IPC_EXCL
-			    | SHM_RW));
-
-		if (TEST_RETURN != -1) {
-			tst_resm(TFAIL, "call succeeded when error expected");
-			continue;
-		}
-
-		switch (TEST_ERRNO) {
-		case ENOSPC:
-			tst_resm(TPASS, "expected failure - errno = "
-				 "%d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
-			break;
-		default:
-			tst_resm(TFAIL, "call failed with an "
-				 "unexpected error - %d : %s",
-				 TEST_ERRNO, strerror(TEST_ERRNO));
-			break;
-		}
-	}
-
-	cleanup();
-
-	tst_exit();
+	TST_EXP_FAIL(shmget(shmkey + maxshms, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW), ENOSPC,
+		"shmget(%i, %i, %i)", shmkey + maxshms, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW);
 }
 
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
+static void setup(void)
 {
+	int res, num;
 
-	tst_sig(NOFORK, DEF_HANDLER, cleanup);
+	shmkey = GETIPCKEY();
 
-	TEST_PAUSE;
+	SAFE_FILE_SCANF("/proc/sys/kernel/shmmni", "%i", &maxshms);
 
-	/*
-	 * Create a temporary directory and cd into it.
-	 * This helps to ensure that a unique msgkey is created.
-	 * See libs/libltpipc/libipc.c for more information.
-	 */
-	tst_tmpdir();
-
-	/* get an IPC resource key */
-	shmkey = getipckey();
-
-	/*
-	 * Use a while loop to create the maximum number of memory segments.
-	 * If the loop exceeds MAXIDS, then break the test and cleanup.
-	 */
-	while ((shm_id_1 = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT |
-				  IPC_EXCL | SHM_RW)) != -1) {
-		shm_id_arr[num_shms++] = shm_id_1;
-		if (num_shms == MAXIDS) {
-			tst_brkm(TBROK, cleanup, "The maximum number of shared "
-				 "memory ID's has been\n\t reached.  Please "
-				 "increase the MAXIDS value in the test.");
-		}
-	}
-
-	/*
-	 * If the errno is other than ENOSPC, then something else is wrong.
-	 */
-	if (errno != ENOSPC) {
-		tst_resm(TINFO, "errno = %d : %s", errno, strerror(errno));
-		tst_brkm(TBROK, cleanup, "Didn't get ENOSPC in test setup");
+	queues = SAFE_MALLOC(maxshms * sizeof(int));
+	for (num = 0; num < maxshms; num++) {
+		queues[num] = -1;
+		res = shmget(shmkey + num, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW);
+		if (res != -1)
+			queues[num] = res;
+		else
+			tst_brk(TBROK | TERRNO, "shmget failed unexpectedly");
 	}
+	tst_res(TINFO, "The maximum number of memory segments (%d) has been reached",
+		maxshms);
 }
 
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test@completion
- * 	       or premature exit.
- */
-void cleanup(void)
+static void cleanup(void)
 {
-	int i;
+	int num;
 
-	/* remove the shared memory resources that were created */
-	for (i = 0; i < num_shms; i++) {
-		rm_shm(shm_id_arr[i]);
-	}
+	if (!queues)
+		return;
 
-	tst_rmdir();
+	for (num = 0; num < maxshms; num++) {
+		if (queues[num] != -1)
+			SAFE_SHMCTL(queues[num], IPC_RMID, NULL);
+	}
 
+	free(queues);
 }
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = verify_shmget,
+};
diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget04.c b/testcases/kernel/syscalls/ipc/shmget/shmget04.c
index 60a263c77..d92dfe635 100644
--- a/testcases/kernel/syscalls/ipc/shmget/shmget04.c
+++ b/testcases/kernel/syscalls/ipc/shmget/shmget04.c
@@ -1,153 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
- *
- *   Copyright (c) International Business Machines  Corp., 2001
- *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines  Corp., 2001
+ *  03/2001 - Written by Wayne Boyer
  */
 
-/*
- * NAME
- *	shmget04.c
- *
- * DESCRIPTION
- *	shmget04 - test for EACCES error
- *
- * ALGORITHM
- *	create a shared memory segment without read or write permissions
- *	loop if that option was specified
- *	  call shmget() with SHM_RW flag using TEST() macro
- *	  check the errno value
- *	    issue a PASS message if we get EACCES
- *	  otherwise, the tests fails
- *	    issue a FAIL message
- *	call cleanup
- *
- * USAGE:  <for command-line>
- *  shmget04 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- *     where,  -c n : Run n copies concurrently.
- *             -e   : Turn on errno logging.
- *	       -i n : Execute test n times.
- *	       -I x : Execute test for x seconds.
- *	       -P x : Pause for x seconds between iterations.
- *	       -t   : Turn on syscall timing.
+/*\
+ * [Description]
  *
- * HISTORY
- *	03/2001 - Written by Wayne Boyer
+ * Test for EACCES error.
  *
- * RESTRICTIONS
- *	none
+ * Create a shared memory segment without read or write permissions under
+ * unpriviledged user and call shmget() with SHM_RD/SHM_WR/SHM_RW flag to
+ * trigger EACCES error.
  */
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <stdlib.h>
 #include <pwd.h>
-#include "ipcshm.h"
-
-char *TCID = "shmget04";
-int TST_TOTAL = 1;
-
-char nobody_uid[] = "nobody";
-struct passwd *ltpuser;
-
-int shm_id_1 = -1;
-
-int main(int ac, char **av)
+#include <sys/shm.h>
+#include "tst_safe_sysv_ipc.h"
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "lapi/shm.h"
+
+static int shm_id = -1;
+static key_t shmkey;
+static struct tcase {
+	char *message;
+	int flag;
+} tcases[] = {
+	{"Testing SHM_RD flag", SHM_RD},
+	{"Testing SHM_WR flag", SHM_WR},
+	{"Testing SHM_RW flag", SHM_RW},
+};
+
+static void verify_shmget(unsigned int n)
 {
-	int lc;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();		/* global setup */
-
-	/* The following loop checks looping state if -i option given */
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
+	struct tcase *tc = &tcases[n];
 
-		/*
-		 * use the TEST() macro to make the call
-		 */
-
-		TEST(shmget(shmkey, SHM_SIZE, SHM_RW));
-
-		if (TEST_RETURN != -1) {
-			tst_resm(TFAIL, "call succeeded when error expected");
-			continue;
-		}
-
-		switch (TEST_ERRNO) {
-		case EACCES:
-			tst_resm(TPASS, "expected failure - errno = "
-				 "%d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
-			break;
-		default:
-			tst_resm(TFAIL, "call failed with an "
-				 "unexpected error - %d : %s",
-				 TEST_ERRNO, strerror(TEST_ERRNO));
-			break;
-		}
-	}
-
-	cleanup();
-
-	tst_exit();
+	tst_res(TINFO, "%s", tc->message);
+	TST_EXP_FAIL(shmget(shmkey, SHM_SIZE, tc->flag), EACCES, "shmget(%i, %i, %i)",
+		shmkey, SHM_SIZE, tc->flag);
 }
 
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
+static void setup(void)
 {
-	tst_require_root();
-
-	tst_sig(NOFORK, DEF_HANDLER, cleanup);
+	struct passwd *pw;
 
-	TEST_PAUSE;
+	pw = SAFE_GETPWNAM("nobody");
+	SAFE_SETUID(pw->pw_uid);
+	shmkey = GETIPCKEY();
 
-	/* Switch to nobody user for correct error code collection */
-	ltpuser = getpwnam(nobody_uid);
-	if (setuid(ltpuser->pw_uid) == -1) {
-		tst_resm(TINFO, "setuid failed to "
-			 "to set the effective uid to %d", ltpuser->pw_uid);
-		perror("setuid");
-	}
-
-	/*
-	 * Create a temporary directory and cd into it.
-	 * This helps to ensure that a unique msgkey is created.
-	 * See libs/libltpipc/libipc.c for more information.
-	 */
-	tst_tmpdir();
-
-	/* get an IPC resource key */
-	shmkey = getipckey();
-
-	/* create a shared memory segment without read or access permissions */
-	if ((shm_id_1 = shmget(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL)) == -1) {
-		tst_brkm(TBROK, cleanup, "Failed to create shared memory "
-			 "segment in setup");
-	}
+	shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL);
 }
 
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * 	       or premature exit.
- */
-void cleanup(void)
+static void cleanup(void)
 {
-	/* if it exists, remove the shared memory resource */
-	rm_shm(shm_id_1);
-
-	tst_rmdir();
-
+	if (shm_id >= 0)
+		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
 }
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.needs_root = 1,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test = verify_shmget,
+	.tcnt = ARRAY_SIZE(tcases),
+};
diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget05.c b/testcases/kernel/syscalls/ipc/shmget/shmget05.c
deleted file mode 100644
index de9544591..000000000
--- a/testcases/kernel/syscalls/ipc/shmget/shmget05.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- *
- *   Copyright (c) International Business Machines  Corp., 2001
- *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * NAME
- *	shmget05.c
- *
- * DESCRIPTION
- *	shmget05 - test for EACCES error
- *
- * ALGORITHM
- *	create a shared memory segment with root only read & write permissions
- *	fork a child process
- *	if child
- *	  set the ID of the child process to that of "nobody"
- *	  loop if that option was specified
- *	    call shmget() using the TEST() macro
- *	    check the errno value
- *	      issue a PASS message if we get EACCES
- *	    otherwise, the tests fails
- *	      issue a FAIL message
- *	  call cleanup
- *	if parent
- *	  wait for child to exit
- *	  remove the shared memory segment
- *
- * USAGE:  <for command-line>
- *  shmget05 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- *     where,  -c n : Run n copies concurrently.
- *             -e   : Turn on errno logging.
- *	       -i n : Execute test n times.
- *	       -I x : Execute test for x seconds.
- *	       -P x : Pause for x seconds between iterations.
- *	       -t   : Turn on syscall timing.
- *
- * HISTORY
- *	03/2001 - Written by Wayne Boyer
- *
- * RESTRICTIONS
- *	test must be run at root
- */
-
-#include "ipcshm.h"
-#include <sys/types.h>
-#include <sys/wait.h>
-#include "safe_macros.h"
-
-char *TCID = "shmget05";
-int TST_TOTAL = 1;
-
-int shm_id_1 = -1;
-
-uid_t ltp_uid;
-char *ltp_user = "nobody";
-
-int main(int ac, char **av)
-{
-	int pid;
-	void do_child(void);
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();		/* global setup */
-
-	if ((pid = FORK_OR_VFORK()) == -1) {
-		tst_brkm(TBROK, cleanup, "could not fork");
-	}
-
-	if (pid == 0) {		/* child */
-		/* set the user ID of the child to the non root user */
-		if (setuid(ltp_uid) == -1) {
-			tst_resm(TBROK, "setuid() failed");
-			exit(1);
-		}
-
-		do_child();
-
-		cleanup();
-
-	} else {		/* parent */
-		/* wait for the child to return */
-		SAFE_WAITPID(cleanup, pid, NULL, 0);
-
-		/* if it exists, remove the shared memory resource */
-		rm_shm(shm_id_1);
-
-		tst_rmdir();
-	}
-	tst_exit();
-}
-
-/*
- * do_child - make the TEST call as the child process
- */
-void do_child(void)
-{
-	int lc;
-
-	/* The following loop checks looping state if -i option given */
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		/*
-		 * Look for a failure ...
-		 */
-
-		TEST(shmget(shmkey, SHM_SIZE, SHM_RW));
-
-		if (TEST_RETURN != -1) {
-			tst_resm(TFAIL, "call succeeded when error expected");
-			continue;
-		}
-
-		switch (TEST_ERRNO) {
-		case EACCES:
-			tst_resm(TPASS, "expected failure - errno = "
-				 "%d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
-			break;
-		default:
-			tst_resm(TFAIL, "call failed with an "
-				 "unexpected error - %d : %s",
-				 TEST_ERRNO, strerror(TEST_ERRNO));
-			break;
-		}
-	}
-}
-
-/*
- * setup() - performs all the ONE TIME setup for this test.
- */
-void setup(void)
-{
-	tst_require_root();
-
-	tst_sig(FORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
-
-	/*
-	 * Create a temporary directory and cd into it.
-	 * This helps to ensure that a unique msgkey is created.
-	 * See libs/libltpipc/libipc.c for more information.
-	 */
-	tst_tmpdir();
-
-	/* get an IPC resource key */
-	shmkey = getipckey();
-
-	/* create a shared memory segment with read and write permissions */
-	if ((shm_id_1 = shmget(shmkey, SHM_SIZE,
-			       SHM_RW | IPC_CREAT | IPC_EXCL)) == -1) {
-		tst_brkm(TBROK, cleanup, "Failed to create shared memory "
-			 "segment in setup");
-	}
-
-	/* get the userid for a non root user */
-	ltp_uid = getuserid(ltp_user);
-}
-
-/*
- * cleanup() - performs all the ONE TIME cleanup for this test at completion
- * 	       or premature exit.
- */
-void cleanup(void)
-{
-
-}
-- 
2.23.0


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

* [LTP] [PATCH v2] syscalls/shmget*: Convert into new api
  2021-06-22  8:31     ` [LTP] [PATCH v2] " Yang Xu
@ 2021-06-23 13:35       ` Cyril Hrubis
  2021-06-24  3:46         ` xuyang2018.jy
  0 siblings, 1 reply; 21+ messages in thread
From: Cyril Hrubis @ 2021-06-23 13:35 UTC (permalink / raw)
  To: ltp

Hi!
> 1) merge shmget05.c into shmget02.c
> 2) Use SHMMIN -1 and SHMMAX + 1 to trigger EINVAL error
> 3) Use SHM_RD, SHM_WR, SHM_RW to trigger EACCES error under unpriviledged user
> 4) add EPERM error test
> 5) Use TST_EXP_FAIL macro
> 
> Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
> ---
>  include/lapi/shm.h                            |  14 +
>  runtest/syscalls                              |   1 -
>  runtest/syscalls-ipc                          |   1 -
>  .../kernel/syscalls/ipc/shmget/.gitignore     |   1 -
>  testcases/kernel/syscalls/ipc/shmget/Makefile |   4 +-
>  .../kernel/syscalls/ipc/shmget/shmget02.c     | 244 ++++++------------
>  .../kernel/syscalls/ipc/shmget/shmget03.c     | 204 ++++-----------
>  .../kernel/syscalls/ipc/shmget/shmget04.c     | 188 ++++----------
>  .../kernel/syscalls/ipc/shmget/shmget05.c     | 185 -------------
>  9 files changed, 206 insertions(+), 636 deletions(-)
>  delete mode 100644 testcases/kernel/syscalls/ipc/shmget/shmget05.c
> 
> diff --git a/include/lapi/shm.h b/include/lapi/shm.h
> index 61c4e37bf..bb280fc44 100644
> --- a/include/lapi/shm.h
> +++ b/include/lapi/shm.h
> @@ -6,8 +6,22 @@
>  #ifndef LAPI_SHM_H__
>  #define LAPI_SHM_H__
>  
> +#include <limits.h>
> +
>  #ifndef SHM_STAT_ANY
>  # define SHM_STAT_ANY 15
>  #endif
>  
> +#ifndef SHMMIN
> +# define SHMMIN 1
> +#endif
> +
> +#ifndef SHMMAX
> +# define SHMMAX (ULONG_MAX - (1UL << 24))
> +#endif
> +
> +#ifndef SHMMNI
> +# define SHMMNI 4096
> +#endif
> +
>  #endif /* LAPI_SHM_H__ */
> diff --git a/runtest/syscalls b/runtest/syscalls
> index c989427c0..e1e932836 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -1407,7 +1407,6 @@ shmdt02 shmdt02
>  shmget02 shmget02
>  shmget03 shmget03
>  shmget04 shmget04
> -shmget05 shmget05
>  
>  sigaction01 sigaction01
>  sigaction02 sigaction02
> diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
> index ff0364704..b3bd37923 100644
> --- a/runtest/syscalls-ipc
> +++ b/runtest/syscalls-ipc
> @@ -67,4 +67,3 @@ shmdt02 shmdt02
>  shmget02 shmget02
>  shmget03 shmget03
>  shmget04 shmget04
> -shmget05 shmget05
> diff --git a/testcases/kernel/syscalls/ipc/shmget/.gitignore b/testcases/kernel/syscalls/ipc/shmget/.gitignore
> index 6f08529f8..c57df68f5 100644
> --- a/testcases/kernel/syscalls/ipc/shmget/.gitignore
> +++ b/testcases/kernel/syscalls/ipc/shmget/.gitignore
> @@ -1,4 +1,3 @@
>  /shmget02
>  /shmget03
>  /shmget04
> -/shmget05
> diff --git a/testcases/kernel/syscalls/ipc/shmget/Makefile b/testcases/kernel/syscalls/ipc/shmget/Makefile
> index 26b9f264d..b1201281d 100644
> --- a/testcases/kernel/syscalls/ipc/shmget/Makefile
> +++ b/testcases/kernel/syscalls/ipc/shmget/Makefile
> @@ -3,10 +3,10 @@
>  
>  top_srcdir              ?= ../../../../..
>  
> -LTPLIBS = ltpipc
> +LTPLIBS = ltpnewipc
>  
>  include $(top_srcdir)/include/mk/testcases.mk
>  
> -LTPLDLIBS  = -lltpipc
> +LTPLDLIBS = -lltpnewipc
>  
>  include $(top_srcdir)/include/mk/generic_leaf_target.mk
> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget02.c b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
> index 4436ca7f8..46ebea118 100644
> --- a/testcases/kernel/syscalls/ipc/shmget/shmget02.c
> +++ b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
> @@ -1,184 +1,106 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
>  /*
> + * Copyright (c) International Business Machines  Corp., 2001
> + *  03/2001 - Written by Wayne Boyer
>   *
> - *   Copyright (c) International Business Machines  Corp., 2001
> - *
> - *   This program is free software;  you can redistribute it and/or modify
> - *   it under the terms of the GNU General Public License as published by
> - *   the Free Software Foundation; either version 2 of the License, or
> - *   (at your option) any later version.
> - *
> - *   This program is distributed in the hope that it will be useful,
> - *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
> - *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
> - *   the GNU General Public License for more details.
> - *
> - *   You should have received a copy of the GNU General Public License
> - *   along with this program;  if not, write to the Free Software
> - *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + * Copyright (c) 2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
>   */
>  
> -/*
> - * NAME
> - *	shmget02.c
> - *
> - * DESCRIPTION
> - *	shmget02 - check for ENOENT, EEXIST and EINVAL errors
> +/*\
> + * [Description]
>   *
> - * ALGORITHM
> - *	create a shared memory segment with read & write permissions
> - *	loop if that option was specified
> - *	  call shmget() using five different invalid cases
> - *	  check the errno value
> - *	    issue a PASS message if we get ENOENT, EEXIST or EINVAL
> - *	  otherwise, the tests fails
> - *	    issue a FAIL message
> - *	call cleanup
> + * Test for ENOENT, EEXIST, EINVAL, EACCES, EPERM errors.
>   *
> - * USAGE:  <for command-line>
> - *  shmget02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
> - *     where,  -c n : Run n copies concurrently.
> - *             -e   : Turn on errno logging.
> - *	       -i n : Execute test n times.
> - *	       -I x : Execute test for x seconds.
> - *	       -P x : Pause for x seconds between iterations.
> - *	       -t   : Turn on syscall timing.
> - *
> - * HISTORY
> - *	03/2001 - Written by Wayne Boyer
> - *
> - *      06/03/2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
> - *      - Fix concurrency issue. The second key used for this test could
> - *        conflict with the key from another task.
> - *
> - * RESTRICTIONS
> - *	none
> + * ENOENT - No segment exists for the given key and IPC_CREAT was not specified.
> + * EEXIST - the segment exists and IPC_CREAT | IPC_EXCL is given.
> + * EINVAL - A new segment was to be created and size is less than SHMMIN or
> + * greater than SHMMAX. Or a segment for the given key exists, but size is
> + * gran eater than the size of that segment.
> + * EACCES - The user does not have permission to access the shared memory segment.
> + * EPERM - The SHM_HUGETLB flag was specified, but the caller was not privileged
> + * (did not have the CAP_IPC_LOCK capability) and is not a member of the
> + * sysctl_hugetlb_shm_group group.
>   */
>  
> -#include "ipcshm.h"
> -
> -char *TCID = "shmget02";
> -int TST_TOTAL = 4;
> -
> -int shm_id_1 = -1;
> -int shm_nonexisting_key = -1;
> -key_t shmkey2;
> -
> -struct test_case_t {
> -	int *skey;
> -	int size;
> +#include <errno.h>
> +#include <sys/types.h>
> +#include <sys/ipc.h>
> +#include <stdlib.h>
> +#include <pwd.h>
> +#include <sys/shm.h>
> +#include "tst_safe_sysv_ipc.h"
> +#include "tst_test.h"
> +#include "libnewipc.h"
> +#include "lapi/shm.h"
> +
> +static int shm_id = -1;
> +static key_t shmkey, shmkey1;
> +static struct passwd *pw;
> +
> +static struct tcase {
> +	int *shmkey;
> +	size_t size;
>  	int flags;
> -	int error;
> -} TC[] = {
> -	/* EINVAL - size is 0 */
> -	{
> -	&shmkey2, 0, IPC_CREAT | IPC_EXCL | SHM_RW, EINVAL},
> -	    /* EINVAL - size is negative */
> -//      {&shmkey2, -1, IPC_CREAT | IPC_EXCL | SHM_RW, EINVAL},
> -	    /* EINVAL - size is larger than created segment */
> -	{
> -	&shmkey, SHM_SIZE * 2, SHM_RW, EINVAL},
> -	    /* EEXIST - the segment exists and IPC_CREAT | IPC_EXCL is given */
> -	{
> -	&shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW, EEXIST},
> -	    /* ENOENT - no segment exists for the key and IPC_CREAT is not given */
> -	    /* use shm_id_2 (-1) as the key */
> -	{
> -	&shm_nonexisting_key, SHM_SIZE, SHM_RW, ENOENT}
> +	/*1: nobody expected  0: root expected */
> +	int exp_user;
> +	int exp_err;
> +} tcases[] = {
> +	{&shmkey1, SHM_SIZE, IPC_EXCL, 0, ENOENT},
> +	{&shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL, 0, EEXIST},
> +	{&shmkey1, SHMMIN - 1, IPC_CREAT | IPC_EXCL, 0, EINVAL},
> +	{&shmkey1, SHMMAX + 1, IPC_CREAT | IPC_EXCL, 0, EINVAL},
> +	{&shmkey, SHM_SIZE * 2, IPC_EXCL, 0, EINVAL},
> +	{&shmkey, SHM_SIZE, SHM_RD, 1, EACCES},
> +	{&shmkey1, SHM_SIZE, IPC_CREAT | SHM_HUGETLB, 1, EPERM}

This case is a bit more complicated, on my test machine with
nr_hugepages == 0 I get ENOMEM, since there are no hugepages allocated
in the pool.

When I add .request_hugepages = 1, the the tst_test structure, the
hugepage pool size is increased by the test library and this request
succeds and creates a SHM segment. See description below on how this has
to be fixed.

>  };
>  
> -int main(int ac, char **av)
> +static void do_test(unsigned int n)
>  {
> -	int lc;
> -	int i;
> -
> -	tst_parse_opts(ac, av, NULL, NULL);
> -
> -	setup();		/* global setup */
> -
> -	/* The following loop checks looping state if -i option given */
> -
> -	for (lc = 0; TEST_LOOPING(lc); lc++) {
> -		/* reset tst_count in case we are looping */
> -		tst_count = 0;
> +	struct tcase *tc = &tcases[n];
> +	pid_t pid;
>  
> -		/* loop through the test cases */
> -		for (i = 0; i < TST_TOTAL; i++) {
> -			/*
> -			 * Look for a failure ...
> -			 */
> -
> -			TEST(shmget(*(TC[i].skey), TC[i].size, TC[i].flags));
> -
> -			if (TEST_RETURN != -1) {
> -				tst_resm(TFAIL, "call succeeded unexpectedly");
> -				continue;
> -			}
> -
> -			if (TEST_ERRNO == TC[i].error) {
> -				tst_resm(TPASS, "expected failure - errno = "
> -					 "%d : %s", TEST_ERRNO,
> -					 strerror(TEST_ERRNO));
> -			} else {
> -				tst_resm(TFAIL, "call failed with an "
> -					 "unexpected error - %d : %s",
> -					 TEST_ERRNO, strerror(TEST_ERRNO));
> -			}
> -		}
> +	if (tc->exp_user == 0) {
> +		TST_EXP_FAIL(shmget(*tc->shmkey, tc->size, tc->flags), tc->exp_err,
> +			"shmget(%i, %lu, %i)", *tc->shmkey, tc->size, tc->flags);
> +		return;
>  	}
>  
> -	cleanup();
> -
> -	tst_exit();
> +	pid = SAFE_FORK();
> +	if (pid == 0) {
> +		SAFE_SETUID(pw->pw_uid);
> +		TST_EXP_FAIL(shmget(*tc->shmkey, tc->size, tc->flags), tc->exp_err,
> +			"shmget(%i, %lu, %i)", *tc->shmkey, tc->size, tc->flags);
> +		exit(0);
> +	}
> +	tst_reap_children();
>  }
>  
> -/*
> - * setup() - performs all the ONE TIME setup for this test.
> - */
> -void setup(void)
> +static void setup(void)
>  {
> +	shmkey = GETIPCKEY();
> +	shmkey1 = GETIPCKEY();
>  
> -	tst_sig(NOFORK, DEF_HANDLER, cleanup);
> -
> -	TEST_PAUSE;
> -
> -	/*
> -	 * Create a temporary directory and cd into it.
> -	 * This helps to ensure that a unique msgkey is created.
> -	 * See libs/libltpipc/libipc.c for more information.
> -	 */
> -	tst_tmpdir();
> -
> -	/* get an IPC resource key */
> -	shmkey = getipckey();
> -
> -	/* Get an new IPC resource key. */
> -	shmkey2 = getipckey();
> -
> -	if ((shm_id_1 = shmget(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL |
> -			       SHM_RW)) == -1) {
> -		tst_brkm(TBROK, cleanup, "couldn't create shared memory "
> -			 "segment in setup()");
> -	}
> -
> -	/* Make sure shm_nonexisting_key is a nonexisting key */
> -	while (1) {
> -		while (-1 != shmget(shm_nonexisting_key, 1, SHM_RD)) {
> -			shm_nonexisting_key--;
> -		}
> -		if (errno == ENOENT)
> -			break;
> -	}
> +	SAFE_FILE_PRINTF("/proc/sys/vm/hugetlb_shm_group", "1");

There is no need to change the default hugetlb group, all that has to be
done is to strip the user of all groups as well as there is absolutely
no guarantee that group 1 will not be in the list of supplementary
groups for a root users.

So when we change uid we as well have to do:

	setgroups(0, NULL);
	SAFE_SETGID(pw->pw_gid);
	SAFE_SETUID(pw->pw_uid);

This will strip the process of all additional permissions that may have
been passed down by the process running under root.

Also ideally we should add SAFE_SETGROUPS() to the test library in a
separate patch so that we can make use of it here.

> +	shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL);
> +	pw = SAFE_GETPWNAM("nobody");
>  }
>  
> -/*
> - * cleanup() - performs all the ONE TIME cleanup for this test at completion
> - * 	       or premature exit.
> - */
> -void cleanup(void)
> +static void cleanup(void)
>  {
> -	/* if it exists, remove the shared memory resource */
> -	rm_shm(shm_id_1);
> -
> -	tst_rmdir();
> -
> +	if (shm_id >= 0)
> +		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
>  }
> +
> +static struct tst_test test = {
> +	.needs_tmpdir = 1,
> +	.needs_root = 1,
> +	.forks_child = 1,
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.test = do_test,
> +	.tcnt = ARRAY_SIZE(tcases),
> +	.save_restore = (const char * const[]) {
> +		"?/proc/sys/vm/hugetlb_shm_group",
> +		NULL,
> +	}
> +};
> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget03.c b/testcases/kernel/syscalls/ipc/shmget/shmget03.c
> index 96ebf3608..d2e850b2a 100644
> --- a/testcases/kernel/syscalls/ipc/shmget/shmget03.c
> +++ b/testcases/kernel/syscalls/ipc/shmget/shmget03.c
> @@ -1,171 +1,75 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
>  /*
> - *
> - *   Copyright (c) International Business Machines  Corp., 2001
> - *
> - *   This program is free software;  you can redistribute it and/or modify
> - *   it under the terms of the GNU General Public License as published by
> - *   the Free Software Foundation; either version 2 of the License, or
> - *   (at your option) any later version.
> - *
> - *   This program is distributed in the hope that it will be useful,
> - *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
> - *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
> - *   the GNU General Public License for more details.
> - *
> - *   You should have received a copy of the GNU General Public License
> - *   along with this program;  if not, write to the Free Software
> - *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + * Copyright (c) International Business Machines  Corp., 2001
> + *  03/2001 - Written by Wayne Boyer
>   */
>  
> -/*
> - * NAME
> - *	shmget03.c
> +/*\
> + * [Description]
>   *
> - * DESCRIPTION
> - *	shmget03 - test for ENOSPC error
> + * Test for ENOSPC error.
>   *
> - * ALGORITHM
> - *	create shared memory segments in a loop until reaching the system limit
> - *	loop if that option was specified
> - *	  attempt to create yet another shared memory segment
> - *	  check the errno value
> - *	    issue a PASS message if we get ENOSPC
> - *	  otherwise, the tests fails
> - *	    issue a FAIL message
> - *	call cleanup
> - *
> - * USAGE:  <for command-line>
> - *  shmget03 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
> - *     where,  -c n : Run n copies concurrently.
> - *             -e   : Turn on errno logging.
> - *	       -i n : Execute test n times.
> - *	       -I x : Execute test for x seconds.
> - *	       -P x : Pause for x seconds between iterations.
> - *	       -t   : Turn on syscall timing.
> - *
> - * HISTORY
> - *	03/2001 - Written by Wayne Boyer
> - *
> - * RESTRICTIONS
> - *	none
> + * ENOSPC -  All possible shared memory segments have been taken (SHMMNI).
>   */
> -
> -#include "ipcshm.h"
> -
> -char *TCID = "shmget03";
> -int TST_TOTAL = 1;
> -
> -/*
> - * The MAXIDS value is somewhat arbitrary and may need to be increased
> - * depending on the system being tested.
> - */
> -#define MAXIDS	8192
> -
> -int shm_id_1 = -1;
> -int num_shms = 0;
> -
> -int shm_id_arr[MAXIDS];
> -
> -int main(int ac, char **av)
> +#include <errno.h>
> +#include <sys/types.h>
> +#include <sys/ipc.h>
> +#include <stdlib.h>
> +#include <pwd.h>
> +#include <sys/shm.h>
> +#include "tst_test.h"
> +#include "tst_safe_sysv_ipc.h"
> +#include "libnewipc.h"
> +
> +static int *queues;
> +static int maxshms;
> +static key_t shmkey;
> +
> +static void verify_shmget(void)
>  {
> -	int lc;
> -
> -	tst_parse_opts(ac, av, NULL, NULL);
> -
> -	setup();		/* global setup */
> -
> -	/* The following loop checks looping state if -i option given */
> -
> -	for (lc = 0; TEST_LOOPING(lc); lc++) {
> -		/* reset tst_count in case we are looping */
> -		tst_count = 0;
> -
> -		/*
> -		 * use the TEST() macro to make the call
> -		 */
> -
> -		TEST(shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | IPC_EXCL
> -			    | SHM_RW));
> -
> -		if (TEST_RETURN != -1) {
> -			tst_resm(TFAIL, "call succeeded when error expected");
> -			continue;
> -		}
> -
> -		switch (TEST_ERRNO) {
> -		case ENOSPC:
> -			tst_resm(TPASS, "expected failure - errno = "
> -				 "%d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
> -			break;
> -		default:
> -			tst_resm(TFAIL, "call failed with an "
> -				 "unexpected error - %d : %s",
> -				 TEST_ERRNO, strerror(TEST_ERRNO));
> -			break;
> -		}
> -	}
> -
> -	cleanup();
> -
> -	tst_exit();
> +	TST_EXP_FAIL(shmget(shmkey + maxshms, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW), ENOSPC,
> +		"shmget(%i, %i, %i)", shmkey + maxshms, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW);
>  }
>  
> -/*
> - * setup() - performs all the ONE TIME setup for this test.
> - */
> -void setup(void)
> +static void setup(void)
>  {
> +	int res, num;
>  
> -	tst_sig(NOFORK, DEF_HANDLER, cleanup);
> +	shmkey = GETIPCKEY();
>  
> -	TEST_PAUSE;
> +	SAFE_FILE_SCANF("/proc/sys/kernel/shmmni", "%i", &maxshms);
>  
> -	/*
> -	 * Create a temporary directory and cd into it.
> -	 * This helps to ensure that a unique msgkey is created.
> -	 * See libs/libltpipc/libipc.c for more information.
> -	 */
> -	tst_tmpdir();
> -
> -	/* get an IPC resource key */
> -	shmkey = getipckey();
> -
> -	/*
> -	 * Use a while loop to create the maximum number of memory segments.
> -	 * If the loop exceeds MAXIDS, then break the test and cleanup.
> -	 */
> -	while ((shm_id_1 = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT |
> -				  IPC_EXCL | SHM_RW)) != -1) {
> -		shm_id_arr[num_shms++] = shm_id_1;
> -		if (num_shms == MAXIDS) {
> -			tst_brkm(TBROK, cleanup, "The maximum number of shared "
> -				 "memory ID's has been\n\t reached.  Please "
> -				 "increase the MAXIDS value in the test.");
> -		}
> -	}
> -
> -	/*
> -	 * If the errno is other than ENOSPC, then something else is wrong.
> -	 */
> -	if (errno != ENOSPC) {
> -		tst_resm(TINFO, "errno = %d : %s", errno, strerror(errno));
> -		tst_brkm(TBROK, cleanup, "Didn't get ENOSPC in test setup");
> +	queues = SAFE_MALLOC(maxshms * sizeof(int));
> +	for (num = 0; num < maxshms; num++) {
> +		queues[num] = -1;
> +		res = shmget(shmkey + num, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW);
> +		if (res != -1)
> +			queues[num] = res;
> +		else
> +			tst_brk(TBROK | TERRNO, "shmget failed unexpectedly");
>  	}
> +	tst_res(TINFO, "The maximum number of memory segments (%d) has been reached",
> +		maxshms);
>  }
>  
> -/*
> - * cleanup() - performs all the ONE TIME cleanup for this test at completion
> - * 	       or premature exit.
> - */
> -void cleanup(void)
> +static void cleanup(void)
>  {
> -	int i;
> +	int num;
>  
> -	/* remove the shared memory resources that were created */
> -	for (i = 0; i < num_shms; i++) {
> -		rm_shm(shm_id_arr[i]);
> -	}
> +	if (!queues)
> +		return;
>  
> -	tst_rmdir();
> +	for (num = 0; num < maxshms; num++) {
> +		if (queues[num] != -1)
> +			SAFE_SHMCTL(queues[num], IPC_RMID, NULL);
> +	}

This is still not correct, we will pass random data to the SAFE_SHMCTL()
in a case shmget() had failed before the loop in setup reached maximal value.

We have to maintain a global variable with the number of the ids in the
queues[] array and only remove these that have been created.

	for (i = 0; i < maxshms; i++) {
		res = shmget(...);

		if (res == -1)
			tst_brk(TBROK...);

		queues[queue_cnt++] = res;
	}



	for (i = 0; i < queue_cnt; i++)
		SAFE_SHMCTL(queues[i], IPC_RMID);

> +	free(queues);
>  }
> +
> +static struct tst_test test = {
> +	.needs_tmpdir = 1,
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.test_all = verify_shmget,
> +};
> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget04.c b/testcases/kernel/syscalls/ipc/shmget/shmget04.c
> index 60a263c77..d92dfe635 100644
> --- a/testcases/kernel/syscalls/ipc/shmget/shmget04.c
> +++ b/testcases/kernel/syscalls/ipc/shmget/shmget04.c
> @@ -1,153 +1,71 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
>  /*
> - *
> - *   Copyright (c) International Business Machines  Corp., 2001
> - *
> - *   This program is free software;  you can redistribute it and/or modify
> - *   it under the terms of the GNU General Public License as published by
> - *   the Free Software Foundation; either version 2 of the License, or
> - *   (at your option) any later version.
> - *
> - *   This program is distributed in the hope that it will be useful,
> - *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
> - *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
> - *   the GNU General Public License for more details.
> - *
> - *   You should have received a copy of the GNU General Public License
> - *   along with this program;  if not, write to the Free Software
> - *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + * Copyright (c) International Business Machines  Corp., 2001
> + *  03/2001 - Written by Wayne Boyer
>   */
>  
> -/*
> - * NAME
> - *	shmget04.c
> - *
> - * DESCRIPTION
> - *	shmget04 - test for EACCES error
> - *
> - * ALGORITHM
> - *	create a shared memory segment without read or write permissions
> - *	loop if that option was specified
> - *	  call shmget() with SHM_RW flag using TEST() macro
> - *	  check the errno value
> - *	    issue a PASS message if we get EACCES
> - *	  otherwise, the tests fails
> - *	    issue a FAIL message
> - *	call cleanup
> - *
> - * USAGE:  <for command-line>
> - *  shmget04 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
> - *     where,  -c n : Run n copies concurrently.
> - *             -e   : Turn on errno logging.
> - *	       -i n : Execute test n times.
> - *	       -I x : Execute test for x seconds.
> - *	       -P x : Pause for x seconds between iterations.
> - *	       -t   : Turn on syscall timing.
> +/*\
> + * [Description]
>   *
> - * HISTORY
> - *	03/2001 - Written by Wayne Boyer
> + * Test for EACCES error.
>   *
> - * RESTRICTIONS
> - *	none
> + * Create a shared memory segment without read or write permissions under
> + * unpriviledged user and call shmget() with SHM_RD/SHM_WR/SHM_RW flag to
> + * trigger EACCES error.
>   */
> +#include <errno.h>
> +#include <sys/types.h>
> +#include <sys/ipc.h>
> +#include <stdlib.h>
>  #include <pwd.h>
> -#include "ipcshm.h"
> -
> -char *TCID = "shmget04";
> -int TST_TOTAL = 1;
> -
> -char nobody_uid[] = "nobody";
> -struct passwd *ltpuser;
> -
> -int shm_id_1 = -1;
> -
> -int main(int ac, char **av)
> +#include <sys/shm.h>
> +#include "tst_safe_sysv_ipc.h"
> +#include "tst_test.h"
> +#include "libnewipc.h"
> +#include "lapi/shm.h"
> +
> +static int shm_id = -1;
> +static key_t shmkey;
> +static struct tcase {
> +	char *message;
> +	int flag;
> +} tcases[] = {
> +	{"Testing SHM_RD flag", SHM_RD},
> +	{"Testing SHM_WR flag", SHM_WR},
> +	{"Testing SHM_RW flag", SHM_RW},
> +};
> +
> +static void verify_shmget(unsigned int n)
>  {
> -	int lc;
> -
> -	tst_parse_opts(ac, av, NULL, NULL);
> -
> -	setup();		/* global setup */
> -
> -	/* The following loop checks looping state if -i option given */
> -
> -	for (lc = 0; TEST_LOOPING(lc); lc++) {
> -		/* reset tst_count in case we are looping */
> -		tst_count = 0;
> +	struct tcase *tc = &tcases[n];
>  
> -		/*
> -		 * use the TEST() macro to make the call
> -		 */
> -
> -		TEST(shmget(shmkey, SHM_SIZE, SHM_RW));
> -
> -		if (TEST_RETURN != -1) {
> -			tst_resm(TFAIL, "call succeeded when error expected");
> -			continue;
> -		}
> -
> -		switch (TEST_ERRNO) {
> -		case EACCES:
> -			tst_resm(TPASS, "expected failure - errno = "
> -				 "%d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
> -			break;
> -		default:
> -			tst_resm(TFAIL, "call failed with an "
> -				 "unexpected error - %d : %s",
> -				 TEST_ERRNO, strerror(TEST_ERRNO));
> -			break;
> -		}
> -	}
> -
> -	cleanup();
> -
> -	tst_exit();
> +	tst_res(TINFO, "%s", tc->message);
> +	TST_EXP_FAIL(shmget(shmkey, SHM_SIZE, tc->flag), EACCES, "shmget(%i, %i, %i)",
> +		shmkey, SHM_SIZE, tc->flag);
>  }
>  
> -/*
> - * setup() - performs all the ONE TIME setup for this test.
> - */
> -void setup(void)
> +static void setup(void)
>  {
> -	tst_require_root();
> -
> -	tst_sig(NOFORK, DEF_HANDLER, cleanup);
> +	struct passwd *pw;
>  
> -	TEST_PAUSE;
> +	pw = SAFE_GETPWNAM("nobody");
> +	SAFE_SETUID(pw->pw_uid);
> +	shmkey = GETIPCKEY();
>  
> -	/* Switch to nobody user for correct error code collection */
> -	ltpuser = getpwnam(nobody_uid);
> -	if (setuid(ltpuser->pw_uid) == -1) {
> -		tst_resm(TINFO, "setuid failed to "
> -			 "to set the effective uid to %d", ltpuser->pw_uid);
> -		perror("setuid");
> -	}
> -
> -	/*
> -	 * Create a temporary directory and cd into it.
> -	 * This helps to ensure that a unique msgkey is created.
> -	 * See libs/libltpipc/libipc.c for more information.
> -	 */
> -	tst_tmpdir();
> -
> -	/* get an IPC resource key */
> -	shmkey = getipckey();
> -
> -	/* create a shared memory segment without read or access permissions */
> -	if ((shm_id_1 = shmget(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL)) == -1) {
> -		tst_brkm(TBROK, cleanup, "Failed to create shared memory "
> -			 "segment in setup");
> -	}
> +	shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL);
>  }
>  
> -/*
> - * cleanup() - performs all the ONE TIME cleanup for this test at completion
> - * 	       or premature exit.
> - */
> -void cleanup(void)
> +static void cleanup(void)
>  {
> -	/* if it exists, remove the shared memory resource */
> -	rm_shm(shm_id_1);
> -
> -	tst_rmdir();
> -
> +	if (shm_id >= 0)
> +		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
>  }
> +
> +static struct tst_test test = {
> +	.needs_tmpdir = 1,
> +	.needs_root = 1,
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.test = verify_shmget,
> +	.tcnt = ARRAY_SIZE(tcases),
> +};

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v2] syscalls/shmget*: Convert into new api
  2021-06-23 13:35       ` Cyril Hrubis
@ 2021-06-24  3:46         ` xuyang2018.jy
  0 siblings, 0 replies; 21+ messages in thread
From: xuyang2018.jy @ 2021-06-24  3:46 UTC (permalink / raw)
  To: ltp

Hi Cyril
> Hi!
>> +
>> +static struct tcase {
>> +	int *shmkey;
>> +	size_t size;
>>   	int flags;
>> -	int error;
>> -} TC[] = {
>> -	/* EINVAL - size is 0 */
>> -	{
>> -	&shmkey2, 0, IPC_CREAT | IPC_EXCL | SHM_RW, EINVAL},
>> -	    /* EINVAL - size is negative */
>> -//      {&shmkey2, -1, IPC_CREAT | IPC_EXCL | SHM_RW, EINVAL},
>> -	    /* EINVAL - size is larger than created segment */
>> -	{
>> -	&shmkey, SHM_SIZE * 2, SHM_RW, EINVAL},
>> -	    /* EEXIST - the segment exists and IPC_CREAT | IPC_EXCL is given */
>> -	{
>> -	&shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW, EEXIST},
>> -	    /* ENOENT - no segment exists for the key and IPC_CREAT is not given */
>> -	    /* use shm_id_2 (-1) as the key */
>> -	{
>> -	&shm_nonexisting_key, SHM_SIZE, SHM_RW, ENOENT}
>> +	/*1: nobody expected  0: root expected */
>> +	int exp_user;
>> +	int exp_err;
>> +} tcases[] = {
>> +	{&shmkey1, SHM_SIZE, IPC_EXCL, 0, ENOENT},
>> +	{&shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL, 0, EEXIST},
>> +	{&shmkey1, SHMMIN - 1, IPC_CREAT | IPC_EXCL, 0, EINVAL},
>> +	{&shmkey1, SHMMAX + 1, IPC_CREAT | IPC_EXCL, 0, EINVAL},
>> +	{&shmkey, SHM_SIZE * 2, IPC_EXCL, 0, EINVAL},
>> +	{&shmkey, SHM_SIZE, SHM_RD, 1, EACCES},
>> +	{&shmkey1, SHM_SIZE, IPC_CREAT | SHM_HUGETLB, 1, EPERM}
>
> This case is a bit more complicated, on my test machine with
> nr_hugepages == 0 I get ENOMEM, since there are no hugepages allocated
> in the pool.
>
> When I add .request_hugepages = 1, the the tst_test structure, the
> hugepage pool size is increased by the test library and this request
> succeds and creates a SHM segment. See description below on how this has
> to be fixed.
>
>>   };
>>
>> -int main(int ac, char **av)
>> +static void do_test(unsigned int n)
>>   {
>> -	int lc;
>> -	int i;
>> -
>> -	tst_parse_opts(ac, av, NULL, NULL);
>> -
>> -	setup();		/* global setup */
>> -
>> -	/* The following loop checks looping state if -i option given */
>> -
>> -	for (lc = 0; TEST_LOOPING(lc); lc++) {
>> -		/* reset tst_count in case we are looping */
>> -		tst_count = 0;
>> +	struct tcase *tc =&tcases[n];
>> +	pid_t pid;
>>
>> -		/* loop through the test cases */
>> -		for (i = 0; i<  TST_TOTAL; i++) {
>> -			/*
>> -			 * Look for a failure ...
>> -			 */
>> -
>> -			TEST(shmget(*(TC[i].skey), TC[i].size, TC[i].flags));
>> -
>> -			if (TEST_RETURN != -1) {
>> -				tst_resm(TFAIL, "call succeeded unexpectedly");
>> -				continue;
>> -			}
>> -
>> -			if (TEST_ERRNO == TC[i].error) {
>> -				tst_resm(TPASS, "expected failure - errno = "
>> -					 "%d : %s", TEST_ERRNO,
>> -					 strerror(TEST_ERRNO));
>> -			} else {
>> -				tst_resm(TFAIL, "call failed with an "
>> -					 "unexpected error - %d : %s",
>> -					 TEST_ERRNO, strerror(TEST_ERRNO));
>> -			}
>> -		}
>> +	if (tc->exp_user == 0) {
>> +		TST_EXP_FAIL(shmget(*tc->shmkey, tc->size, tc->flags), tc->exp_err,
>> +			"shmget(%i, %lu, %i)", *tc->shmkey, tc->size, tc->flags);
>> +		return;
>>   	}
>>
>> -	cleanup();
>> -
>> -	tst_exit();
>> +	pid = SAFE_FORK();
>> +	if (pid == 0) {
>> +		SAFE_SETUID(pw->pw_uid);
>> +		TST_EXP_FAIL(shmget(*tc->shmkey, tc->size, tc->flags), tc->exp_err,
>> +			"shmget(%i, %lu, %i)", *tc->shmkey, tc->size, tc->flags);
>> +		exit(0);
>> +	}
>> +	tst_reap_children();
>>   }
>>
>> -/*
>> - * setup() - performs all the ONE TIME setup for this test.
>> - */
>> -void setup(void)
>> +static void setup(void)
>>   {
>> +	shmkey = GETIPCKEY();
>> +	shmkey1 = GETIPCKEY();
>>
>> -	tst_sig(NOFORK, DEF_HANDLER, cleanup);
>> -
>> -	TEST_PAUSE;
>> -
>> -	/*
>> -	 * Create a temporary directory and cd into it.
>> -	 * This helps to ensure that a unique msgkey is created.
>> -	 * See libs/libltpipc/libipc.c for more information.
>> -	 */
>> -	tst_tmpdir();
>> -
>> -	/* get an IPC resource key */
>> -	shmkey = getipckey();
>> -
>> -	/* Get an new IPC resource key. */
>> -	shmkey2 = getipckey();
>> -
>> -	if ((shm_id_1 = shmget(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL |
>> -			       SHM_RW)) == -1) {
>> -		tst_brkm(TBROK, cleanup, "couldn't create shared memory "
>> -			 "segment in setup()");
>> -	}
>> -
>> -	/* Make sure shm_nonexisting_key is a nonexisting key */
>> -	while (1) {
>> -		while (-1 != shmget(shm_nonexisting_key, 1, SHM_RD)) {
>> -			shm_nonexisting_key--;
>> -		}
>> -		if (errno == ENOENT)
>> -			break;
>> -	}
>> +	SAFE_FILE_PRINTF("/proc/sys/vm/hugetlb_shm_group", "1");
>
> There is no need to change the default hugetlb group, all that has to be
> done is to strip the user of all groups as well as there is absolutely
> no guarantee that group 1 will not be in the list of supplementary
> groups for a root users.
>
> So when we change uid we as well have to do:
>
> 	setgroups(0, NULL);
> 	SAFE_SETGID(pw->pw_gid);
> 	SAFE_SETUID(pw->pw_uid);
>
> This will strip the process of all additional permissions that may have
> been passed down by the process running under root.
>
> Also ideally we should add SAFE_SETGROUPS() to the test library in a
> separate patch so that we can make use of it here.
>
Yes, your are right. my origial way is to set 1 and it doesn't work on 
your envrionment, so it doesn't meet EPERM error and meet the ENOMEM 
error in kernel hugetlb_file_setup function.

I have check the kernel code, it used  in_group_p function to check 
whether have read access. So using setgroups(0, NULL) is right. Thanks.

Also, I add a ENOMEM test error test.
>> +	shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL);
>> +	pw = SAFE_GETPWNAM("nobody");
>>   }
>>
>> -/*
>> - * cleanup() - performs all the ONE TIME cleanup for this test at completion
>> - * 	       or premature exit.
>> - */
>> -void cleanup(void)
>> +static void cleanup(void)
>>   {
>> -	/* if it exists, remove the shared memory resource */
>> -	rm_shm(shm_id_1);
>> -
>> -	tst_rmdir();
>> -
>> +	if (shm_id>= 0)
>> +		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
>>   }
>> +
>> +static struct tst_test test = {
>> +	.needs_tmpdir = 1,
>> +	.needs_root = 1,
>> +	.forks_child = 1,
>> +	.setup = setup,
>> +	.cleanup = cleanup,
>> +	.test = do_test,
>> +	.tcnt = ARRAY_SIZE(tcases),
>> +	.save_restore = (const char * const[]) {
>> +		"?/proc/sys/vm/hugetlb_shm_group",
>> +		NULL,
>> +	}
>> +};
>> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget03.c b/testcases/kernel/syscalls/ipc/shmget/shmget03.c
>> index 96ebf3608..d2e850b2a 100644
>> --- a/testcases/kernel/syscalls/ipc/shmget/shmget03.c
>> +++ b/testcases/kernel/syscalls/ipc/shmget/shmget03.c
>> @@ -1,171 +1,75 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>>   /*
>> - *
>> - *   Copyright (c) International Business Machines  Corp., 2001
>> - *
>> - *   This program is free software;  you can redistribute it and/or modify
>> - *   it under the terms of the GNU General Public License as published by
>> - *   the Free Software Foundation; either version 2 of the License, or
>> - *   (at your option) any later version.
>> - *
>> - *   This program is distributed in the hope that it will be useful,
>> - *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
>> - *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
>> - *   the GNU General Public License for more details.
>> - *
>> - *   You should have received a copy of the GNU General Public License
>> - *   along with this program;  if not, write to the Free Software
>> - *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>> + * Copyright (c) International Business Machines  Corp., 2001
>> + *  03/2001 - Written by Wayne Boyer
>>    */
>>
>> -/*
>> - * NAME
>> - *	shmget03.c
>> +/*\
>> + * [Description]
>>    *
>> - * DESCRIPTION
>> - *	shmget03 - test for ENOSPC error
>> + * Test for ENOSPC error.
>>    *
>> - * ALGORITHM
>> - *	create shared memory segments in a loop until reaching the system limit
>> - *	loop if that option was specified
>> - *	  attempt to create yet another shared memory segment
>> - *	  check the errno value
>> - *	    issue a PASS message if we get ENOSPC
>> - *	  otherwise, the tests fails
>> - *	    issue a FAIL message
>> - *	call cleanup
>> - *
>> - * USAGE:<for command-line>
>> - *  shmget03 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
>> - *     where,  -c n : Run n copies concurrently.
>> - *             -e   : Turn on errno logging.
>> - *	       -i n : Execute test n times.
>> - *	       -I x : Execute test for x seconds.
>> - *	       -P x : Pause for x seconds between iterations.
>> - *	       -t   : Turn on syscall timing.
>> - *
>> - * HISTORY
>> - *	03/2001 - Written by Wayne Boyer
>> - *
>> - * RESTRICTIONS
>> - *	none
>> + * ENOSPC -  All possible shared memory segments have been taken (SHMMNI).
>>    */
>> -
>> -#include "ipcshm.h"
>> -
>> -char *TCID = "shmget03";
>> -int TST_TOTAL = 1;
>> -
>> -/*
>> - * The MAXIDS value is somewhat arbitrary and may need to be increased
>> - * depending on the system being tested.
>> - */
>> -#define MAXIDS	8192
>> -
>> -int shm_id_1 = -1;
>> -int num_shms = 0;
>> -
>> -int shm_id_arr[MAXIDS];
>> -
>> -int main(int ac, char **av)
>> +#include<errno.h>
>> +#include<sys/types.h>
>> +#include<sys/ipc.h>
>> +#include<stdlib.h>
>> +#include<pwd.h>
>> +#include<sys/shm.h>
>> +#include "tst_test.h"
>> +#include "tst_safe_sysv_ipc.h"
>> +#include "libnewipc.h"
>> +
>> +static int *queues;
>> +static int maxshms;
>> +static key_t shmkey;
>> +
>> +static void verify_shmget(void)
>>   {
>> -	int lc;
>> -
>> -	tst_parse_opts(ac, av, NULL, NULL);
>> -
>> -	setup();		/* global setup */
>> -
>> -	/* The following loop checks looping state if -i option given */
>> -
>> -	for (lc = 0; TEST_LOOPING(lc); lc++) {
>> -		/* reset tst_count in case we are looping */
>> -		tst_count = 0;
>> -
>> -		/*
>> -		 * use the TEST() macro to make the call
>> -		 */
>> -
>> -		TEST(shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | IPC_EXCL
>> -			    | SHM_RW));
>> -
>> -		if (TEST_RETURN != -1) {
>> -			tst_resm(TFAIL, "call succeeded when error expected");
>> -			continue;
>> -		}
>> -
>> -		switch (TEST_ERRNO) {
>> -		case ENOSPC:
>> -			tst_resm(TPASS, "expected failure - errno = "
>> -				 "%d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
>> -			break;
>> -		default:
>> -			tst_resm(TFAIL, "call failed with an "
>> -				 "unexpected error - %d : %s",
>> -				 TEST_ERRNO, strerror(TEST_ERRNO));
>> -			break;
>> -		}
>> -	}
>> -
>> -	cleanup();
>> -
>> -	tst_exit();
>> +	TST_EXP_FAIL(shmget(shmkey + maxshms, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW), ENOSPC,
>> +		"shmget(%i, %i, %i)", shmkey + maxshms, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW);
>>   }
>>
>> -/*
>> - * setup() - performs all the ONE TIME setup for this test.
>> - */
>> -void setup(void)
>> +static void setup(void)
>>   {
>> +	int res, num;
>>
>> -	tst_sig(NOFORK, DEF_HANDLER, cleanup);
>> +	shmkey = GETIPCKEY();
>>
>> -	TEST_PAUSE;
>> +	SAFE_FILE_SCANF("/proc/sys/kernel/shmmni", "%i",&maxshms);
>>
>> -	/*
>> -	 * Create a temporary directory and cd into it.
>> -	 * This helps to ensure that a unique msgkey is created.
>> -	 * See libs/libltpipc/libipc.c for more information.
>> -	 */
>> -	tst_tmpdir();
>> -
>> -	/* get an IPC resource key */
>> -	shmkey = getipckey();
>> -
>> -	/*
>> -	 * Use a while loop to create the maximum number of memory segments.
>> -	 * If the loop exceeds MAXIDS, then break the test and cleanup.
>> -	 */
>> -	while ((shm_id_1 = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT |
>> -				  IPC_EXCL | SHM_RW)) != -1) {
>> -		shm_id_arr[num_shms++] = shm_id_1;
>> -		if (num_shms == MAXIDS) {
>> -			tst_brkm(TBROK, cleanup, "The maximum number of shared "
>> -				 "memory ID's has been\n\t reached.  Please "
>> -				 "increase the MAXIDS value in the test.");
>> -		}
>> -	}
>> -
>> -	/*
>> -	 * If the errno is other than ENOSPC, then something else is wrong.
>> -	 */
>> -	if (errno != ENOSPC) {
>> -		tst_resm(TINFO, "errno = %d : %s", errno, strerror(errno));
>> -		tst_brkm(TBROK, cleanup, "Didn't get ENOSPC in test setup");
>> +	queues = SAFE_MALLOC(maxshms * sizeof(int));
>> +	for (num = 0; num<  maxshms; num++) {
>> +		queues[num] = -1;
>> +		res = shmget(shmkey + num, SHM_SIZE, IPC_CREAT | IPC_EXCL | SHM_RW);
>> +		if (res != -1)
>> +			queues[num] = res;
>> +		else
>> +			tst_brk(TBROK | TERRNO, "shmget failed unexpectedly");
>>   	}
>> +	tst_res(TINFO, "The maximum number of memory segments (%d) has been reached",
>> +		maxshms);
>>   }
>>
>> -/*
>> - * cleanup() - performs all the ONE TIME cleanup for this test at completion
>> - * 	       or premature exit.
>> - */
>> -void cleanup(void)
>> +static void cleanup(void)
>>   {
>> -	int i;
>> +	int num;
>>
>> -	/* remove the shared memory resources that were created */
>> -	for (i = 0; i<  num_shms; i++) {
>> -		rm_shm(shm_id_arr[i]);
>> -	}
>> +	if (!queues)
>> +		return;
>>
>> -	tst_rmdir();
>> +	for (num = 0; num<  maxshms; num++) {
>> +		if (queues[num] != -1)
>> +			SAFE_SHMCTL(queues[num], IPC_RMID, NULL);
>> +	}
>
> This is still not correct, we will pass random data to the SAFE_SHMCTL()
> in a case shmget() had failed before the loop in setup reached maximal value.
>
> We have to maintain a global variable with the number of the ids in the
> queues[] array and only remove these that have been created.
Yes, I have added a global count.

Best Regards
Yang Xu
>
> 	for (i = 0; i<  maxshms; i++) {
> 		res = shmget(...);
>
> 		if (res == -1)
> 			tst_brk(TBROK...);
>
> 		queues[queue_cnt++] = res;
> 	}
>
>
>
> 	for (i = 0; i<  queue_cnt; i++)
> 		SAFE_SHMCTL(queues[i], IPC_RMID);
>
>> +	free(queues);
>>   }

>> +
>> +static struct tst_test test = {
>> +	.needs_tmpdir = 1,
>> +	.setup = setup,
>> +	.cleanup = cleanup,
>> +	.test_all = verify_shmget,
>> +};
>> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget04.c b/testcases/kernel/syscalls/ipc/shmget/shmget04.c
>> index 60a263c77..d92dfe635 100644
>> --- a/testcases/kernel/syscalls/ipc/shmget/shmget04.c
>> +++ b/testcases/kernel/syscalls/ipc/shmget/shmget04.c
>> @@ -1,153 +1,71 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>>   /*
>> - *
>> - *   Copyright (c) International Business Machines  Corp., 2001
>> - *
>> - *   This program is free software;  you can redistribute it and/or modify
>> - *   it under the terms of the GNU General Public License as published by
>> - *   the Free Software Foundation; either version 2 of the License, or
>> - *   (at your option) any later version.
>> - *
>> - *   This program is distributed in the hope that it will be useful,
>> - *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
>> - *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
>> - *   the GNU General Public License for more details.
>> - *
>> - *   You should have received a copy of the GNU General Public License
>> - *   along with this program;  if not, write to the Free Software
>> - *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>> + * Copyright (c) International Business Machines  Corp., 2001
>> + *  03/2001 - Written by Wayne Boyer
>>    */
>>
>> -/*
>> - * NAME
>> - *	shmget04.c
>> - *
>> - * DESCRIPTION
>> - *	shmget04 - test for EACCES error
>> - *
>> - * ALGORITHM
>> - *	create a shared memory segment without read or write permissions
>> - *	loop if that option was specified
>> - *	  call shmget() with SHM_RW flag using TEST() macro
>> - *	  check the errno value
>> - *	    issue a PASS message if we get EACCES
>> - *	  otherwise, the tests fails
>> - *	    issue a FAIL message
>> - *	call cleanup
>> - *
>> - * USAGE:<for command-line>
>> - *  shmget04 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
>> - *     where,  -c n : Run n copies concurrently.
>> - *             -e   : Turn on errno logging.
>> - *	       -i n : Execute test n times.
>> - *	       -I x : Execute test for x seconds.
>> - *	       -P x : Pause for x seconds between iterations.
>> - *	       -t   : Turn on syscall timing.
>> +/*\
>> + * [Description]
>>    *
>> - * HISTORY
>> - *	03/2001 - Written by Wayne Boyer
>> + * Test for EACCES error.
>>    *
>> - * RESTRICTIONS
>> - *	none
>> + * Create a shared memory segment without read or write permissions under
>> + * unpriviledged user and call shmget() with SHM_RD/SHM_WR/SHM_RW flag to
>> + * trigger EACCES error.
>>    */
>> +#include<errno.h>
>> +#include<sys/types.h>
>> +#include<sys/ipc.h>
>> +#include<stdlib.h>
>>   #include<pwd.h>
>> -#include "ipcshm.h"
>> -
>> -char *TCID = "shmget04";
>> -int TST_TOTAL = 1;
>> -
>> -char nobody_uid[] = "nobody";
>> -struct passwd *ltpuser;
>> -
>> -int shm_id_1 = -1;
>> -
>> -int main(int ac, char **av)
>> +#include<sys/shm.h>
>> +#include "tst_safe_sysv_ipc.h"
>> +#include "tst_test.h"
>> +#include "libnewipc.h"
>> +#include "lapi/shm.h"
>> +
>> +static int shm_id = -1;
>> +static key_t shmkey;
>> +static struct tcase {
>> +	char *message;
>> +	int flag;
>> +} tcases[] = {
>> +	{"Testing SHM_RD flag", SHM_RD},
>> +	{"Testing SHM_WR flag", SHM_WR},
>> +	{"Testing SHM_RW flag", SHM_RW},
>> +};
>> +
>> +static void verify_shmget(unsigned int n)
>>   {
>> -	int lc;
>> -
>> -	tst_parse_opts(ac, av, NULL, NULL);
>> -
>> -	setup();		/* global setup */
>> -
>> -	/* The following loop checks looping state if -i option given */
>> -
>> -	for (lc = 0; TEST_LOOPING(lc); lc++) {
>> -		/* reset tst_count in case we are looping */
>> -		tst_count = 0;
>> +	struct tcase *tc =&tcases[n];
>>
>> -		/*
>> -		 * use the TEST() macro to make the call
>> -		 */
>> -
>> -		TEST(shmget(shmkey, SHM_SIZE, SHM_RW));
>> -
>> -		if (TEST_RETURN != -1) {
>> -			tst_resm(TFAIL, "call succeeded when error expected");
>> -			continue;
>> -		}
>> -
>> -		switch (TEST_ERRNO) {
>> -		case EACCES:
>> -			tst_resm(TPASS, "expected failure - errno = "
>> -				 "%d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
>> -			break;
>> -		default:
>> -			tst_resm(TFAIL, "call failed with an "
>> -				 "unexpected error - %d : %s",
>> -				 TEST_ERRNO, strerror(TEST_ERRNO));
>> -			break;
>> -		}
>> -	}
>> -
>> -	cleanup();
>> -
>> -	tst_exit();
>> +	tst_res(TINFO, "%s", tc->message);
>> +	TST_EXP_FAIL(shmget(shmkey, SHM_SIZE, tc->flag), EACCES, "shmget(%i, %i, %i)",
>> +		shmkey, SHM_SIZE, tc->flag);
>>   }
>>
>> -/*
>> - * setup() - performs all the ONE TIME setup for this test.
>> - */
>> -void setup(void)
>> +static void setup(void)
>>   {
>> -	tst_require_root();
>> -
>> -	tst_sig(NOFORK, DEF_HANDLER, cleanup);
>> +	struct passwd *pw;
>>
>> -	TEST_PAUSE;
>> +	pw = SAFE_GETPWNAM("nobody");
>> +	SAFE_SETUID(pw->pw_uid);
>> +	shmkey = GETIPCKEY();
>>
>> -	/* Switch to nobody user for correct error code collection */
>> -	ltpuser = getpwnam(nobody_uid);
>> -	if (setuid(ltpuser->pw_uid) == -1) {
>> -		tst_resm(TINFO, "setuid failed to "
>> -			 "to set the effective uid to %d", ltpuser->pw_uid);
>> -		perror("setuid");
>> -	}
>> -
>> -	/*
>> -	 * Create a temporary directory and cd into it.
>> -	 * This helps to ensure that a unique msgkey is created.
>> -	 * See libs/libltpipc/libipc.c for more information.
>> -	 */
>> -	tst_tmpdir();
>> -
>> -	/* get an IPC resource key */
>> -	shmkey = getipckey();
>> -
>> -	/* create a shared memory segment without read or access permissions */
>> -	if ((shm_id_1 = shmget(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL)) == -1) {
>> -		tst_brkm(TBROK, cleanup, "Failed to create shared memory "
>> -			 "segment in setup");
>> -	}
>> +	shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL);
>>   }
>>
>> -/*
>> - * cleanup() - performs all the ONE TIME cleanup for this test at completion
>> - * 	       or premature exit.
>> - */
>> -void cleanup(void)
>> +static void cleanup(void)
>>   {
>> -	/* if it exists, remove the shared memory resource */
>> -	rm_shm(shm_id_1);
>> -
>> -	tst_rmdir();
>> -
>> +	if (shm_id>= 0)
>> +		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
>>   }
>> +
>> +static struct tst_test test = {
>> +	.needs_tmpdir = 1,
>> +	.needs_root = 1,
>> +	.setup = setup,
>> +	.cleanup = cleanup,
>> +	.test = verify_shmget,
>> +	.tcnt = ARRAY_SIZE(tcases),
>> +};
>

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

* [LTP] [PATCH v1 3/4] syscalls/shmget05: Add test for /proc/sys/kernel/shm_next_id
  2021-05-12  8:52 ` [LTP] [PATCH v1 3/4] syscalls/shmget05: Add test for /proc/sys/kernel/shm_next_id Yang Xu
@ 2021-06-29  3:25   ` xuyang2018.jy
  2021-07-12  2:37     ` xuyang2018.jy
  2021-07-22 11:52   ` Cyril Hrubis
  1 sibling, 1 reply; 21+ messages in thread
From: xuyang2018.jy @ 2021-06-29  3:25 UTC (permalink / raw)
  To: ltp

Hi Cyril

Since the previous patches have been merged, this patch can be continued.

Best Regards
Yang Xu
> This case is similar to msgget04.c.
> 
> Signed-off-by: Yang Xu<xuyang2018.jy@fujitsu.com>
> ---
>   runtest/syscalls                              |  1 +
>   runtest/syscalls-ipc                          |  1 +
>   .../kernel/syscalls/ipc/shmget/.gitignore     |  1 +
>   .../kernel/syscalls/ipc/shmget/shmget05.c     | 69 +++++++++++++++++++
>   4 files changed, 72 insertions(+)
>   create mode 100644 testcases/kernel/syscalls/ipc/shmget/shmget05.c
> 
> diff --git a/runtest/syscalls b/runtest/syscalls
> index 2dff25984..63d821e53 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -1402,6 +1402,7 @@ shmdt02 shmdt02
>   shmget02 shmget02
>   shmget03 shmget03
>   shmget04 shmget04
> +shmget05 shmget05
> 
>   sigaction01 sigaction01
>   sigaction02 sigaction02
> diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
> index b3bd37923..ff0364704 100644
> --- a/runtest/syscalls-ipc
> +++ b/runtest/syscalls-ipc
> @@ -67,3 +67,4 @@ shmdt02 shmdt02
>   shmget02 shmget02
>   shmget03 shmget03
>   shmget04 shmget04
> +shmget05 shmget05
> diff --git a/testcases/kernel/syscalls/ipc/shmget/.gitignore b/testcases/kernel/syscalls/ipc/shmget/.gitignore
> index c57df68f5..6f08529f8 100644
> --- a/testcases/kernel/syscalls/ipc/shmget/.gitignore
> +++ b/testcases/kernel/syscalls/ipc/shmget/.gitignore
> @@ -1,3 +1,4 @@
>   /shmget02
>   /shmget03
>   /shmget04
> +/shmget05
> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget05.c b/testcases/kernel/syscalls/ipc/shmget/shmget05.c
> new file mode 100644
> index 000000000..601609648
> --- /dev/null
> +++ b/testcases/kernel/syscalls/ipc/shmget/shmget05.c
> @@ -0,0 +1,69 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2021 FUJITSU LIMITED. All rights reserved.
> + * Author: Yang Xu<xuyang2018.jy@fujitsu.com>
> + */
> +
> +/*\
> + * [Description]
> + *
> + * It is a basic test about shm_next_id.
> + *
> + * shm_next_id specifies desired id for next allocated IPC shared memory. By
> + * default they are equal to -1, which means generic allocation logic.
> + * Possible values to set are in range {0..INT_MAX}.
> + * Toggle with non-default value will be set back to -1 by kernel after
> + * successful IPC object allocation.
> + */
> +
> +#include<errno.h>
> +#include<string.h>
> +#include<sys/types.h>
> +#include<sys/ipc.h>
> +#include<sys/shm.h>
> +#include "tst_test.h"
> +#include "tst_safe_sysv_ipc.h"
> +#include "libnewipc.h"
> +
> +#define NEXT_ID_PATH "/proc/sys/kernel/shm_next_id"
> +static int shm_id, pid;
> +static key_t shmkey;
> +
> +static void verify_shmget(void)
> +{
> +	SAFE_FILE_PRINTF(NEXT_ID_PATH, "%d", pid);
> +
> +	shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, SHM_RW | IPC_CREAT);
> +	if (shm_id == pid)
> +		tst_res(TPASS, "shm_next_id succeeded, shm id %d", pid);
> +	else
> +		tst_res(TFAIL, "shm_next_id failed, expected id %d, but got %d", pid, shm_id);
> +
> +	TST_ASSERT_INT(NEXT_ID_PATH, -1);
> +	SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
> +	pid++;
> +}
> +
> +static void setup(void)
> +{
> +	shmkey = GETIPCKEY();
> +	pid = getpid();
> +}
> +
> +static void cleanup(void)
> +{
> +	if (shm_id != -1)
> +		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
> +}
> +
> +static struct tst_test test = {
> +	.needs_tmpdir = 1,
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.test_all = verify_shmget,
> +	.needs_kconfigs = (const char *[]) {
> +		"CONFIG_CHECKPOINT_RESTORE=y",
> +		NULL
> +	},
> +	.needs_root = 1,
> +};

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

* [LTP] [PATCH v1 3/4] syscalls/shmget05: Add test for /proc/sys/kernel/shm_next_id
  2021-06-29  3:25   ` xuyang2018.jy
@ 2021-07-12  2:37     ` xuyang2018.jy
  0 siblings, 0 replies; 21+ messages in thread
From: xuyang2018.jy @ 2021-07-12  2:37 UTC (permalink / raw)
  To: ltp

Hi
Ping.

ps:On lastest ltp, this patch still can be merged without rebase.

Best Regards
Yang Xu
> Hi Cyril
> 
> Since the previous patches have been merged, this patch can be continued.
> 
> Best Regards
> Yang Xu
>> This case is similar to msgget04.c.
>>
>> Signed-off-by: Yang Xu<xuyang2018.jy@fujitsu.com>
>> ---
>>    runtest/syscalls                              |  1 +
>>    runtest/syscalls-ipc                          |  1 +
>>    .../kernel/syscalls/ipc/shmget/.gitignore     |  1 +
>>    .../kernel/syscalls/ipc/shmget/shmget05.c     | 69 +++++++++++++++++++
>>    4 files changed, 72 insertions(+)
>>    create mode 100644 testcases/kernel/syscalls/ipc/shmget/shmget05.c
>>
>> diff --git a/runtest/syscalls b/runtest/syscalls
>> index 2dff25984..63d821e53 100644
>> --- a/runtest/syscalls
>> +++ b/runtest/syscalls
>> @@ -1402,6 +1402,7 @@ shmdt02 shmdt02
>>    shmget02 shmget02
>>    shmget03 shmget03
>>    shmget04 shmget04
>> +shmget05 shmget05
>>
>>    sigaction01 sigaction01
>>    sigaction02 sigaction02
>> diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
>> index b3bd37923..ff0364704 100644
>> --- a/runtest/syscalls-ipc
>> +++ b/runtest/syscalls-ipc
>> @@ -67,3 +67,4 @@ shmdt02 shmdt02
>>    shmget02 shmget02
>>    shmget03 shmget03
>>    shmget04 shmget04
>> +shmget05 shmget05
>> diff --git a/testcases/kernel/syscalls/ipc/shmget/.gitignore b/testcases/kernel/syscalls/ipc/shmget/.gitignore
>> index c57df68f5..6f08529f8 100644
>> --- a/testcases/kernel/syscalls/ipc/shmget/.gitignore
>> +++ b/testcases/kernel/syscalls/ipc/shmget/.gitignore
>> @@ -1,3 +1,4 @@
>>    /shmget02
>>    /shmget03
>>    /shmget04
>> +/shmget05
>> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget05.c b/testcases/kernel/syscalls/ipc/shmget/shmget05.c
>> new file mode 100644
>> index 000000000..601609648
>> --- /dev/null
>> +++ b/testcases/kernel/syscalls/ipc/shmget/shmget05.c
>> @@ -0,0 +1,69 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Copyright (c) 2021 FUJITSU LIMITED. All rights reserved.
>> + * Author: Yang Xu<xuyang2018.jy@fujitsu.com>
>> + */
>> +
>> +/*\
>> + * [Description]
>> + *
>> + * It is a basic test about shm_next_id.
>> + *
>> + * shm_next_id specifies desired id for next allocated IPC shared memory. By
>> + * default they are equal to -1, which means generic allocation logic.
>> + * Possible values to set are in range {0..INT_MAX}.
>> + * Toggle with non-default value will be set back to -1 by kernel after
>> + * successful IPC object allocation.
>> + */
>> +
>> +#include<errno.h>
>> +#include<string.h>
>> +#include<sys/types.h>
>> +#include<sys/ipc.h>
>> +#include<sys/shm.h>
>> +#include "tst_test.h"
>> +#include "tst_safe_sysv_ipc.h"
>> +#include "libnewipc.h"
>> +
>> +#define NEXT_ID_PATH "/proc/sys/kernel/shm_next_id"
>> +static int shm_id, pid;
>> +static key_t shmkey;
>> +
>> +static void verify_shmget(void)
>> +{
>> +	SAFE_FILE_PRINTF(NEXT_ID_PATH, "%d", pid);
>> +
>> +	shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, SHM_RW | IPC_CREAT);
>> +	if (shm_id == pid)
>> +		tst_res(TPASS, "shm_next_id succeeded, shm id %d", pid);
>> +	else
>> +		tst_res(TFAIL, "shm_next_id failed, expected id %d, but got %d", pid, shm_id);
>> +
>> +	TST_ASSERT_INT(NEXT_ID_PATH, -1);
>> +	SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
>> +	pid++;
>> +}
>> +
>> +static void setup(void)
>> +{
>> +	shmkey = GETIPCKEY();
>> +	pid = getpid();
>> +}
>> +
>> +static void cleanup(void)
>> +{
>> +	if (shm_id != -1)
>> +		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
>> +}
>> +
>> +static struct tst_test test = {
>> +	.needs_tmpdir = 1,
>> +	.setup = setup,
>> +	.cleanup = cleanup,
>> +	.test_all = verify_shmget,
>> +	.needs_kconfigs = (const char *[]) {
>> +		"CONFIG_CHECKPOINT_RESTORE=y",
>> +		NULL
>> +	},
>> +	.needs_root = 1,
>> +};
> 

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

* [LTP] [PATCH v1 3/4] syscalls/shmget05: Add test for /proc/sys/kernel/shm_next_id
  2021-05-12  8:52 ` [LTP] [PATCH v1 3/4] syscalls/shmget05: Add test for /proc/sys/kernel/shm_next_id Yang Xu
  2021-06-29  3:25   ` xuyang2018.jy
@ 2021-07-22 11:52   ` Cyril Hrubis
  2021-07-23  9:10     ` xuyang2018.jy
  1 sibling, 1 reply; 21+ messages in thread
From: Cyril Hrubis @ 2021-07-22 11:52 UTC (permalink / raw)
  To: ltp

Hi!
First of all, sorry for the late response.

> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget05.c b/testcases/kernel/syscalls/ipc/shmget/shmget05.c
> new file mode 100644
> index 000000000..601609648
> --- /dev/null
> +++ b/testcases/kernel/syscalls/ipc/shmget/shmget05.c
> @@ -0,0 +1,69 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2021 FUJITSU LIMITED. All rights reserved.
> + * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
> + */
> +
> +/*\
> + * [Description]
> + *
> + * It is a basic test about shm_next_id.
                           ^
			   for
> + *
> + * shm_next_id specifies desired id for next allocated IPC shared memory. By
> + * default they are equal to -1, which means generic allocation logic.
              ^
	      it's instead of 'they are'
> + * Possible values to set are in range {0..INT_MAX}.
> + * Toggle with non-default value will be set back to -1 by kernel after

This would probably be better with just: "The value will be set back ..."

> + * successful IPC object allocation.
> + */
> +
> +#include <errno.h>
> +#include <string.h>
> +#include <sys/types.h>
> +#include <sys/ipc.h>
> +#include <sys/shm.h>
> +#include "tst_test.h"
> +#include "tst_safe_sysv_ipc.h"
> +#include "libnewipc.h"
> +
> +#define NEXT_ID_PATH "/proc/sys/kernel/shm_next_id"
> +static int shm_id, pid;
> +static key_t shmkey;
> +
> +static void verify_shmget(void)
> +{
> +	SAFE_FILE_PRINTF(NEXT_ID_PATH, "%d", pid);
> +
> +	shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, SHM_RW | IPC_CREAT);
> +	if (shm_id == pid)
> +		tst_res(TPASS, "shm_next_id succeeded, shm id %d", pid);
> +	else
> +		tst_res(TFAIL, "shm_next_id failed, expected id %d, but got %d", pid, shm_id);
> +
> +	TST_ASSERT_INT(NEXT_ID_PATH, -1);
> +	SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
> +	pid++;
> +}
> +
> +static void setup(void)
> +{
> +	shmkey = GETIPCKEY();
> +	pid = getpid();
> +}
> +
> +static void cleanup(void)
> +{
> +	if (shm_id != -1)
> +		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
> +}
> +
> +static struct tst_test test = {
> +	.needs_tmpdir = 1,

I guess that we want this for the GETIPCKEY() right?

> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.test_all = verify_shmget,
> +	.needs_kconfigs = (const char *[]) {
> +		"CONFIG_CHECKPOINT_RESTORE=y",
> +		NULL
> +	},
> +	.needs_root = 1,
> +};

Looks good.

With the minor adjustements in the test description:

Reviewed-by: Cyril Hrubis <chrubis@suse.cz>

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v1 4/4] syscalls/shmget06: Add test when the id of shm_next_id has existed
  2021-05-12  8:52 ` [LTP] [PATCH v1 4/4] syscalls/shmget06: Add test when the id of shm_next_id has existed Yang Xu
@ 2021-07-22 12:08   ` Cyril Hrubis
  2021-07-23  9:15     ` xuyang2018.jy
  2021-07-23  9:41     ` [LTP] [PATCH v2 1/2] syscalls/shmget05: Add test for /proc/sys/kernel/shm_next_id Yang Xu
  0 siblings, 2 replies; 21+ messages in thread
From: Cyril Hrubis @ 2021-07-22 12:08 UTC (permalink / raw)
  To: ltp

Hi!
> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget06.c b/testcases/kernel/syscalls/ipc/shmget/shmget06.c
> new file mode 100644
> index 000000000..3138d4482
> --- /dev/null
> +++ b/testcases/kernel/syscalls/ipc/shmget/shmget06.c
> @@ -0,0 +1,77 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2021 FUJITSU LIMITED. All rights reserved.
> + * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
> + */
> +
> +/*\
> + * [Description]
> + *
> + * It is a basic test about shm_next_id.
                          ^
			  for
> + *
> + * When the shared memory segment identifier that shm_next_id stored has
> + * existed, call shmget with different key just use another unused value in range
      ^                                      ^
      'does exist' instead of 'has existed'  |
      or even better 'is allready in use'    |
                                            will
> + * [0,INT_MAX]. kernel doesn't guarantee the desired id.
                   ^
		   Capital letter at the start of the sentence.
> + */
> +
> +#include <errno.h>
> +#include <string.h>
> +#include <sys/types.h>
> +#include <sys/ipc.h>
> +#include <sys/shm.h>
> +#include "tst_test.h"
> +#include "tst_safe_sysv_ipc.h"
> +#include "libnewipc.h"
> +
> +#define NEXT_ID_PATH "/proc/sys/kernel/shm_next_id"
> +
> +static int shm_id[2], pid;
> +static key_t shmkey[2];
> +
> +static void verify_shmget(void)
> +{
> +	SAFE_FILE_PRINTF(NEXT_ID_PATH, "%d", shm_id[0]);
> +
> +	shm_id[1] = SAFE_SHMGET(shmkey[1], SHM_SIZE, IPC_CREAT | SHM_RW);
> +	if (shm_id[1] == shm_id[0])
> +		tst_res(TFAIL, "shm id %d has existed, shmget() returns the"
> +			" same shm id unexpectedly", shm_id[0]);
> +	else
> +		tst_res(TPASS, "shm id %d has existed, shmget() returns the"
> +			" new shm id %d", shm_id[0], shm_id[1]);
> +
> +	SAFE_SHMCTL(shm_id[1], IPC_RMID, NULL);
> +}
> +
> +static void setup(void)
> +{
> +	shmkey[0] = GETIPCKEY();
> +	shmkey[1] = GETIPCKEY();
> +	pid = getpid();
> +	SAFE_FILE_PRINTF(NEXT_ID_PATH, "%d", pid);

So we are using this to "randomize" the id here right?

> +	shm_id[0] = SAFE_SHMGET(shmkey[0], SHM_SIZE, IPC_CREAT | SHM_RW);
> +	tst_res(TINFO, "Test shm_next_id effects on shmget(different key) "
> +		"when this identifier of shared memory segment has existed");

I do not think that printing test description is useful, especially
since we have nicely formatted test description in the test source which
gets exported into the metadata.

> +}
> +
> +static void cleanup(void)
> +{
> +	int i;
> +
> +	for (i = 0; i < 2; i++) {
> +		if (shm_id[i] != -1)
> +			SAFE_SHMCTL(shm_id[i], IPC_RMID, NULL);
> +	}
> +}
> +
> +static struct tst_test test = {
> +	.needs_tmpdir = 1,
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.test_all = verify_shmget,
> +	.needs_kconfigs = (const char *[]) {
> +		"CONFIG_CHECKPOINT_RESTORE=y",
> +		NULL
> +	},
> +	.needs_root = 1,
> +};

With the minor adjustements in description:

Reivewed-by: Cyril Hrubis <chrubis@suse.cz>

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v1 3/4] syscalls/shmget05: Add test for /proc/sys/kernel/shm_next_id
  2021-07-22 11:52   ` Cyril Hrubis
@ 2021-07-23  9:10     ` xuyang2018.jy
  0 siblings, 0 replies; 21+ messages in thread
From: xuyang2018.jy @ 2021-07-23  9:10 UTC (permalink / raw)
  To: ltp

Hi Cyril
> Hi!
> First of all, sorry for the late response.
>
>> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget05.c b/testcases/kernel/syscalls/ipc/shmget/shmget05.c
>> new file mode 100644
>> index 000000000..601609648
>> --- /dev/null
>> +++ b/testcases/kernel/syscalls/ipc/shmget/shmget05.c
>> @@ -0,0 +1,69 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Copyright (c) 2021 FUJITSU LIMITED. All rights reserved.
>> + * Author: Yang Xu<xuyang2018.jy@fujitsu.com>
>> + */
>> +
>> +/*\
>> + * [Description]
>> + *
>> + * It is a basic test about shm_next_id.
>                             ^
> 			   for
>> + *
>> + * shm_next_id specifies desired id for next allocated IPC shared memory. By
>> + * default they are equal to -1, which means generic allocation logic.
>                ^
> 	      it's instead of 'they are'
>> + * Possible values to set are in range {0..INT_MAX}.
>> + * Toggle with non-default value will be set back to -1 by kernel after
>
> This would probably be better with just: "The value will be set back ..."
>
>> + * successful IPC object allocation.
>> + */
>> +
>> +#include<errno.h>
>> +#include<string.h>
>> +#include<sys/types.h>
>> +#include<sys/ipc.h>
>> +#include<sys/shm.h>
>> +#include "tst_test.h"
>> +#include "tst_safe_sysv_ipc.h"
>> +#include "libnewipc.h"
>> +
>> +#define NEXT_ID_PATH "/proc/sys/kernel/shm_next_id"
>> +static int shm_id, pid;
>> +static key_t shmkey;
>> +
>> +static void verify_shmget(void)
>> +{
>> +	SAFE_FILE_PRINTF(NEXT_ID_PATH, "%d", pid);
>> +
>> +	shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, SHM_RW | IPC_CREAT);
>> +	if (shm_id == pid)
>> +		tst_res(TPASS, "shm_next_id succeeded, shm id %d", pid);
>> +	else
>> +		tst_res(TFAIL, "shm_next_id failed, expected id %d, but got %d", pid, shm_id);
>> +
>> +	TST_ASSERT_INT(NEXT_ID_PATH, -1);
>> +	SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
>> +	pid++;
>> +}
>> +
>> +static void setup(void)
>> +{
>> +	shmkey = GETIPCKEY();
>> +	pid = getpid();
>> +}
>> +
>> +static void cleanup(void)
>> +{
>> +	if (shm_id != -1)
>> +		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
>> +}
>> +
>> +static struct tst_test test = {
>> +	.needs_tmpdir = 1,
>
> I guess that we want this for the GETIPCKEY() right?
>
Yes.
>> +	.setup = setup,
>> +	.cleanup = cleanup,
>> +	.test_all = verify_shmget,
>> +	.needs_kconfigs = (const char *[]) {
>> +		"CONFIG_CHECKPOINT_RESTORE=y",
>> +		NULL
>> +	},
>> +	.needs_root = 1,
>> +};
>
> Looks good.
>
> With the minor adjustements in the test description:
>
> Reviewed-by: Cyril Hrubis<chrubis@suse.cz>
Thanks for your review. Will send v2.
>

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

* [LTP] [PATCH v1 4/4] syscalls/shmget06: Add test when the id of shm_next_id has existed
  2021-07-22 12:08   ` Cyril Hrubis
@ 2021-07-23  9:15     ` xuyang2018.jy
  2021-07-23  9:41     ` [LTP] [PATCH v2 1/2] syscalls/shmget05: Add test for /proc/sys/kernel/shm_next_id Yang Xu
  1 sibling, 0 replies; 21+ messages in thread
From: xuyang2018.jy @ 2021-07-23  9:15 UTC (permalink / raw)
  To: ltp

Hi Cyril
> Hi!
>> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget06.c b/testcases/kernel/syscalls/ipc/shmget/shmget06.c
>> new file mode 100644
>> index 000000000..3138d4482
>> --- /dev/null
>> +++ b/testcases/kernel/syscalls/ipc/shmget/shmget06.c
>> @@ -0,0 +1,77 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Copyright (c) 2021 FUJITSU LIMITED. All rights reserved.
>> + * Author: Yang Xu<xuyang2018.jy@fujitsu.com>
>> + */
>> +
>> +/*\
>> + * [Description]
>> + *
>> + * It is a basic test about shm_next_id.
>                            ^
> 			  for
>> + *
>> + * When the shared memory segment identifier that shm_next_id stored has
>> + * existed, call shmget with different key just use another unused value in range
>        ^                                      ^
>        'does exist' instead of 'has existed'  |
>        or even better 'is allready in use'    |
>                                              will
>> + * [0,INT_MAX]. kernel doesn't guarantee the desired id.
>                     ^
> 		   Capital letter at the start of the sentence.
>> + */\
Will do.
>> +
>> +#include<errno.h>
>> +#include<string.h>
>> +#include<sys/types.h>
>> +#include<sys/ipc.h>
>> +#include<sys/shm.h>
>> +#include "tst_test.h"
>> +#include "tst_safe_sysv_ipc.h"
>> +#include "libnewipc.h"
>> +
>> +#define NEXT_ID_PATH "/proc/sys/kernel/shm_next_id"
>> +
>> +static int shm_id[2], pid;
>> +static key_t shmkey[2];
>> +
>> +static void verify_shmget(void)
>> +{
>> +	SAFE_FILE_PRINTF(NEXT_ID_PATH, "%d", shm_id[0]);
>> +
>> +	shm_id[1] = SAFE_SHMGET(shmkey[1], SHM_SIZE, IPC_CREAT | SHM_RW);
>> +	if (shm_id[1] == shm_id[0])
>> +		tst_res(TFAIL, "shm id %d has existed, shmget() returns the"
>> +			" same shm id unexpectedly", shm_id[0]);
>> +	else
>> +		tst_res(TPASS, "shm id %d has existed, shmget() returns the"
>> +			" new shm id %d", shm_id[0], shm_id[1]);
>> +
>> +	SAFE_SHMCTL(shm_id[1], IPC_RMID, NULL);
>> +}
>> +
>> +static void setup(void)
>> +{
>> +	shmkey[0] = GETIPCKEY();
>> +	shmkey[1] = GETIPCKEY();
>> +	pid = getpid();
>> +	SAFE_FILE_PRINTF(NEXT_ID_PATH, "%d", pid);
>
> So we are using this to "randomize" the id here right?
Yes.
>
>> +	shm_id[0] = SAFE_SHMGET(shmkey[0], SHM_SIZE, IPC_CREAT | SHM_RW);
>> +	tst_res(TINFO, "Test shm_next_id effects on shmget(different key) "
>> +		"when this identifier of shared memory segment has existed");
>
> I do not think that printing test description is useful, especially
> since we have nicely formatted test description in the test source which
> gets exported into the metadata.
Will remove it on v2.
>
>> +}
>> +
>> +static void cleanup(void)
>> +{
>> +	int i;
>> +
>> +	for (i = 0; i<  2; i++) {
>> +		if (shm_id[i] != -1)
>> +			SAFE_SHMCTL(shm_id[i], IPC_RMID, NULL);
>> +	}
>> +}
>> +
>> +static struct tst_test test = {
>> +	.needs_tmpdir = 1,
>> +	.setup = setup,
>> +	.cleanup = cleanup,
>> +	.test_all = verify_shmget,
>> +	.needs_kconfigs = (const char *[]) {
>> +		"CONFIG_CHECKPOINT_RESTORE=y",
>> +		NULL
>> +	},
>> +	.needs_root = 1,
>> +};
>
> With the minor adjustements in description:
>
> Reivewed-by: Cyril Hrubis<chrubis@suse.cz>
>

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

* [LTP] [PATCH v2 1/2] syscalls/shmget05: Add test for /proc/sys/kernel/shm_next_id
  2021-07-22 12:08   ` Cyril Hrubis
  2021-07-23  9:15     ` xuyang2018.jy
@ 2021-07-23  9:41     ` Yang Xu
  2021-07-23  9:42       ` [LTP] [PATCH v2 2/2] syscalls/shmget06: Add test when shm_next_id is already in use Yang Xu
  1 sibling, 1 reply; 21+ messages in thread
From: Yang Xu @ 2021-07-23  9:41 UTC (permalink / raw)
  To: ltp

This case is similar to msgget04.c.

Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
---
 runtest/syscalls                              |  1 +
 runtest/syscalls-ipc                          |  1 +
 .../kernel/syscalls/ipc/shmget/.gitignore     |  1 +
 .../kernel/syscalls/ipc/shmget/shmget05.c     | 69 +++++++++++++++++++
 4 files changed, 72 insertions(+)
 create mode 100644 testcases/kernel/syscalls/ipc/shmget/shmget05.c

diff --git a/runtest/syscalls b/runtest/syscalls
index 1deb6118f..b65b18c32 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1412,6 +1412,7 @@ shmdt02 shmdt02
 shmget02 shmget02
 shmget03 shmget03
 shmget04 shmget04
+shmget05 shmget05
 
 sigaction01 sigaction01
 sigaction02 sigaction02
diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
index b3bd37923..ff0364704 100644
--- a/runtest/syscalls-ipc
+++ b/runtest/syscalls-ipc
@@ -67,3 +67,4 @@ shmdt02 shmdt02
 shmget02 shmget02
 shmget03 shmget03
 shmget04 shmget04
+shmget05 shmget05
diff --git a/testcases/kernel/syscalls/ipc/shmget/.gitignore b/testcases/kernel/syscalls/ipc/shmget/.gitignore
index c57df68f5..6f08529f8 100644
--- a/testcases/kernel/syscalls/ipc/shmget/.gitignore
+++ b/testcases/kernel/syscalls/ipc/shmget/.gitignore
@@ -1,3 +1,4 @@
 /shmget02
 /shmget03
 /shmget04
+/shmget05
diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget05.c b/testcases/kernel/syscalls/ipc/shmget/shmget05.c
new file mode 100644
index 000000000..42a115474
--- /dev/null
+++ b/testcases/kernel/syscalls/ipc/shmget/shmget05.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2021 FUJITSU LIMITED. All rights reserved.
+ * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * It is a basic test for shm_next_id.
+ *
+ * shm_next_id specifies desired id for next allocated IPC shared memory. By
+ * default it's equal to -1, which means generic allocation logic.
+ * Possible values to set are in range {0..INT_MAX}.
+ * The value will be set back to -1 by kernel after successful IPC object
+ * allocation.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
+#include "libnewipc.h"
+
+#define NEXT_ID_PATH "/proc/sys/kernel/shm_next_id"
+static int shm_id, pid;
+static key_t shmkey;
+
+static void verify_shmget(void)
+{
+	SAFE_FILE_PRINTF(NEXT_ID_PATH, "%d", pid);
+
+	shm_id = SAFE_SHMGET(shmkey, SHM_SIZE, SHM_RW | IPC_CREAT);
+	if (shm_id == pid)
+		tst_res(TPASS, "shm_next_id succeeded, shm id %d", pid);
+	else
+		tst_res(TFAIL, "shm_next_id failed, expected id %d, but got %d", pid, shm_id);
+
+	TST_ASSERT_INT(NEXT_ID_PATH, -1);
+	SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
+	pid++;
+}
+
+static void setup(void)
+{
+	shmkey = GETIPCKEY();
+	pid = getpid();
+}
+
+static void cleanup(void)
+{
+	if (shm_id != -1)
+		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
+}
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = verify_shmget,
+	.needs_kconfigs = (const char *[]) {
+		"CONFIG_CHECKPOINT_RESTORE=y",
+		NULL
+	},
+	.needs_root = 1,
+};
-- 
2.23.0


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

* [LTP] [PATCH v2 2/2] syscalls/shmget06: Add test when shm_next_id is already in use
  2021-07-23  9:41     ` [LTP] [PATCH v2 1/2] syscalls/shmget05: Add test for /proc/sys/kernel/shm_next_id Yang Xu
@ 2021-07-23  9:42       ` Yang Xu
  2021-07-27  2:13         ` xuyang2018.jy
  0 siblings, 1 reply; 21+ messages in thread
From: Yang Xu @ 2021-07-23  9:42 UTC (permalink / raw)
  To: ltp

When the identifier of the System V shared memory segment that shm_next_id stored
is already in use, shmget() with different key will return the another shm id. But
kernel doesn't guarantee desired id, I just compare with the existed id, if not
equal, the test succeeds.

This case is similar to msgget05.c.

Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
---
 runtest/syscalls                              |  1 +
 runtest/syscalls-ipc                          |  1 +
 .../kernel/syscalls/ipc/shmget/.gitignore     |  1 +
 .../kernel/syscalls/ipc/shmget/shmget06.c     | 75 +++++++++++++++++++
 4 files changed, 78 insertions(+)
 create mode 100644 testcases/kernel/syscalls/ipc/shmget/shmget06.c

diff --git a/runtest/syscalls b/runtest/syscalls
index b65b18c32..b379b2d90 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1413,6 +1413,7 @@ shmget02 shmget02
 shmget03 shmget03
 shmget04 shmget04
 shmget05 shmget05
+shmget06 shmget06
 
 sigaction01 sigaction01
 sigaction02 sigaction02
diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
index ff0364704..b758158c3 100644
--- a/runtest/syscalls-ipc
+++ b/runtest/syscalls-ipc
@@ -68,3 +68,4 @@ shmget02 shmget02
 shmget03 shmget03
 shmget04 shmget04
 shmget05 shmget05
+shmget06 shmget06
diff --git a/testcases/kernel/syscalls/ipc/shmget/.gitignore b/testcases/kernel/syscalls/ipc/shmget/.gitignore
index 6f08529f8..768d1c69d 100644
--- a/testcases/kernel/syscalls/ipc/shmget/.gitignore
+++ b/testcases/kernel/syscalls/ipc/shmget/.gitignore
@@ -2,3 +2,4 @@
 /shmget03
 /shmget04
 /shmget05
+/shmget06
diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget06.c b/testcases/kernel/syscalls/ipc/shmget/shmget06.c
new file mode 100644
index 000000000..d91b7b635
--- /dev/null
+++ b/testcases/kernel/syscalls/ipc/shmget/shmget06.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2021 FUJITSU LIMITED. All rights reserved.
+ * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * It is a basic test for shm_next_id.
+ *
+ * When the shared memory segment identifier that shm_next_id stored is already
+ * in use, call shmget with different key just use another unused value in range
+ * [0,INT_MAX]. Kernel doesn't guarantee the desired id.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
+#include "libnewipc.h"
+
+#define NEXT_ID_PATH "/proc/sys/kernel/shm_next_id"
+
+static int shm_id[2], pid;
+static key_t shmkey[2];
+
+static void verify_shmget(void)
+{
+	SAFE_FILE_PRINTF(NEXT_ID_PATH, "%d", shm_id[0]);
+
+	shm_id[1] = SAFE_SHMGET(shmkey[1], SHM_SIZE, IPC_CREAT | SHM_RW);
+	if (shm_id[1] == shm_id[0])
+		tst_res(TFAIL, "shm id %d has existed, shmget() returns the"
+			" same shm id unexpectedly", shm_id[0]);
+	else
+		tst_res(TPASS, "shm id %d has existed, shmget() returns the"
+			" new shm id %d", shm_id[0], shm_id[1]);
+
+	SAFE_SHMCTL(shm_id[1], IPC_RMID, NULL);
+}
+
+static void setup(void)
+{
+	shmkey[0] = GETIPCKEY();
+	shmkey[1] = GETIPCKEY();
+	pid = getpid();
+	SAFE_FILE_PRINTF(NEXT_ID_PATH, "%d", pid);
+	shm_id[0] = SAFE_SHMGET(shmkey[0], SHM_SIZE, IPC_CREAT | SHM_RW);
+}
+
+static void cleanup(void)
+{
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		if (shm_id[i] != -1)
+			SAFE_SHMCTL(shm_id[i], IPC_RMID, NULL);
+	}
+}
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = verify_shmget,
+	.needs_kconfigs = (const char *[]) {
+		"CONFIG_CHECKPOINT_RESTORE=y",
+		NULL
+	},
+	.needs_root = 1,
+};
-- 
2.23.0


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

* [LTP] [PATCH v2 2/2] syscalls/shmget06: Add test when shm_next_id is already in use
  2021-07-23  9:42       ` [LTP] [PATCH v2 2/2] syscalls/shmget06: Add test when shm_next_id is already in use Yang Xu
@ 2021-07-27  2:13         ` xuyang2018.jy
  0 siblings, 0 replies; 21+ messages in thread
From: xuyang2018.jy @ 2021-07-27  2:13 UTC (permalink / raw)
  To: ltp

Hi Cyril

I have merged this patchset, thanks for your review.

Best Regards
Yang Xu
> When the identifier of the System V shared memory segment that shm_next_id stored
> is already in use, shmget() with different key will return the another shm id. But
> kernel doesn't guarantee desired id, I just compare with the existed id, if not
> equal, the test succeeds.
> 
> This case is similar to msgget05.c.
> 
> Reviewed-by: Cyril Hrubis<chrubis@suse.cz>
> Signed-off-by: Yang Xu<xuyang2018.jy@fujitsu.com>
> ---
>   runtest/syscalls                              |  1 +
>   runtest/syscalls-ipc                          |  1 +
>   .../kernel/syscalls/ipc/shmget/.gitignore     |  1 +
>   .../kernel/syscalls/ipc/shmget/shmget06.c     | 75 +++++++++++++++++++
>   4 files changed, 78 insertions(+)
>   create mode 100644 testcases/kernel/syscalls/ipc/shmget/shmget06.c
> 
> diff --git a/runtest/syscalls b/runtest/syscalls
> index b65b18c32..b379b2d90 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -1413,6 +1413,7 @@ shmget02 shmget02
>   shmget03 shmget03
>   shmget04 shmget04
>   shmget05 shmget05
> +shmget06 shmget06
> 
>   sigaction01 sigaction01
>   sigaction02 sigaction02
> diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
> index ff0364704..b758158c3 100644
> --- a/runtest/syscalls-ipc
> +++ b/runtest/syscalls-ipc
> @@ -68,3 +68,4 @@ shmget02 shmget02
>   shmget03 shmget03
>   shmget04 shmget04
>   shmget05 shmget05
> +shmget06 shmget06
> diff --git a/testcases/kernel/syscalls/ipc/shmget/.gitignore b/testcases/kernel/syscalls/ipc/shmget/.gitignore
> index 6f08529f8..768d1c69d 100644
> --- a/testcases/kernel/syscalls/ipc/shmget/.gitignore
> +++ b/testcases/kernel/syscalls/ipc/shmget/.gitignore
> @@ -2,3 +2,4 @@
>   /shmget03
>   /shmget04
>   /shmget05
> +/shmget06
> diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget06.c b/testcases/kernel/syscalls/ipc/shmget/shmget06.c
> new file mode 100644
> index 000000000..d91b7b635
> --- /dev/null
> +++ b/testcases/kernel/syscalls/ipc/shmget/shmget06.c
> @@ -0,0 +1,75 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2021 FUJITSU LIMITED. All rights reserved.
> + * Author: Yang Xu<xuyang2018.jy@fujitsu.com>
> + */
> +
> +/*\
> + * [Description]
> + *
> + * It is a basic test for shm_next_id.
> + *
> + * When the shared memory segment identifier that shm_next_id stored is already
> + * in use, call shmget with different key just use another unused value in range
> + * [0,INT_MAX]. Kernel doesn't guarantee the desired id.
> + */
> +
> +#include<errno.h>
> +#include<string.h>
> +#include<sys/types.h>
> +#include<sys/ipc.h>
> +#include<sys/shm.h>
> +#include "tst_test.h"
> +#include "tst_safe_sysv_ipc.h"
> +#include "libnewipc.h"
> +
> +#define NEXT_ID_PATH "/proc/sys/kernel/shm_next_id"
> +
> +static int shm_id[2], pid;
> +static key_t shmkey[2];
> +
> +static void verify_shmget(void)
> +{
> +	SAFE_FILE_PRINTF(NEXT_ID_PATH, "%d", shm_id[0]);
> +
> +	shm_id[1] = SAFE_SHMGET(shmkey[1], SHM_SIZE, IPC_CREAT | SHM_RW);
> +	if (shm_id[1] == shm_id[0])
> +		tst_res(TFAIL, "shm id %d has existed, shmget() returns the"
> +			" same shm id unexpectedly", shm_id[0]);
> +	else
> +		tst_res(TPASS, "shm id %d has existed, shmget() returns the"
> +			" new shm id %d", shm_id[0], shm_id[1]);
> +
> +	SAFE_SHMCTL(shm_id[1], IPC_RMID, NULL);
> +}
> +
> +static void setup(void)
> +{
> +	shmkey[0] = GETIPCKEY();
> +	shmkey[1] = GETIPCKEY();
> +	pid = getpid();
> +	SAFE_FILE_PRINTF(NEXT_ID_PATH, "%d", pid);
> +	shm_id[0] = SAFE_SHMGET(shmkey[0], SHM_SIZE, IPC_CREAT | SHM_RW);
> +}
> +
> +static void cleanup(void)
> +{
> +	int i;
> +
> +	for (i = 0; i<  2; i++) {
> +		if (shm_id[i] != -1)
> +			SAFE_SHMCTL(shm_id[i], IPC_RMID, NULL);
> +	}
> +}
> +
> +static struct tst_test test = {
> +	.needs_tmpdir = 1,
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.test_all = verify_shmget,
> +	.needs_kconfigs = (const char *[]) {
> +		"CONFIG_CHECKPOINT_RESTORE=y",
> +		NULL
> +	},
> +	.needs_root = 1,
> +};

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

end of thread, other threads:[~2021-07-27  2:13 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-12  8:52 [LTP] [PATCH v1 1/4] syscalls/shmget01: Remove it Yang Xu
2021-05-12  8:52 ` [LTP] [PATCH v1 2/4] syscalls/shmget*: Convert into new api Yang Xu
2021-05-12 10:44   ` xuyang2018.jy
2021-06-03  9:49     ` xuyang2018.jy
2021-06-18 14:28   ` Cyril Hrubis
2021-06-21  9:48     ` xuyang2018.jy
2021-06-22  8:31     ` [LTP] [PATCH v2] " Yang Xu
2021-06-23 13:35       ` Cyril Hrubis
2021-06-24  3:46         ` xuyang2018.jy
2021-05-12  8:52 ` [LTP] [PATCH v1 3/4] syscalls/shmget05: Add test for /proc/sys/kernel/shm_next_id Yang Xu
2021-06-29  3:25   ` xuyang2018.jy
2021-07-12  2:37     ` xuyang2018.jy
2021-07-22 11:52   ` Cyril Hrubis
2021-07-23  9:10     ` xuyang2018.jy
2021-05-12  8:52 ` [LTP] [PATCH v1 4/4] syscalls/shmget06: Add test when the id of shm_next_id has existed Yang Xu
2021-07-22 12:08   ` Cyril Hrubis
2021-07-23  9:15     ` xuyang2018.jy
2021-07-23  9:41     ` [LTP] [PATCH v2 1/2] syscalls/shmget05: Add test for /proc/sys/kernel/shm_next_id Yang Xu
2021-07-23  9:42       ` [LTP] [PATCH v2 2/2] syscalls/shmget06: Add test when shm_next_id is already in use Yang Xu
2021-07-27  2:13         ` xuyang2018.jy
2021-06-18 12:54 ` [LTP] [PATCH v1 1/4] syscalls/shmget01: Remove it Cyril Hrubis

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.