1 /* Copyright 2018 The ChromiumOS Authors
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Test util.[ch] module code using gtest.
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <sys/stat.h>
12 #include <unistd.h>
13
14 #include <gtest/gtest.h>
15
16 #include "bpf.h"
17 #include "test_util.h"
18 #include "util.h"
19
20 namespace {
21
dump_env(const char * const * env)22 std::string dump_env(const char* const* env) {
23 std::string result;
24 for (; *env; ++env) {
25 result += *env;
26 result += "\n";
27 }
28
29 return result;
30 }
31
32 } // namespace
33
34 // Sanity check for the strip func.
TEST(strip,basic)35 TEST(strip, basic) {
36 char str[] = " foo\t";
37 ASSERT_EQ("foo", std::string(strip(str)));
38 }
39
40 // Make sure we don't crash with various "null"-like inputs.
TEST(tokenize,null_stringp)41 TEST(tokenize, null_stringp) {
42 ASSERT_EQ(nullptr, tokenize(nullptr, nullptr));
43 ASSERT_EQ(nullptr, tokenize(nullptr, ""));
44 ASSERT_EQ(nullptr, tokenize(nullptr, ","));
45
46 char* p = nullptr;
47 ASSERT_EQ(nullptr, tokenize(&p, nullptr));
48 }
49
50 // Make sure we don't crash with various "null"-like inputs.
TEST(tokenize,null_delim)51 TEST(tokenize, null_delim) {
52 char str[] = "a,b,c";
53 char* p = str;
54 ASSERT_EQ(str, tokenize(&p, nullptr));
55 ASSERT_EQ(nullptr, p);
56 ASSERT_EQ(str, std::string("a,b,c"));
57
58 p = str;
59 ASSERT_EQ(str, tokenize(&p, ""));
60 ASSERT_EQ(nullptr, p);
61 ASSERT_EQ(str, std::string("a,b,c"));
62 }
63
64 // Sanity check for the tokenize func.
TEST(tokenize,basic)65 TEST(tokenize, basic) {
66 char str[] = "a,b,c";
67 char* p = str;
68 ASSERT_EQ("a", std::string(tokenize(&p, ",")));
69 ASSERT_EQ("b", std::string(tokenize(&p, ",")));
70 ASSERT_EQ("c", std::string(tokenize(&p, ",")));
71 ASSERT_EQ(nullptr, p);
72 ASSERT_EQ(nullptr, tokenize(&p, ","));
73 }
74
75 // Check edge case with an empty string.
TEST(tokenize,empty_string)76 TEST(tokenize, empty_string) {
77 char str[] = "";
78 char* p = str;
79 ASSERT_EQ("", std::string(tokenize(&p, ",")));
80 ASSERT_EQ(nullptr, p);
81 ASSERT_EQ(nullptr, tokenize(&p, ","));
82 }
83
84 // Check behavior with empty tokens at the start/middle/end.
TEST(tokenize,empty_tokens)85 TEST(tokenize, empty_tokens) {
86 char str[] = ",,a,b,,,c,,";
87 char* p = str;
88 ASSERT_EQ("", std::string(tokenize(&p, ",")));
89 ASSERT_EQ("", std::string(tokenize(&p, ",")));
90 ASSERT_EQ("a", std::string(tokenize(&p, ",")));
91 ASSERT_EQ("b", std::string(tokenize(&p, ",")));
92 ASSERT_EQ("", std::string(tokenize(&p, ",")));
93 ASSERT_EQ("", std::string(tokenize(&p, ",")));
94 ASSERT_EQ("c", std::string(tokenize(&p, ",")));
95 ASSERT_EQ("", std::string(tokenize(&p, ",")));
96 ASSERT_EQ("", std::string(tokenize(&p, ",")));
97 ASSERT_EQ(nullptr, p);
98 ASSERT_EQ(nullptr, tokenize(&p, ","));
99 }
100
101 // Check environment manipulation functions.
TEST(environment,copy_and_modify)102 TEST(environment, copy_and_modify) {
103 minijail_free_env(nullptr);
104
105 char** env = minijail_copy_env(nullptr);
106 EXPECT_EQ("", dump_env(env));
107 minijail_free_env(env);
108
109 const char* const kConstEnv[] = {
110 "val1=1", "val2=2", "dup=1", "dup=2", "empty=", nullptr,
111 };
112
113 // libc unfortunately uses char* const[] as the type for the environment, and
114 // we match that. It's actually missing a const-ness of the chars making up
115 // the environment strings, but we need that to initialize the |kEnv|
116 // constant. Hence, do a cast here to force things into alignment...
117 char* const* kEnv = const_cast<char* const*>(kConstEnv);
118
119 env = minijail_copy_env(kEnv);
120 EXPECT_EQ("val1=1\nval2=2\ndup=1\ndup=2\nempty=\n", dump_env(env));
121 minijail_free_env(env);
122
123 env = minijail_copy_env(kEnv);
124 EXPECT_EQ("val1=1\nval2=2\ndup=1\ndup=2\nempty=\n", dump_env(env));
125
126 EXPECT_EQ(EINVAL, minijail_setenv(nullptr, "val1", "3", 1));
127 char** env_ret = nullptr;
128 EXPECT_EQ(EINVAL, minijail_setenv(&env_ret, "val1", "3", 1));
129
130 env_ret = env;
131 EXPECT_EQ(EINVAL, minijail_setenv(&env_ret, nullptr, "3", 1));
132 EXPECT_EQ(env, env_ret);
133 EXPECT_EQ(EINVAL, minijail_setenv(&env_ret, "", "3", 1));
134 EXPECT_EQ(env, env_ret);
135 EXPECT_EQ(EINVAL, minijail_setenv(&env_ret, "", nullptr, 1));
136 EXPECT_EQ(env, env_ret);
137
138 EXPECT_EQ(0, minijail_setenv(&env, "val1", "3", 0));
139 EXPECT_EQ("val1=1\nval2=2\ndup=1\ndup=2\nempty=\n", dump_env(env));
140 EXPECT_EQ(0, minijail_setenv(&env, "val1", "3", 1));
141 EXPECT_EQ("val1=3\nval2=2\ndup=1\ndup=2\nempty=\n", dump_env(env));
142 EXPECT_EQ(0, minijail_setenv(&env, "val2", "4", 1));
143 EXPECT_EQ("val1=3\nval2=4\ndup=1\ndup=2\nempty=\n", dump_env(env));
144 EXPECT_EQ(0, minijail_setenv(&env, "dup", "5", 1));
145 EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\n", dump_env(env));
146 EXPECT_EQ(0, minijail_setenv(&env, "empty", "6", 1));
147 EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=6\n", dump_env(env));
148 EXPECT_EQ(0, minijail_setenv(&env, "empty", "", 1));
149 EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\n", dump_env(env));
150 EXPECT_EQ(0, minijail_setenv(&env, "new1", "7", 0));
151 EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\n", dump_env(env));
152 EXPECT_EQ(0, minijail_setenv(&env, "new2", "8", 1));
153 EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
154 dump_env(env));
155
156 EXPECT_EQ(nullptr, minijail_getenv(nullptr, "dup"));
157 EXPECT_EQ(nullptr, minijail_getenv(nullptr, nullptr));
158 EXPECT_EQ(nullptr, minijail_getenv(env, nullptr));
159 EXPECT_EQ(nullptr, minijail_getenv(env, "dup="));
160 EXPECT_EQ(nullptr, minijail_getenv(env, "du"));
161 EXPECT_EQ(std::string("8"), minijail_getenv(env, "new2"));
162 EXPECT_EQ(std::string("3"), minijail_getenv(env, "val1"));
163 EXPECT_EQ(std::string("5"), minijail_getenv(env, "dup"));
164
165 EXPECT_EQ(false, minijail_unsetenv(env, "nonexisting"));
166 EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
167 dump_env(env));
168 EXPECT_EQ(false, minijail_unsetenv(env, ""));
169 EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
170 dump_env(env));
171 EXPECT_EQ(false, minijail_unsetenv(env, nullptr));
172 EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
173 dump_env(env));
174 EXPECT_EQ(false, minijail_unsetenv(nullptr, nullptr));
175 EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
176 dump_env(env));
177 EXPECT_EQ(false, minijail_unsetenv(nullptr, "nonexisting"));
178 EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
179 dump_env(env));
180 EXPECT_EQ(false, minijail_unsetenv(env, "val1="));
181 EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
182 dump_env(env));
183 EXPECT_EQ(true, minijail_unsetenv(env, "val1"));
184 EXPECT_EQ("new2=8\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\n", dump_env(env));
185 EXPECT_EQ(true, minijail_unsetenv(env, "empty"));
186 EXPECT_EQ("new2=8\nval2=4\ndup=5\ndup=2\nnew1=7\n", dump_env(env));
187 EXPECT_EQ(true, minijail_unsetenv(env, "new2"));
188 EXPECT_EQ("new1=7\nval2=4\ndup=5\ndup=2\n", dump_env(env));
189 EXPECT_EQ(true, minijail_unsetenv(env, "new1"));
190 EXPECT_EQ("dup=2\nval2=4\ndup=5\n", dump_env(env));
191
192 minijail_free_env(env);
193 }
194
TEST(parse_single_constant,formats)195 TEST(parse_single_constant, formats) {
196 char* end;
197 long int c = 0;
198 std::string constant;
199
200 // Check base 10 works.
201 constant = "1234";
202 c = parse_constant(const_cast<char*>(constant.data()), &end);
203 EXPECT_EQ(1234, c);
204
205 // Check base 16 works.
206 constant = "0x1234";
207 c = parse_constant(const_cast<char*>(constant.data()), &end);
208 EXPECT_EQ(0x1234, c);
209
210 // Check base 8 works.
211 constant = "01234";
212 c = parse_constant(const_cast<char*>(constant.data()), &end);
213 EXPECT_EQ(01234, c);
214 }
215
TEST(parse_constant,unsigned)216 TEST(parse_constant, unsigned) {
217 char* end;
218 long int c = 0;
219 std::string constant;
220
221 #if defined(BITS32)
222 constant = "0x80000000";
223 c = parse_constant(const_cast<char*>(constant.data()), &end);
224 EXPECT_EQ(0x80000000U, static_cast<unsigned long int>(c));
225
226 #elif defined(BITS64)
227 constant = "0x8000000000000000";
228 c = parse_constant(const_cast<char*>(constant.data()), &end);
229 EXPECT_EQ(0x8000000000000000UL, static_cast<unsigned long int>(c));
230
231 #else
232 #error "unknown bits!"
233 #endif
234 }
235
TEST(parse_constant,unsigned_toobig)236 TEST(parse_constant, unsigned_toobig) {
237 char* end;
238 long int c = 0;
239 std::string constant;
240
241 #if defined(BITS32)
242 constant = "0x100000000"; // Too big for 32-bit unsigned long int.
243 c = parse_constant(const_cast<char*>(constant.data()), &end);
244 // Error case should return 0.
245 EXPECT_EQ(0, c);
246
247 #elif defined(BITS64)
248 constant = "0x10000000000000000";
249 c = parse_constant(const_cast<char*>(constant.data()), &end);
250 // Error case should return 0.
251 EXPECT_EQ(0, c);
252
253 #else
254 #error "unknown bits!"
255 #endif
256 }
257
TEST(parse_constant,signed)258 TEST(parse_constant, signed) {
259 char* end;
260 long int c = 0;
261 std::string constant = "-1";
262 c = parse_constant(const_cast<char*>(constant.data()), &end);
263 EXPECT_EQ(-1, c);
264 }
265
TEST(parse_constant,signed_toonegative)266 TEST(parse_constant, signed_toonegative) {
267 char* end;
268 long int c = 0;
269 std::string constant;
270
271 #if defined(BITS32)
272 constant = "-0x80000001";
273 c = parse_constant(const_cast<char*>(constant.data()), &end);
274 // Error case should return 0.
275 EXPECT_EQ(0, c);
276
277 #elif defined(BITS64)
278 constant = "-0x8000000000000001";
279 c = parse_constant(const_cast<char*>(constant.data()), &end);
280 // Error case should return 0.
281 EXPECT_EQ(0, c);
282
283 #else
284 #error "unknown bits!"
285 #endif
286 }
287
TEST(parse_constant,complements)288 TEST(parse_constant, complements) {
289 char* end;
290 long int c = 0;
291 std::string constant;
292
293 #if defined(BITS32)
294 constant = "~0x005AF0FF|~0xFFA50FFF";
295 c = parse_constant(const_cast<char*>(constant.data()), &end);
296 EXPECT_EQ(c, 0xFFFFFF00);
297 constant = "0x0F|~(0x005AF000|0x00A50FFF)|0xF0";
298 c = parse_constant(const_cast<char*>(constant.data()), &end);
299 EXPECT_EQ(c, 0xFF0000FF);
300
301 #elif defined(BITS64)
302 constant = "~0x00005A5AF0F0FFFF|~0xFFFFA5A50F0FFFFF";
303 c = parse_constant(const_cast<char*>(constant.data()), &end);
304 EXPECT_EQ(c, 0xFFFFFFFFFFFF0000UL);
305 constant = "0x00FF|~(0x00005A5AF0F00000|0x0000A5A50F0FFFFF)|0xFF00";
306 c = parse_constant(const_cast<char*>(constant.data()), &end);
307 EXPECT_EQ(c, 0xFFFF00000000FFFFUL);
308
309 #else
310 #error "unknown bits!"
311 #endif
312 }
313
TEST(parse_constant,parenthesized_expresions)314 TEST(parse_constant, parenthesized_expresions) {
315 char* end;
316
317 const std::vector<const char*> bad_expressions = {
318 "(1", "1)", "(1)1", "|(1)", "(1)|", "()",
319 "(", "((", "(()", "(()1", "1(0)",
320 };
321 for (const auto* expression : bad_expressions) {
322 std::string mutable_expression = expression;
323 long int c =
324 parse_constant(const_cast<char*>(mutable_expression.data()), &end);
325 EXPECT_EQ(reinterpret_cast<const void*>(end),
326 reinterpret_cast<const void*>(mutable_expression.data()));
327 // Error case should return 0.
328 EXPECT_EQ(c, 0) << "For expression: \"" << expression << "\"";
329 }
330
331 const std::vector<const char*> good_expressions = {
332 "(3)", "(1)|2", "1|(2)", "(1)|(2)", "((3))", "0|(1|2)", "(0|1|2)",
333 };
334 for (const auto* expression : good_expressions) {
335 std::string mutable_expression = expression;
336 long int c =
337 parse_constant(const_cast<char*>(mutable_expression.data()), &end);
338 EXPECT_EQ(c, 3) << "For expression: \"" << expression << "\"";
339 }
340 }
341
TEST(parse_size,complete)342 TEST(parse_size, complete) {
343 uint64_t size;
344
345 ASSERT_EQ(0, parse_size(&size, "42"));
346 ASSERT_EQ(42U, size);
347
348 ASSERT_EQ(0, parse_size(&size, "16K"));
349 ASSERT_EQ(16384U, size);
350
351 ASSERT_EQ(0, parse_size(&size, "1M"));
352 ASSERT_EQ(1024U * 1024, size);
353
354 uint64_t gigabyte = UINT64_C(1024) * 1024 * 1024;
355 ASSERT_EQ(0, parse_size(&size, "3G"));
356 ASSERT_EQ(3U, size / gigabyte);
357 ASSERT_EQ(0U, size % gigabyte);
358
359 ASSERT_EQ(0, parse_size(&size, "4294967294"));
360 ASSERT_EQ(3U, size / gigabyte);
361 ASSERT_EQ(gigabyte - 2, size % gigabyte);
362
363 uint64_t exabyte = gigabyte * 1024 * 1024 * 1024;
364 ASSERT_EQ(0, parse_size(&size, "9E"));
365 ASSERT_EQ(9U, size / exabyte);
366 ASSERT_EQ(0U, size % exabyte);
367
368 ASSERT_EQ(0, parse_size(&size, "15E"));
369 ASSERT_EQ(15U, size / exabyte);
370 ASSERT_EQ(0U, size % exabyte);
371
372 // Check values that don't fit in 64-bits.
373 ASSERT_EQ(-ERANGE, parse_size(&size, "16384P"));
374 ASSERT_EQ(-ERANGE, parse_size(&size, "1638400P"));
375 ASSERT_EQ(-ERANGE, parse_size(&size, "16E"));
376 ASSERT_EQ(-ERANGE, parse_size(&size, "16000000000E"));
377
378 // Check limits right around 64-bits.
379 ASSERT_EQ(0, parse_size(&size, "18446744073709551614"));
380 ASSERT_EQ(ULLONG_MAX - 1, size);
381 ASSERT_EQ(0, parse_size(&size, "18446744073709551615"));
382 ASSERT_EQ(ULLONG_MAX, size);
383 ASSERT_EQ(-ERANGE, parse_size(&size, "18446744073709551616"));
384
385 // Only allow 1 valid suffix.
386 ASSERT_EQ(-EINVAL, parse_size(&size, "7GTPE"));
387
388 // Check edge cases that strto* APIs accept, but we don't.
389 ASSERT_EQ(-EINVAL, parse_size(&size, "-8"));
390 ASSERT_EQ(-EINVAL, parse_size(&size, "+8"));
391 ASSERT_EQ(-EINVAL, parse_size(&size, " -8"));
392 ASSERT_EQ(-EINVAL, parse_size(&size, " +8"));
393
394 ASSERT_EQ(-EINVAL, parse_size(&size, ""));
395 ASSERT_EQ(-EINVAL, parse_size(&size, "14u"));
396 ASSERT_EQ(-EINVAL, parse_size(&size, "14B"));
397 ASSERT_EQ(-EINVAL, parse_size(&size, "14Z"));
398 ASSERT_EQ(-EINVAL, parse_size(&size, "14.2G"));
399 ASSERT_EQ(-EINVAL, parse_size(&size, "G"));
400 ASSERT_EQ(-EINVAL, parse_size(&size, "; /bin/rm -- "));
401 }
402
TEST(path_join,basic)403 TEST(path_join, basic) {
404 char* path = path_join("a", "b");
405 ASSERT_EQ(std::string("a/b"), path);
406 free(path);
407 }
408
TEST(path_is_parent,simple)409 TEST(path_is_parent, simple) {
410 EXPECT_TRUE(path_is_parent("/dev", "/dev/rtc"));
411 EXPECT_TRUE(path_is_parent("/dev/", "/dev/rtc"));
412 EXPECT_TRUE(path_is_parent("/sys", "/sys/power"));
413 EXPECT_TRUE(path_is_parent("/sys/power", "/sys/power/something"));
414 EXPECT_TRUE(path_is_parent("/sys", "/sys/sys/power"));
415
416 EXPECT_FALSE(path_is_parent("/dev", ""));
417 EXPECT_FALSE(path_is_parent("/dev", "/sys"));
418 EXPECT_FALSE(path_is_parent("/dev", "dev"));
419 EXPECT_FALSE(path_is_parent("/dev", "/sys/dev"));
420 EXPECT_FALSE(path_is_parent("/dev", "/device"));
421 }
422
TEST(getmultiline,basic)423 TEST(getmultiline, basic) {
424 std::string config =
425 "\n"
426 "mount = none\n"
427 "mount =\\\n"
428 "none\n"
429 "binding = none,/tmp\n"
430 "binding = none,\\\n"
431 "/tmp";
432 FILE* config_file = write_to_pipe(config);
433 ASSERT_NE(config_file, nullptr);
434
435 char* line = NULL;
436 size_t len = 0;
437 ASSERT_EQ(0, getmultiline(&line, &len, config_file));
438 EXPECT_EQ(std::string(line), "");
439 ASSERT_EQ(12, getmultiline(&line, &len, config_file));
440 EXPECT_EQ(std::string(line), "mount = none");
441 ASSERT_EQ(12, getmultiline(&line, &len, config_file));
442 EXPECT_EQ(std::string(line), "mount = none");
443 ASSERT_EQ(19, getmultiline(&line, &len, config_file));
444 EXPECT_EQ(std::string(line), "binding = none,/tmp");
445 ASSERT_EQ(20, getmultiline(&line, &len, config_file));
446 EXPECT_EQ(std::string(line), "binding = none, /tmp");
447 free(line);
448 }
449