OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Crashpad Authors. All rights reserved. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 | |
15 #include "util/posix/process_info.h" | |
16 | |
17 #include <crt_externs.h> | |
18 #include <time.h> | |
19 #include <unistd.h> | |
20 | |
21 #include <set> | |
22 #include <string> | |
23 #include <vector> | |
24 | |
25 #include "base/basictypes.h" | |
26 #include "build/build_config.h" | |
27 #include "gtest/gtest.h" | |
28 #include "util/test/errors.h" | |
29 | |
30 namespace crashpad { | |
31 namespace test { | |
32 namespace { | |
33 | |
34 void TestSelfProcess(const ProcessInfo& process_info) { | |
35 EXPECT_EQ(getpid(), process_info.ProcessID()); | |
36 EXPECT_EQ(getppid(), process_info.ParentProcessID()); | |
37 | |
38 // There’s no system call to obtain the saved set-user ID or saved set-group | |
39 // ID in an easy way. Normally, they are the same as the effective user ID and | |
40 // effective group ID, so just check against those. | |
41 EXPECT_EQ(getuid(), process_info.RealUserID()); | |
42 const uid_t euid = geteuid(); | |
43 EXPECT_EQ(euid, process_info.EffectiveUserID()); | |
44 EXPECT_EQ(euid, process_info.SavedUserID()); | |
45 const gid_t gid = getgid(); | |
46 EXPECT_EQ(gid, process_info.RealGroupID()); | |
47 const gid_t egid = getegid(); | |
48 EXPECT_EQ(egid, process_info.EffectiveGroupID()); | |
49 EXPECT_EQ(egid, process_info.SavedGroupID()); | |
50 | |
51 // Test SupplementaryGroups(). | |
52 int group_count = getgroups(0, nullptr); | |
53 ASSERT_GE(group_count, 0) << ErrnoMessage("getgroups"); | |
54 | |
55 std::vector<gid_t> group_vector(group_count); | |
56 if (group_count > 0) { | |
57 group_count = getgroups(group_vector.size(), &group_vector[0]); | |
58 ASSERT_GE(group_count, 0) << ErrnoMessage("getgroups"); | |
59 ASSERT_EQ(group_vector.size(), implicit_cast<size_t>(group_count)); | |
60 } | |
61 | |
62 std::set<gid_t> group_set(group_vector.begin(), group_vector.end()); | |
63 EXPECT_EQ(group_set, process_info.SupplementaryGroups()); | |
64 | |
65 // Test AllGroups(), which is SupplementaryGroups() plus the real, effective, | |
66 // and saved set-group IDs. The effective and saved set-group IDs are expected | |
67 // to be identical (see above). | |
68 group_set.insert(gid); | |
69 group_set.insert(egid); | |
70 | |
71 EXPECT_EQ(group_set, process_info.AllGroups()); | |
72 | |
73 // The test executable isn’t expected to change privileges. | |
74 EXPECT_FALSE(process_info.DidChangePrivileges()); | |
75 | |
76 #if defined(ARCH_CPU_64_BITS) | |
77 EXPECT_TRUE(process_info.Is64Bit()); | |
78 #else | |
79 EXPECT_FALSE(process_info.Is64Bit()); | |
80 #endif | |
81 | |
82 // Test StartTime(). This program must have started at some time in the past. | |
83 timeval start_time; | |
84 process_info.StartTime(&start_time); | |
85 time_t now; | |
86 time(&now); | |
87 EXPECT_LE(start_time.tv_sec, now); | |
88 | |
89 std::vector<std::string> argv; | |
90 ASSERT_TRUE(process_info.Arguments(&argv)); | |
91 | |
92 // gtest argv processing scrambles argv, but it leaves argc and argv[0] | |
93 // intact, so test those. | |
94 | |
95 int argc = implicit_cast<int>(argv.size()); | |
96 int expect_argc = *_NSGetArgc(); | |
Robert Sesek
2014/11/14 22:06:18
This isn't quite POSIX-y.
| |
97 EXPECT_EQ(expect_argc, argc); | |
98 | |
99 ASSERT_GE(expect_argc, 1); | |
100 ASSERT_GE(argc, 1); | |
101 | |
102 char** expect_argv = *_NSGetArgv(); | |
103 EXPECT_EQ(std::string(expect_argv[0]), argv[0]); | |
104 } | |
105 | |
106 | |
107 TEST(ProcessInfo, Self) { | |
108 ProcessInfo process_info; | |
109 ASSERT_TRUE(process_info.Initialize(getpid())); | |
110 TestSelfProcess(process_info); | |
111 } | |
112 | |
113 #if defined(OS_MACOSX) | |
114 TEST(ProcessInfo, SelfTask) { | |
115 ProcessInfo process_info; | |
116 ASSERT_TRUE(process_info.InitializeFromTask(mach_task_self())); | |
117 TestSelfProcess(process_info); | |
118 } | |
119 #endif | |
120 | |
121 TEST(ProcessInfo, Pid1) { | |
122 // PID 1 is expected to be init or the system’s equivalent. This tests reading | |
123 // information about another process. | |
124 ProcessInfo process_info; | |
125 ASSERT_TRUE(process_info.Initialize(1)); | |
126 | |
127 EXPECT_EQ(implicit_cast<pid_t>(1), process_info.ProcessID()); | |
128 EXPECT_EQ(implicit_cast<pid_t>(0), process_info.ParentProcessID()); | |
129 EXPECT_EQ(implicit_cast<uid_t>(0), process_info.RealUserID()); | |
130 EXPECT_EQ(implicit_cast<uid_t>(0), process_info.EffectiveUserID()); | |
131 EXPECT_EQ(implicit_cast<uid_t>(0), process_info.SavedUserID()); | |
132 EXPECT_EQ(implicit_cast<gid_t>(0), process_info.RealGroupID()); | |
133 EXPECT_EQ(implicit_cast<gid_t>(0), process_info.EffectiveGroupID()); | |
134 EXPECT_EQ(implicit_cast<gid_t>(0), process_info.SavedGroupID()); | |
135 EXPECT_FALSE(process_info.AllGroups().empty()); | |
136 } | |
137 | |
138 } // namespace | |
139 } // namespace test | |
140 } // namespace crashpad | |
OLD | NEW |