Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(268)

Side by Side Diff: sandbox/linux/services/credentials_unittest.cc

Issue 54643010: Linux: add basic unprivileged namespace support. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: A tiny bit more testing. Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "sandbox/linux/services/credentials.h" 5 #include "sandbox/linux/services/credentials.h"
6 6
7 #include <unistd.h>
8
7 #include "base/logging.h" 9 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
9 #include "sandbox/linux/tests/unit_tests.h" 11 #include "sandbox/linux/tests/unit_tests.h"
10 #include "testing/gtest/include/gtest/gtest.h" 12 #include "testing/gtest/include/gtest/gtest.h"
11 13
12 namespace sandbox { 14 namespace sandbox {
13 15
16 namespace {
17
18 bool DirectoryExists(const char* path) {
19 struct stat dir;
20 errno = 0;
21 int ret = stat(path, &dir);
22 return -1 != ret || ENOENT != errno;
23 }
24
25 bool WorkingDirectoryIsRoot() {
26 char current_dir[PATH_MAX];
27 char* cwd = getcwd(current_dir, sizeof(current_dir));
28 PCHECK(cwd);
29 if (strcmp("/", cwd)) return false;
30
31 // The current directory is the root. Add a few paranoid checks.
32 struct stat current;
33 CHECK_EQ(0, stat(".", &current));
34 struct stat parrent;
35 CHECK_EQ(0, stat("..", &parrent));
36 CHECK_EQ(current.st_dev, parrent.st_dev);
37 CHECK_EQ(current.st_ino, parrent.st_ino);
38 CHECK_EQ(current.st_mode, parrent.st_mode);
39 CHECK_EQ(current.st_uid, parrent.st_uid);
40 CHECK_EQ(current.st_gid, parrent.st_gid);
41 return true;
42 }
43
14 // Give dynamic tools a simple thing to test. 44 // Give dynamic tools a simple thing to test.
15 TEST(Credentials, CreateAndDestroy) { 45 TEST(Credentials, CreateAndDestroy) {
16 { 46 {
17 Credentials cred1; 47 Credentials cred1;
18 (void) cred1; 48 (void) cred1;
19 } 49 }
20 scoped_ptr<Credentials> cred2(new Credentials); 50 scoped_ptr<Credentials> cred2(new Credentials);
21 } 51 }
22 52
23 SANDBOX_TEST(Credentials, DropAllCaps) { 53 SANDBOX_TEST(Credentials, DropAllCaps) {
24 Credentials creds; 54 Credentials creds;
25 creds.DropAllCapabilities(); 55 CHECK(creds.DropAllCapabilities());
26 SANDBOX_ASSERT(!creds.HasAnyCapability()); 56 CHECK(!creds.HasAnyCapability());
27 } 57 }
28 58
29 SANDBOX_TEST(Credentials, GetCurrentCapString) { 59 SANDBOX_TEST(Credentials, GetCurrentCapString) {
30 Credentials creds; 60 Credentials creds;
31 creds.DropAllCapabilities(); 61 CHECK(creds.DropAllCapabilities());
32 const char kNoCapabilityText[] = "="; 62 const char kNoCapabilityText[] = "=";
33 SANDBOX_ASSERT(*creds.GetCurrentCapString() == kNoCapabilityText); 63 CHECK(*creds.GetCurrentCapString() == kNoCapabilityText);
34 } 64 }
35 65
66 SANDBOX_TEST(Credentials, MoveToNewUserNS) {
67 Credentials creds;
68 creds.DropAllCapabilities();
69 bool userns_supported = creds.MoveToNewUserNS();
70 printf("Unprivileged CLONE_NEWUSER supported: %s\n",
71 userns_supported ? "true." : "false.");
72 if (!userns_supported) {
73 printf("This kernel does not support unprivileged namespaces. "
74 "USERNS tests will all pass.\n");
75 return;
76 }
77 CHECK(creds.HasAnyCapability());
78 creds.DropAllCapabilities();
79 CHECK(!creds.HasAnyCapability());
80 }
81
82 SANDBOX_TEST(Credentials, UidIsPreserved) {
83 Credentials creds;
84 creds.DropAllCapabilities();
85 uid_t old_ruid, old_euid, old_suid;
86 gid_t old_rgid, old_egid, old_sgid;
87 PCHECK(0 == getresuid(&old_ruid, &old_euid, &old_suid));
88 PCHECK(0 == getresgid(&old_rgid, &old_egid, &old_sgid));
89 // Probably missing kernel support.
90 if (!creds.MoveToNewUserNS()) return;
91 uid_t new_ruid, new_euid, new_suid;
92 PCHECK(0 == getresuid(&new_ruid, &new_euid, &new_suid));
93 CHECK(old_ruid == new_ruid);
94 CHECK(old_euid == new_euid);
95 CHECK(old_suid == new_suid);
96
97 gid_t new_rgid, new_egid, new_sgid;
98 PCHECK(0 == getresgid(&new_rgid, &new_egid, &new_sgid));
99 CHECK(old_rgid == new_rgid);
100 CHECK(old_egid == new_egid);
101 CHECK(old_sgid == new_sgid);
102 }
103
104 bool NewUserNSCycle(Credentials* creds) {
105 DCHECK(creds);
106 if (!creds->MoveToNewUserNS() ||
107 !creds->HasAnyCapability() ||
108 !creds->DropAllCapabilities() ||
109 creds->HasAnyCapability()) {
110 return false;
111 }
112 return true;
113 }
114
115 SANDBOX_TEST(Credentials, NestedUserNS) {
116 Credentials creds;
117 CHECK(creds.DropAllCapabilities());
118 // Probably missing kernel support.
119 if (!creds.MoveToNewUserNS()) return;
120 creds.DropAllCapabilities();
121 // As of 3.12, the kernel has a limit of 32. See create_user_ns().
122 const int kNestLevel = 10;
123 for (int i = 0; i < kNestLevel; ++i) {
124 CHECK(NewUserNSCycle(&creds)) << "Creating new user NS failed at iteration "
125 << i << ".";
126 }
127 }
128
129 // Test the WorkingDirectoryIsRoot() helper.
130 TEST(Credentials, CanDetectRoot) {
131 ASSERT_EQ(0, chdir("/proc/"));
132 ASSERT_FALSE(WorkingDirectoryIsRoot());
133 ASSERT_EQ(0, chdir("/"));
134 ASSERT_TRUE(WorkingDirectoryIsRoot());
135 }
136
137 SANDBOX_TEST(Credentials, DropFileSystemAccessIsSafe) {
138 Credentials creds;
139 CHECK(creds.DropAllCapabilities());
140 // Probably missing kernel support.
141 if (!creds.MoveToNewUserNS()) return;
142 CHECK(creds.DropFileSystemAccess());
143 CHECK(!DirectoryExists("/proc"));
144 CHECK(WorkingDirectoryIsRoot());
145 // We want the chroot to never have a subdirectory. A subdirectory
146 // could allow a chroot escape.
147 CHECK_NE(0, mkdir("/test", 0700));
148 }
149
150 // Check that after dropping filesystem access and dropping privileges
151 // it is not possible to regain capabilities.
152 SANDBOX_TEST(Credentials, CannotRegainPrivileges) {
153 Credentials creds;
154 CHECK(creds.DropAllCapabilities());
155 // Probably missing kernel support.
156 if (!creds.MoveToNewUserNS()) return;
157 CHECK(creds.DropFileSystemAccess());
158 CHECK(creds.DropAllCapabilities());
159
160 // The kernel should now prevent us from regaining capabilities because we
161 // are in a chroot.
162 CHECK(!creds.MoveToNewUserNS());
163 }
164
165 } // namespace.
166
36 } // namespace sandbox. 167 } // namespace sandbox.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698