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 the minijail0 CLI using gtest.
6 *
7 * Note: We don't verify that the minijail struct was set correctly from these
8 * flags as only libminijail.c knows that definition. If we wanted to improve
9 * this test, we'd have to pull that struct into a common (internal) header.
10 */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14
15 #include <gtest/gtest.h>
16
17 #include "config_parser.h"
18 #include "libminijail.h"
19 #include "minijail0_cli.h"
20 #include "test_util.h"
21
22 namespace {
23
24 constexpr char kValidUser[] = "nobody";
25 constexpr char kValidUid[] = "100";
26 constexpr char kValidGroup[] = "users";
27 constexpr char kValidGid[] = "100";
28
29 class CliTest : public ::testing::Test {
30 protected:
SetUp()31 virtual void SetUp() {
32 // Most tests do not care about this logic. For the few that do, make
33 // them opt into it so they can validate specifically.
34 elftype_ = ELFDYNAMIC;
35 }
TearDown()36 virtual void TearDown() {}
37
38 // We use a vector of strings rather than const char * pointers because we
39 // need the backing memory to be writable. The CLI might mutate the strings
40 // as it parses things (which is normally permissible with argv).
parse_args_(const std::vector<std::string> & argv,int * exit_immediately,ElfType * elftype)41 int parse_args_(const std::vector<std::string>& argv,
42 int* exit_immediately,
43 ElfType* elftype) {
44 // Make sure we reset the getopts state when scanning a new argv. Setting
45 // this to 0 is a GNU extension, but AOSP/BSD also checks this (as an alias
46 // to their "optreset").
47 optind = 0;
48
49 // We create & destroy this for every parse_args call because some API
50 // calls can dupe memory which confuses LSAN. https://crbug.com/844615
51 struct minijail *j = minijail_new();
52
53 std::vector<const char *> pargv;
54 pargv.push_back("minijail0");
55 for (const std::string& arg : argv)
56 pargv.push_back(arg.c_str());
57
58 // We grab stdout from parse_args itself as it might dump things we don't
59 // usually care about like help output.
60 testing::internal::CaptureStdout();
61
62 const char* preload_path = PRELOADPATH;
63 char **envp = NULL;
64 int ret =
65 parse_args(j, pargv.size(), const_cast<char* const*>(pargv.data()),
66 NULL, exit_immediately, elftype, &preload_path, &envp);
67 testing::internal::GetCapturedStdout();
68
69 minijail_destroy(j);
70
71 return ret;
72 }
73
parse_args_(const std::vector<std::string> & argv)74 int parse_args_(const std::vector<std::string>& argv) {
75 return parse_args_(argv, &exit_immediately_, &elftype_);
76 }
77
78 ElfType elftype_;
79 int exit_immediately_;
80 };
81
82 } // namespace
83
84 // Should exit non-zero when there's no arguments.
TEST_F(CliTest,no_args)85 TEST_F(CliTest, no_args) {
86 std::vector<std::string> argv = {};
87 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
88 }
89
90 // Should exit zero when we asked for help.
TEST_F(CliTest,help)91 TEST_F(CliTest, help) {
92 std::vector<std::string> argv = {"-h"};
93 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(0), "");
94
95 argv = {"--help"};
96 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(0), "");
97
98 argv = {"-H"};
99 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(0), "");
100 }
101
102 // Just a simple program to run.
TEST_F(CliTest,valid_program)103 TEST_F(CliTest, valid_program) {
104 std::vector<std::string> argv = {"/bin/sh"};
105 ASSERT_TRUE(parse_args_(argv));
106 }
107
108 // Valid calls to the change user option.
TEST_F(CliTest,valid_set_user)109 TEST_F(CliTest, valid_set_user) {
110 std::vector<std::string> argv = {"-u", "", "/bin/sh"};
111
112 argv[1] = kValidUser;
113 ASSERT_TRUE(parse_args_(argv));
114
115 argv[1] = kValidUid;
116 ASSERT_TRUE(parse_args_(argv));
117 }
118
119 // Invalid calls to the change user option.
TEST_F(CliTest,invalid_set_user)120 TEST_F(CliTest, invalid_set_user) {
121 std::vector<std::string> argv = {"-u", "", "/bin/sh"};
122 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
123
124 argv[1] = "j;lX:J*Pj;oijfs;jdlkjC;j";
125 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
126
127 argv[1] = "1000x";
128 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
129
130 // Supplying -u more than once is bad.
131 argv = {"-u", kValidUser, "-u", kValidUid, "/bin/sh"};
132 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1),
133 "-u provided multiple times");
134 }
135
136 // Valid calls to the change group option.
TEST_F(CliTest,valid_set_group)137 TEST_F(CliTest, valid_set_group) {
138 std::vector<std::string> argv = {"-g", "", "/bin/sh"};
139
140 argv[1] = kValidGroup;
141 ASSERT_TRUE(parse_args_(argv));
142
143 argv[1] = kValidGid;
144 ASSERT_TRUE(parse_args_(argv));
145 }
146
147 // Invalid calls to the change group option.
TEST_F(CliTest,invalid_set_group)148 TEST_F(CliTest, invalid_set_group) {
149 std::vector<std::string> argv = {"-g", "", "/bin/sh"};
150 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
151
152 argv[1] = "j;lX:J*Pj;oijfs;jdlkjC;j";
153 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
154
155 argv[1] = "1000x";
156 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
157
158 // Supplying -g more than once is bad.
159 argv = {"-g", kValidGroup, "-g", kValidGid, "/bin/sh"};
160 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1),
161 "-g provided multiple times");
162 }
163
164 // Valid calls to the add-suppl-group option.
TEST_F(CliTest,valid_add_supp_group)165 TEST_F(CliTest, valid_add_supp_group) {
166 std::vector<std::string> argv = {"--add-suppl-group", "", "/bin/sh"};
167
168 argv[1] = kValidGroup;
169 ASSERT_TRUE(parse_args_(argv));
170
171 argv[1] = kValidGid;
172 ASSERT_TRUE(parse_args_(argv));
173
174 std::vector<std::string> argv2 = {"--add-suppl-group", "",
175 "--add-suppl-group", "", "/bin/sh"};
176 argv[1] = kValidGroup;
177 argv[2] = kValidGid;
178 ASSERT_TRUE(parse_args_(argv));
179 }
180
181 // Invalid calls to the add-suppl-group option.
TEST_F(CliTest,invalid_add_supp_group)182 TEST_F(CliTest, invalid_add_supp_group) {
183 std::vector<std::string> argv = {"--add-suppl-group", "", "/bin/sh"};
184
185 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
186
187 argv[1] = "j;lX:J*Pj;oijfs;jdlkjC;j";
188 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
189
190 argv[1] = "1000x";
191 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
192 }
193
194 // Valid calls to the skip securebits option.
TEST_F(CliTest,valid_skip_securebits)195 TEST_F(CliTest, valid_skip_securebits) {
196 // An empty string is the same as 0.
197 std::vector<std::string> argv = {"-B", "", "/bin/sh"};
198 ASSERT_TRUE(parse_args_(argv));
199
200 argv[1] = "0xAB";
201 ASSERT_TRUE(parse_args_(argv));
202
203 argv[1] = "1234";
204 ASSERT_TRUE(parse_args_(argv));
205 }
206
207 // Invalid calls to the skip securebits option.
TEST_F(CliTest,invalid_skip_securebits)208 TEST_F(CliTest, invalid_skip_securebits) {
209 std::vector<std::string> argv = {"-B", "", "/bin/sh"};
210
211 argv[1] = "xja";
212 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
213 }
214
215 // Valid calls to the caps option.
TEST_F(CliTest,valid_caps)216 TEST_F(CliTest, valid_caps) {
217 // An empty string is the same as 0.
218 std::vector<std::string> argv = {"-c", "", "/bin/sh"};
219 ASSERT_TRUE(parse_args_(argv));
220
221 argv[1] = "0xAB";
222 ASSERT_TRUE(parse_args_(argv));
223
224 argv[1] = "1234";
225 ASSERT_TRUE(parse_args_(argv));
226 }
227
228 // Invalid calls to the caps option.
TEST_F(CliTest,invalid_caps)229 TEST_F(CliTest, invalid_caps) {
230 std::vector<std::string> argv = {"-c", "", "/bin/sh"};
231
232 argv[1] = "xja";
233 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
234 }
235
236 // Valid calls to the logging option.
TEST_F(CliTest,valid_logging)237 TEST_F(CliTest, valid_logging) {
238 std::vector<std::string> argv = {"--logging", "", "/bin/sh"};
239
240 // This should list all valid logging targets.
241 const std::vector<std::string> profiles = {
242 "stderr",
243 "syslog",
244 };
245
246 for (const auto& profile : profiles) {
247 argv[1] = profile;
248 ASSERT_TRUE(parse_args_(argv));
249 }
250 }
251
252 // Invalid calls to the logging option.
TEST_F(CliTest,invalid_logging)253 TEST_F(CliTest, invalid_logging) {
254 std::vector<std::string> argv = {"--logging", "", "/bin/sh"};
255 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
256
257 argv[1] = "stdout";
258 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
259 }
260
261 // Valid calls to the rlimit option.
TEST_F(CliTest,valid_rlimit)262 TEST_F(CliTest, valid_rlimit) {
263 std::vector<std::string> argv = {"-R", "", "/bin/sh"};
264
265 argv[1] = "0,1,2";
266 ASSERT_TRUE(parse_args_(argv));
267
268 argv[1] = "0,0x100,4";
269 ASSERT_TRUE(parse_args_(argv));
270
271 argv[1] = "1,1,unlimited";
272 ASSERT_TRUE(parse_args_(argv));
273
274 argv[1] = "2,unlimited,2";
275 ASSERT_TRUE(parse_args_(argv));
276
277 argv[1] = "RLIMIT_AS,unlimited,unlimited";
278 ASSERT_TRUE(parse_args_(argv));
279 }
280
281 // Invalid calls to the rlimit option.
TEST_F(CliTest,invalid_rlimit)282 TEST_F(CliTest, invalid_rlimit) {
283 std::vector<std::string> argv = {"-R", "", "/bin/sh"};
284 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
285
286 // Missing cur & max.
287 argv[1] = "0";
288 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
289
290 // Missing max.
291 argv[1] = "0,0";
292 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
293
294 // Too many options.
295 argv[1] = "0,0,0,0";
296 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
297
298 // Non-numeric limits
299 argv[1] = "0,0,invalid-limit";
300 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
301
302 // Invalid number.
303 argv[1] = "0,0,0j";
304 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
305
306 // Invalid hex number.
307 argv[1] = "0,0x1jf,0";
308 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
309
310 // Invalid rlimit constant.
311 argv[1] = "RLIMIT_GOGOOGOG,0,0";
312 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
313 }
314
315 // Valid calls to the profile option.
TEST_F(CliTest,valid_profile)316 TEST_F(CliTest, valid_profile) {
317 std::vector<std::string> argv = {"--profile", "", "/bin/sh"};
318
319 // This should list all valid profiles.
320 const std::vector<std::string> profiles = {
321 "minimalistic-mountns",
322 "minimalistic-mountns-nodev",
323 };
324
325 for (const auto& profile : profiles) {
326 argv[1] = profile;
327 ASSERT_TRUE(parse_args_(argv));
328 }
329 }
330
331 // Invalid calls to the profile option.
TEST_F(CliTest,invalid_profile)332 TEST_F(CliTest, invalid_profile) {
333 std::vector<std::string> argv = {"--profile", "", "/bin/sh"};
334 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
335
336 argv[1] = "random-unknown-profile";
337 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
338 }
339
340 // Valid calls to the chroot option.
TEST_F(CliTest,valid_chroot)341 TEST_F(CliTest, valid_chroot) {
342 std::vector<std::string> argv = {"-C", "/", "/bin/sh"};
343 ASSERT_TRUE(parse_args_(argv));
344 }
345
346 // Valid calls to the pivot root option.
TEST_F(CliTest,valid_pivot_root)347 TEST_F(CliTest, valid_pivot_root) {
348 std::vector<std::string> argv = {"-P", "/", "/bin/sh"};
349 ASSERT_TRUE(parse_args_(argv));
350 }
351
352 // We cannot handle multiple options with chroot/profile/pivot root.
TEST_F(CliTest,conflicting_roots)353 TEST_F(CliTest, conflicting_roots) {
354 std::vector<std::string> argv;
355
356 // Chroot & pivot root.
357 argv = {"-C", "/", "-P", "/", "/bin/sh"};
358 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
359
360 // Chroot & minimalistic-mountns profile.
361 argv = {"-C", "/", "--profile", "minimalistic-mountns", "/bin/sh"};
362 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
363
364 // Pivot root & minimalistic-mountns profile.
365 argv = {"-P", "/", "--profile", "minimalistic-mountns", "/bin/sh"};
366 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
367 }
368
369 // Valid calls to the uidmap option.
TEST_F(CliTest,valid_uidmap)370 TEST_F(CliTest, valid_uidmap) {
371 std::vector<std::string> argv = {"-m", "/bin/sh"};
372 // Use a default map (no option from user).
373 ASSERT_TRUE(parse_args_(argv));
374
375 // Use a single map.
376 argv = {"-m0 0 1", "/bin/sh"};
377 ASSERT_TRUE(parse_args_(argv));
378
379 // Multiple maps.
380 argv = {"-m0 0 1,100 100 1", "/bin/sh"};
381 ASSERT_TRUE(parse_args_(argv));
382 }
383
384 // Valid calls to the gidmap option.
TEST_F(CliTest,valid_gidmap)385 TEST_F(CliTest, valid_gidmap) {
386 std::vector<std::string> argv = {"-M", "/bin/sh"};
387 // Use a default map (no option from user).
388 ASSERT_TRUE(parse_args_(argv));
389
390 // Use a single map.
391 argv = {"-M0 0 1", "/bin/sh"};
392 ASSERT_TRUE(parse_args_(argv));
393
394 // Multiple maps.
395 argv = {"-M0 0 1,100 100 1", "/bin/sh"};
396 ASSERT_TRUE(parse_args_(argv));
397 }
398
399 // Invalid calls to the uidmap/gidmap options.
400 // Note: Can't really test these as all validation is delayed/left to the
401 // runtime kernel. Minijail will simply write verbatim what the user gave
402 // it to the corresponding /proc/.../[ug]id_map.
403
404 // Valid calls to the binding option.
TEST_F(CliTest,valid_binding)405 TEST_F(CliTest, valid_binding) {
406 std::vector<std::string> argv = {"-v", "-b", "", "/bin/sh"};
407
408 // Dest & writable are optional.
409 argv[1] = "/";
410 ASSERT_TRUE(parse_args_(argv));
411
412 // Writable is optional.
413 argv[1] = "/,/";
414 ASSERT_TRUE(parse_args_(argv));
415
416 // Writable is an integer.
417 argv[1] = "/,/,0";
418 ASSERT_TRUE(parse_args_(argv));
419 argv[1] = "/,/,1";
420 ASSERT_TRUE(parse_args_(argv));
421
422 // Dest is optional.
423 argv[1] = "/,,0";
424 ASSERT_TRUE(parse_args_(argv));
425 }
426
427 // Invalid calls to the binding option.
TEST_F(CliTest,invalid_binding)428 TEST_F(CliTest, invalid_binding) {
429 std::vector<std::string> argv = {"-v", "-b", "", "/bin/sh"};
430
431 // Missing source.
432 argv[2] = "";
433 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
434
435 // Too many args.
436 argv[2] = "/,/,0,what";
437 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
438
439 // Missing mount namespace/etc...
440 argv = {"-b", "/", "/bin/sh"};
441 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
442
443 // Bad value for <writable>.
444 argv = {"-b", "/,,writable", "/bin/sh"};
445 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
446 }
447
448 // Valid calls to the mount option.
TEST_F(CliTest,valid_mount)449 TEST_F(CliTest, valid_mount) {
450 std::vector<std::string> argv = {"-v", "-k", "", "/bin/sh"};
451
452 // Flags & data are optional.
453 argv[2] = "none,/,none";
454 ASSERT_TRUE(parse_args_(argv));
455
456 // Data is optional.
457 argv[2] = "none,/,none,0xe";
458 ASSERT_TRUE(parse_args_(argv));
459
460 // Flags are optional.
461 argv[2] = "none,/,none,,mode=755";
462 ASSERT_TRUE(parse_args_(argv));
463
464 // Multiple data options to the kernel.
465 argv[2] = "none,/,none,0xe,mode=755,uid=0,gid=10";
466 ASSERT_TRUE(parse_args_(argv));
467
468 // Single MS constant.
469 argv[2] = "none,/,none,MS_NODEV,mode=755";
470 ASSERT_TRUE(parse_args_(argv));
471
472 // Multiple MS constants.
473 argv[2] = "none,/,none,MS_NODEV|MS_NOEXEC,mode=755";
474 ASSERT_TRUE(parse_args_(argv));
475
476 // Mixed constant & number.
477 argv[2] = "none,/,none,MS_NODEV|0xf,mode=755";
478 ASSERT_TRUE(parse_args_(argv));
479 }
480
481 // Invalid calls to the mount option.
TEST_F(CliTest,invalid_mount)482 TEST_F(CliTest, invalid_mount) {
483 std::vector<std::string> argv = {"-v", "-k", "", "/bin/sh"};
484
485 // Missing source.
486 argv[2] = "";
487 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
488
489 // Missing dest.
490 argv[2] = "none";
491 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
492
493 // Missing type.
494 argv[2] = "none,/";
495 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
496
497 // Unknown MS constant.
498 argv[2] = "none,/,none,MS_WHOOPS";
499 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
500 }
501
502 // Valid calls to the remount mode option.
TEST_F(CliTest,valid_remount_mode)503 TEST_F(CliTest, valid_remount_mode) {
504 std::vector<std::string> argv = {"-v", "", "/bin/sh"};
505
506 // Mode is optional.
507 argv[1] = "-K";
508 ASSERT_TRUE(parse_args_(argv));
509
510 // This should list all valid modes.
511 const std::vector<std::string> modes = {
512 "shared",
513 "private",
514 "slave",
515 "unbindable",
516 };
517
518 for (const auto& mode : modes) {
519 argv[1] = "-K" + mode;
520 ASSERT_TRUE(parse_args_(argv));
521 }
522 }
523
524 // Invalid calls to the remount mode option.
TEST_F(CliTest,invalid_remount_mode)525 TEST_F(CliTest, invalid_remount_mode) {
526 std::vector<std::string> argv = {"-v", "", "/bin/sh"};
527
528 // Unknown mode.
529 argv[1] = "-Kfoo";
530 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
531 }
532
TEST_F(CliTest,invalid_L_combo)533 TEST_F(CliTest, invalid_L_combo) {
534 std::vector<std::string> argv = {"", "", "", "/bin/sh"};
535
536 // Cannot call minijail0 with -L and a pre-compiled seccomp policy.
537 argv[0] = "-L";
538 argv[1] = "--seccomp-bpf-binary";
539 argv[2] = "source";
540 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
541
542 argv[0] = "--seccomp-bpf-binary";
543 argv[1] = "source";
544 argv[2] = "-L";
545 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
546 }
547
548 // Valid calls to the clear env option.
TEST_F(CliTest,valid_clear_env)549 TEST_F(CliTest, valid_clear_env) {
550 std::vector<std::string> argv = {"--env-reset", "/bin/sh"};
551
552 ASSERT_TRUE(parse_args_(argv));
553 }
554
555 // Valid calls to the set env option.
TEST_F(CliTest,valid_set_env)556 TEST_F(CliTest, valid_set_env) {
557 std::vector<std::string> argv1 = {"--env-add", "NAME=value", "/bin/sh"};
558 ASSERT_TRUE(parse_args_(argv1));
559
560 // multiple occurences are allowed.
561 std::vector<std::string> argv2 = {"--env-add", "A=b",
562 "--env-add", "b=C=D", "/bin/sh"};
563 ASSERT_TRUE(parse_args_(argv2));
564
565 // --env-reset before any --env-add to not pass our own env.
566 std::vector<std::string> argv3 = {"--env-reset", "--env-add", "A=b", "/bin/sh"};
567 ASSERT_TRUE(parse_args_(argv3));
568
569 // --env-add before an --env-reset doesn't have any effect, but is allowed.
570 std::vector<std::string> argv4 = {"--env-add", "A=b", "--env-reset", "/bin/sh"};
571 ASSERT_TRUE(parse_args_(argv4));
572 }
573
574 // Invalid calls to the set env options.
TEST_F(CliTest,invalid_set_env)575 TEST_F(CliTest, invalid_set_env) {
576
577 // invalid env=value arguments.
578 std::vector<std::string> argv2 = {"--env-add", "", "/bin/sh"};
579
580 argv2[1] = "INVALID";
581 ASSERT_EXIT(parse_args_(argv2), testing::ExitedWithCode(1), "");
582
583 argv2[1] = "=";
584 ASSERT_EXIT(parse_args_(argv2), testing::ExitedWithCode(1), "");
585
586 argv2[1] = "=foo";
587 ASSERT_EXIT(parse_args_(argv2), testing::ExitedWithCode(1), "");
588 }
589
590 // Android unit tests do not support data file yet.
591 #if !defined(__ANDROID__)
592
TEST_F(CliTest,conf_parsing_invalid_key)593 TEST_F(CliTest, conf_parsing_invalid_key) {
594 std::vector<std::string> argv = {"--config", source_path("test/invalid.conf"),
595 "/bin/sh"};
596
597 ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
598 }
599
TEST_F(CliTest,conf_parsing)600 TEST_F(CliTest, conf_parsing) {
601 std::vector<std::string> argv = {"--config",
602 source_path("test/valid.conf"),
603 "/bin/sh"};
604
605 ASSERT_TRUE(parse_args_(argv));
606 }
607
TEST_F(CliTest,conf_parsing_with_dac_override)608 TEST_F(CliTest, conf_parsing_with_dac_override) {
609 std::vector<std::string> argv = {"-c 2", "--config",
610 source_path("test/valid.conf"),
611 "/bin/sh"};
612
613 ASSERT_TRUE(parse_args_(argv));
614 }
615
TEST_F(CliTest,conf_fs_path)616 TEST_F(CliTest, conf_fs_path) {
617 std::vector<std::string> argv = {"-c 2", "--config",
618 source_path("test/landlock.conf"),
619 "/bin/sh"};
620
621 ASSERT_TRUE(parse_args_(argv));
622 }
623
624
625 #endif // !__ANDROID__
626