Home | History | Annotate | Download | only in minijail
      1 /* libminijail_unittest.c
      2  * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
      3  * Use of this source code is governed by a BSD-style license that can be
      4  * found in the LICENSE file.
      5  *
      6  * Test platform independent logic of minijail.
      7  */
      8 
      9 #include <errno.h>
     10 
     11 #include <sys/types.h>
     12 #include <sys/wait.h>
     13 
     14 #include "test_harness.h"
     15 
     16 #include "libminijail.h"
     17 #include "libminijail-private.h"
     18 
     19 /* Prototypes needed only by test. */
     20 void *consumebytes(size_t length, char **buf, size_t *buflength);
     21 char *consumestr(char **buf, size_t *buflength);
     22 
     23 /* Silence unused variable warnings. */
     24 TEST(silence_unused) {
     25   EXPECT_STREQ(kLdPreloadEnvVar, kLdPreloadEnvVar);
     26   EXPECT_STREQ(kFdEnvVar, kFdEnvVar);
     27   EXPECT_STRNE(kFdEnvVar, kLdPreloadEnvVar);
     28 }
     29 
     30 TEST(consumebytes_zero) {
     31   char buf[1024];
     32   size_t len = sizeof(buf);
     33   char *pos = &buf[0];
     34   EXPECT_NE(NULL, consumebytes(0, &pos, &len));
     35   EXPECT_EQ(&buf[0], pos);
     36   EXPECT_EQ(sizeof(buf), len);
     37 }
     38 
     39 TEST(consumebytes_exact) {
     40   char buf[1024];
     41   size_t len = sizeof(buf);
     42   char *pos = &buf[0];
     43   /* One past the end since it consumes the whole buffer. */
     44   char *end = &buf[sizeof(buf)];
     45   EXPECT_NE(NULL, consumebytes(len, &pos, &len));
     46   EXPECT_EQ((size_t)0, len);
     47   EXPECT_EQ(end, pos);
     48 }
     49 
     50 TEST(consumebytes_half) {
     51   char buf[1024];
     52   size_t len = sizeof(buf);
     53   char *pos = &buf[0];
     54   /* One past the end since it consumes the whole buffer. */
     55   char *end = &buf[sizeof(buf) / 2];
     56   EXPECT_NE(NULL, consumebytes(len / 2, &pos, &len));
     57   EXPECT_EQ(sizeof(buf) / 2, len);
     58   EXPECT_EQ(end, pos);
     59 }
     60 
     61 TEST(consumebytes_toolong) {
     62   char buf[1024];
     63   size_t len = sizeof(buf);
     64   char *pos = &buf[0];
     65   /* One past the end since it consumes the whole buffer. */
     66   EXPECT_EQ(NULL, consumebytes(len + 1, &pos, &len));
     67   EXPECT_EQ(sizeof(buf), len);
     68   EXPECT_EQ(&buf[0], pos);
     69 }
     70 
     71 TEST(consumestr_zero) {
     72   char buf[1024];
     73   size_t len = 0;
     74   char *pos = &buf[0];
     75   memset(buf, 0xff, sizeof(buf));
     76   EXPECT_EQ(NULL, consumestr(&pos, &len));
     77   EXPECT_EQ((size_t)0, len);
     78   EXPECT_EQ(&buf[0], pos);
     79 }
     80 
     81 TEST(consumestr_nonul) {
     82   char buf[1024];
     83   size_t len = sizeof(buf);
     84   char *pos = &buf[0];
     85   memset(buf, 0xff, sizeof(buf));
     86   EXPECT_EQ(NULL, consumestr(&pos, &len));
     87   EXPECT_EQ(sizeof(buf), len);
     88   EXPECT_EQ(&buf[0], pos);
     89 }
     90 
     91 TEST(consumestr_full) {
     92   char buf[1024];
     93   size_t len = sizeof(buf);
     94   char *pos = &buf[0];
     95   memset(buf, 0xff, sizeof(buf));
     96   buf[sizeof(buf)-1] = '\0';
     97   EXPECT_EQ((void *)buf, consumestr(&pos, &len));
     98   EXPECT_EQ((size_t)0, len);
     99   EXPECT_EQ(&buf[sizeof(buf)], pos);
    100 }
    101 
    102 TEST(consumestr_trailing_nul) {
    103   char buf[1024];
    104   size_t len = sizeof(buf) - 1;
    105   char *pos = &buf[0];
    106   memset(buf, 0xff, sizeof(buf));
    107   buf[sizeof(buf)-1] = '\0';
    108   EXPECT_EQ(NULL, consumestr(&pos, &len));
    109   EXPECT_EQ(sizeof(buf) - 1, len);
    110   EXPECT_EQ(&buf[0], pos);
    111 }
    112 
    113 FIXTURE(marshal) {
    114   char buf[4096];
    115   struct minijail *m;
    116   struct minijail *j;
    117   size_t size;
    118 };
    119 
    120 FIXTURE_SETUP(marshal) {
    121   self->m = minijail_new();
    122   self->j = minijail_new();
    123   ASSERT_TRUE(self->m && self->j) TH_LOG("allocation failed");
    124   self->size = minijail_size(self->m);
    125   ASSERT_GT(sizeof(self->buf), self->size) {
    126     TH_LOG("static buffer too small for test");
    127   }
    128 }
    129 
    130 FIXTURE_TEARDOWN(marshal) {
    131   minijail_destroy(self->m);
    132   minijail_destroy(self->j);
    133 }
    134 
    135 TEST_F(marshal, empty) {
    136   ASSERT_EQ(0, minijail_marshal(self->m, self->buf, sizeof(self->buf)));
    137   EXPECT_EQ(0, minijail_unmarshal(self->j, self->buf, self->size));
    138 }
    139 
    140 TEST_F(marshal, 0xff) {
    141   memset(self->buf, 0xff, sizeof(self->buf));
    142   /* Should fail on the first consumestr since a NUL will never be found. */
    143   EXPECT_EQ(-EINVAL, minijail_unmarshal(self->j, self->buf, sizeof(self->buf)));
    144 }
    145 
    146 TEST(test_minijail_run_pid_pipes_no_preload) {
    147   pid_t pid;
    148   int child_stdin, child_stdout, child_stderr;
    149   int mj_run_ret;
    150   ssize_t write_ret, read_ret;
    151   const size_t buf_len = 128;
    152   char buf[buf_len];
    153   int status;
    154 #if defined(__ANDROID__)
    155   char filename[] = "/system/bin/cat";
    156 #else
    157   char filename[] = "/bin/cat";
    158 #endif
    159   char teststr[] = "test\n";
    160   size_t teststr_len = strlen(teststr);
    161   char *argv[4];
    162 
    163   struct minijail *j = minijail_new();
    164 
    165   argv[0] = filename;
    166   argv[1] = NULL;
    167   mj_run_ret = minijail_run_pid_pipes_no_preload(j, argv[0], argv,
    168                                                  &pid,
    169                                                  &child_stdin, &child_stdout,
    170                                                  NULL);
    171   EXPECT_EQ(mj_run_ret, 0);
    172 
    173   write_ret = write(child_stdin, teststr, teststr_len);
    174   EXPECT_EQ(write_ret, (int)teststr_len);
    175 
    176   read_ret = read(child_stdout, buf, 8);
    177   EXPECT_EQ(read_ret, (int)teststr_len);
    178   buf[teststr_len] = 0;
    179   EXPECT_EQ(strcmp(buf, teststr), 0);
    180 
    181   EXPECT_EQ(kill(pid, SIGTERM), 0);
    182   waitpid(pid, &status, 0);
    183   ASSERT_TRUE(WIFSIGNALED(status));
    184   EXPECT_EQ(WTERMSIG(status), SIGTERM);
    185 
    186 #if defined(__ANDROID__)
    187   argv[0] = "/system/bin/sh";
    188 #else
    189   argv[0] = "/bin/sh";
    190 #endif
    191   argv[1] = "-c";
    192   argv[2] = "echo test >&2";
    193   argv[3] = NULL;
    194   mj_run_ret = minijail_run_pid_pipes_no_preload(j, argv[0], argv, &pid,
    195                                                  &child_stdin, &child_stdout,
    196                                                  &child_stderr);
    197   EXPECT_EQ(mj_run_ret, 0);
    198 
    199   read_ret = read(child_stderr, buf, buf_len);
    200   EXPECT_GE(read_ret, (int)teststr_len);
    201 
    202   waitpid(pid, &status, 0);
    203   ASSERT_TRUE(WIFEXITED(status));
    204   EXPECT_EQ(WEXITSTATUS(status), 0);
    205 
    206   minijail_destroy(j);
    207 }
    208 
    209 TEST_HARNESS_MAIN
    210