Serenity Operating System
1/*
2 * Copyright (c) 2021, Max Wipfli <max.wipfli@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <LibTest/TestCase.h>
8
9#include <errno.h>
10#include <stdlib.h>
11#include <sys/stat.h>
12#include <time.h>
13#include <unistd.h>
14
15static DeprecatedString random_dirname()
16{
17 return DeprecatedString::formatted("/tmp/test_mkdir_{:04x}", (u16)rand());
18}
19
20TEST_SETUP
21{
22 srand(time(NULL));
23}
24
25TEST_CASE(basic)
26{
27 auto dirname = random_dirname();
28 int res = mkdir(dirname.characters(), 0755);
29 EXPECT(res == 0);
30
31 res = mkdir(dirname.characters(), 0755);
32 int cached_errno = errno;
33 EXPECT(res < 0);
34 EXPECT_EQ(cached_errno, EEXIST);
35}
36
37TEST_CASE(insufficient_permissions)
38{
39 VERIFY(getuid() != 0);
40 int res = mkdir("/root/foo", 0755);
41 int cached_errno = errno;
42 EXPECT(res < 0);
43 EXPECT_EQ(cached_errno, EACCES);
44}
45
46TEST_CASE(nonexistent_parent)
47{
48 auto parent = random_dirname();
49 auto child = DeprecatedString::formatted("{}/foo", parent);
50 int res = mkdir(child.characters(), 0755);
51 int cached_errno = errno;
52 EXPECT(res < 0);
53 EXPECT_EQ(cached_errno, ENOENT);
54}
55
56TEST_CASE(parent_is_file)
57{
58 int res = mkdir("/etc/passwd/foo", 0755);
59 int cached_errno = errno;
60 EXPECT(res < 0);
61 EXPECT_EQ(cached_errno, ENOTDIR);
62}
63
64TEST_CASE(pledge)
65{
66 int res = pledge("stdio cpath", nullptr);
67 EXPECT(res == 0);
68
69 auto dirname = random_dirname();
70 res = mkdir(dirname.characters(), 0755);
71 EXPECT(res == 0);
72 // FIXME: Somehow also check that mkdir() stops working when removing the cpath promise. This is currently
73 // not possible because this would prevent the unveil test case from properly working.
74}
75
76TEST_CASE(unveil)
77{
78 int res = unveil("/tmp", "rwc");
79 EXPECT(res == 0);
80
81 auto dirname = random_dirname();
82 res = mkdir(dirname.characters(), 0755);
83 EXPECT(res == 0);
84
85 res = unveil("/tmp", "rw");
86 EXPECT(res == 0);
87
88 dirname = random_dirname();
89 res = mkdir(dirname.characters(), 0755);
90 int cached_errno = errno;
91 EXPECT(res < 0);
92 EXPECT_EQ(cached_errno, EACCES);
93
94 res = unveil("/tmp", "");
95 EXPECT(res == 0);
96
97 dirname = random_dirname();
98 res = mkdir(dirname.characters(), 0755);
99 cached_errno = errno;
100 EXPECT(res < 0);
101 EXPECT_EQ(cached_errno, ENOENT);
102
103 res = unveil(nullptr, nullptr);
104 EXPECT(res == 0);
105}