[LTP] [PATCH v2 2/2] Add chdir() test for unprivileged user
Martin Doucha
mdoucha@suse.cz
Fri Jul 24 14:50:52 CEST 2020
chdir01 tests chdir() return values with root permissions. chdir02 does
the same test scenario with EUID set to nobody.
Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---
Changes since v1: New patch
runtest/syscalls | 1 +
testcases/kernel/syscalls/chdir/.gitignore | 1 +
testcases/kernel/syscalls/chdir/chdir02.c | 134 +++++++++++++++++++++
3 files changed, 136 insertions(+)
create mode 100644 testcases/kernel/syscalls/chdir/chdir02.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 70b3277d3..deadc21bc 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -54,6 +54,7 @@ capset04 capset04
cacheflush01 cacheflush01
chdir01 chdir01
+chdir02 chdir02
chdir01A symlink01 -T chdir01
chdir04 chdir04
diff --git a/testcases/kernel/syscalls/chdir/.gitignore b/testcases/kernel/syscalls/chdir/.gitignore
index 1b15eb6b9..3475c5e54 100644
--- a/testcases/kernel/syscalls/chdir/.gitignore
+++ b/testcases/kernel/syscalls/chdir/.gitignore
@@ -1,2 +1,3 @@
/chdir01
+/chdir02
/chdir04
diff --git a/testcases/kernel/syscalls/chdir/chdir02.c b/testcases/kernel/syscalls/chdir/chdir02.c
new file mode 100644
index 000000000..e62362808
--- /dev/null
+++ b/testcases/kernel/syscalls/chdir/chdir02.c
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) International Business Machines Corp., 2001
+ * 07/2001 Ported by Wayne Boyer
+ * Copyright (c) 2019 SUSE LLC <mdoucha@suse.cz>
+ */
+
+/*
+ * Check that the chdir() syscall returns correct value and error code
+ * in various situations when called by regular user
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <pwd.h>
+
+#include "tst_test.h"
+
+#define MNTPOINT "mntpoint"
+
+#define FILE_NAME "testfile"
+#define DIR_NAME "subdir"
+#define BLOCKED_NAME "keep_out"
+#define LINK_NAME1 "symloop"
+#define LINK_NAME2 "symloop2"
+
+static char *workdir;
+static unsigned int skip_symlinks, skip_blocked;
+static struct passwd *ltpuser;
+
+static struct test_case {
+ const char *name;
+ int retval, experr;
+} testcase_list[] = {
+ {FILE_NAME, -1, ENOTDIR},
+ {BLOCKED_NAME, -1, EACCES},
+ {DIR_NAME, 0, 0},
+ {".", 0, 0},
+ {"..", 0, 0},
+ {"/", 0, 0},
+ {"missing", -1, ENOENT},
+ {LINK_NAME1, -1, ELOOP},
+};
+
+static void setup(void)
+{
+ char *cwd;
+ int fd;
+ struct stat statbuf;
+
+ cwd = SAFE_GETCWD(NULL, 0);
+ workdir = SAFE_MALLOC(strlen(cwd) + strlen(MNTPOINT) + 2);
+ sprintf(workdir, "%s/%s", cwd, MNTPOINT);
+ free(cwd);
+ SAFE_CHDIR(workdir);
+ SAFE_MKDIR(DIR_NAME, 0755);
+ SAFE_MKDIR(BLOCKED_NAME, 0644);
+
+ /* FAT and NTFS override file and directory permissions */
+ SAFE_STAT(BLOCKED_NAME, &statbuf);
+ skip_blocked = statbuf.st_mode & 0111;
+ skip_symlinks = 0;
+ TEST(symlink(LINK_NAME1, LINK_NAME2));
+
+ if (!TST_RET)
+ SAFE_SYMLINK(LINK_NAME2, LINK_NAME1);
+ else if (TST_RET == -1 && TST_ERR == EPERM)
+ skip_symlinks = 1; /* man symlink(2): EPERM == unsupported */
+ else
+ tst_brk(TBROK | TTERRNO, "Cannot create symlinks");
+
+ fd = SAFE_CREAT(FILE_NAME, 0644);
+ SAFE_CLOSE(fd);
+
+ if (!ltpuser)
+ ltpuser = SAFE_GETPWNAM("nobody");
+
+ SAFE_SETEUID(ltpuser->pw_uid);
+}
+
+static void run(unsigned int n)
+{
+ struct test_case *tc = testcase_list + n;
+
+ if (tc->experr == EACCES && skip_blocked) {
+ tst_res(TCONF, "Skipping permission test, FS mangles dir mode");
+ return;
+ }
+
+ if (tc->experr == ELOOP && skip_symlinks) {
+ tst_res(TCONF, "Skipping symlink loop test, not supported");
+ return;
+ }
+
+ /* Reset current directory to mountpoint */
+ SAFE_CHDIR(workdir);
+
+ TEST(chdir(tc->name));
+
+ if (TST_RET != tc->retval) {
+ tst_res(TFAIL | TTERRNO,
+ "chdir(\"%s\") returned unexpected value %ld",
+ tc->name, TST_RET);
+ return;
+ }
+
+ if (TST_RET != 0 && TST_ERR != tc->experr) {
+ tst_res(TFAIL | TTERRNO,
+ "chdir(\"%s\") returned unexpected error", tc->name);
+ return;
+ }
+
+ tst_res(TPASS | TTERRNO, "chdir(\"%s\") returned correct value",
+ tc->name);
+}
+
+static void cleanup(void)
+{
+ free(workdir);
+ SAFE_SETEUID(0);
+}
+
+static struct tst_test test = {
+ .needs_root = 1,
+ .mount_device = 1,
+ .mntpoint = MNTPOINT,
+ .all_filesystems = 1,
+ .test = run,
+ .tcnt = ARRAY_SIZE(testcase_list),
+ .setup = setup,
+ .cleanup = cleanup
+};
--
2.26.2
More information about the ltp
mailing list