@@ -1,51 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) Huawei Technologies Co., Ltd., 2015
- * 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.
+ * Copyright (C) 2022 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/
-/*
- * Verify that:
- * A process created via fork(2) or clone(2) without the
- * CLONE_NEWUSER flag is a member of the same user namespace as its
- * parent.
- * When unshare an user namespace, the calling process is moved into
- * a new user namespace which is not shared with any previously
- * existing process.
+/*\
+ * [Description]
+ *
+ * Verify that if a process created via fork(2) or clone(2) without the
+ * CLONE_NEWUSER flag is a member of the same user namespace as its parent.
+ * When unshare an user namespace, the calling process is moved into a new user
+ * namespace which is not shared with any previously existing process.
*/
#define _GNU_SOURCE
-#include <sys/wait.h>
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include "userns_helper.h"
-#include "test.h"
-
-char *TCID = "user_namespace5";
-int TST_TOTAL = 1;
-static void cleanup(void)
-{
- tst_rmdir();
-}
+#include <stdio.h>
+#include <stdbool.h>
+#include "tst_test.h"
+#include "common.h"
/*
* child_fn1() - Inside a new user namespace
*/
static int child_fn1(void)
{
- TST_SAFE_CHECKPOINT_WAIT(NULL, 0);
+ TST_CHECKPOINT_WAIT(0);
return 0;
}
@@ -57,86 +37,82 @@ static unsigned int getusernsidbypid(int pid)
sprintf(path, "/proc/%d/ns/user", pid);
- if (readlink(path, userid, BUFSIZ) == -1)
- tst_resm(TFAIL | TERRNO, "readlink failure.");
+ SAFE_READLINK(path, userid, BUFSIZ);
+
+ if (sscanf(userid, "user:[%u]", &id) < 0)
+ tst_brk(TBROK | TERRNO, "sscanf failure");
- if (sscanf(userid, "user:[%u]", &id) != 1)
- tst_resm(TFAIL, "sscanf failure.");
return id;
}
-static void test_userns_id(void)
+static void run(void)
{
int cpid1, cpid2, cpid3;
unsigned int parentuserns, cpid1userns, cpid2userns, newparentuserns;
parentuserns = getusernsidbypid(getpid());
- cpid1 = ltp_clone_quick(SIGCHLD, (void *)child_fn1,
- NULL);
+
+ cpid1 = ltp_clone_quick(SIGCHLD, (void *)child_fn1, NULL);
if (cpid1 < 0)
- tst_brkm(TBROK | TERRNO, cleanup, "clone failed");
+ tst_brk(TBROK | TTERRNO, "clone failed");
+
cpid1userns = getusernsidbypid(cpid1);
- TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);
+
+ TST_CHECKPOINT_WAKE(0);
/* A process created via fork(2) or clone(2) without the
- CLONE_NEWUSER flag is a member of the same user namespace as its
- parent.*/
+ * CLONE_NEWUSER flag is a member of the same user namespace as its
+ * parent
+ */
if (parentuserns != cpid1userns)
- tst_resm(TFAIL, "userns:parent should be equal to cpid1");
+ tst_res(TFAIL, "userns:parent should be equal to cpid1");
+ else
+ tst_res(TPASS, "userns:parent is equal to cpid1");
- cpid2 = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD,
- (void *)child_fn1, NULL);
+ cpid2 = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, (void *)child_fn1, NULL);
if (cpid2 < 0)
- tst_brkm(TBROK | TERRNO, cleanup, "clone failed");
+ tst_brk(TBROK | TTERRNO, "clone failed");
+
cpid2userns = getusernsidbypid(cpid2);
- TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);
+
+ TST_CHECKPOINT_WAKE(0);
if (parentuserns == cpid2userns)
- tst_resm(TFAIL, "userns:parent should be not equal to cpid2");
-
- switch (cpid3 = fork()) {
- case -1:
- tst_brkm(TBROK | TERRNO, cleanup, "fork");
- case 0:
- if (unshare(CLONE_NEWUSER) == -1) {
- printf("parent pid unshare failure: (%d) %s",
- errno, strerror(errno));
- exit(1);
- }
+ tst_res(TFAIL, "userns:parent should be not equal to cpid2");
+ else
+ tst_res(TPASS, "userns:parent is not equal to cpid2");
+
+ cpid3 = SAFE_FORK();
+ if (!cpid3) {
+ SAFE_UNSHARE(CLONE_NEWUSER);
newparentuserns = getusernsidbypid(getpid());
/* When unshare an user namespace, the calling process
- is moved into a new user namespace which is not shared
- with any previously existing process.*/
+ * is moved into a new user namespace which is not shared
+ * with any previously existing process
+ */
if (parentuserns == newparentuserns)
- exit(1);
- exit(0);
- }
+ tst_res(TFAIL, "unshared namespaces with same id");
+ else
+ tst_res(TPASS, "unshared namespaces with different id");
- tst_record_childstatus(cleanup, cpid1);
- tst_record_childstatus(cleanup, cpid2);
- tst_record_childstatus(cleanup, cpid3);
+ return;
+ }
}
static void setup(void)
{
check_newuser();
-
- tst_tmpdir();
- TST_CHECKPOINT_INIT(NULL);
}
-int main(int argc, char *argv[])
-{
- int lc;
-
- tst_parse_opts(argc, argv, NULL, NULL);
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
- test_userns_id();
- }
- cleanup();
- tst_exit();
-}
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .needs_root = 1,
+ .forks_child = 1,
+ .needs_checkpoints = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_USER_NS",
+ NULL,
+ },
+};
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.de> --- testcases/kernel/containers/userns/userns05.c | 148 ++++++++---------- 1 file changed, 62 insertions(+), 86 deletions(-)