LCOV - code coverage report
Current view: top level - journal - test-journal-verify.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 28 55 50.9 %
Date: 2019-08-23 13:36:53 Functions: 1 3 33.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 16 56 28.6 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <fcntl.h>
       4                 :            : #include <stdio.h>
       5                 :            : #include <unistd.h>
       6                 :            : 
       7                 :            : #include "chattr-util.h"
       8                 :            : #include "fd-util.h"
       9                 :            : #include "io-util.h"
      10                 :            : #include "journal-file.h"
      11                 :            : #include "journal-verify.h"
      12                 :            : #include "log.h"
      13                 :            : #include "rm-rf.h"
      14                 :            : #include "terminal-util.h"
      15                 :            : #include "tests.h"
      16                 :            : #include "util.h"
      17                 :            : 
      18                 :            : #define N_ENTRIES 6000
      19                 :            : #define RANDOM_RANGE 77
      20                 :            : 
      21                 :          0 : static void bit_toggle(const char *fn, uint64_t p) {
      22                 :            :         uint8_t b;
      23                 :            :         ssize_t r;
      24                 :            :         int fd;
      25                 :            : 
      26                 :          0 :         fd = open(fn, O_RDWR|O_CLOEXEC);
      27         [ #  # ]:          0 :         assert_se(fd >= 0);
      28                 :            : 
      29                 :          0 :         r = pread(fd, &b, 1, p/8);
      30         [ #  # ]:          0 :         assert_se(r == 1);
      31                 :            : 
      32                 :          0 :         b ^= 1 << (p % 8);
      33                 :            : 
      34                 :          0 :         r = pwrite(fd, &b, 1, p/8);
      35         [ #  # ]:          0 :         assert_se(r == 1);
      36                 :            : 
      37                 :          0 :         safe_close(fd);
      38                 :          0 : }
      39                 :            : 
      40                 :          0 : static int raw_verify(const char *fn, const char *verification_key) {
      41                 :            :         JournalFile *f;
      42                 :            :         int r;
      43                 :            : 
      44                 :          0 :         r = journal_file_open(-1, fn, O_RDONLY, 0666, true, (uint64_t) -1, !!verification_key, NULL, NULL, NULL, NULL, &f);
      45         [ #  # ]:          0 :         if (r < 0)
      46                 :          0 :                 return r;
      47                 :            : 
      48                 :          0 :         r = journal_file_verify(f, verification_key, NULL, NULL, NULL, false);
      49                 :          0 :         (void) journal_file_close(f);
      50                 :            : 
      51                 :          0 :         return r;
      52                 :            : }
      53                 :            : 
      54                 :          4 : int main(int argc, char *argv[]) {
      55                 :          4 :         char t[] = "/var/tmp/journal-XXXXXX";
      56                 :            :         unsigned n;
      57                 :            :         JournalFile *f;
      58                 :          4 :         const char *verification_key = argv[1];
      59                 :          4 :         usec_t from = 0, to = 0, total = 0;
      60                 :            :         char a[FORMAT_TIMESTAMP_MAX];
      61                 :            :         char b[FORMAT_TIMESTAMP_MAX];
      62                 :            :         char c[FORMAT_TIMESPAN_MAX];
      63                 :            :         struct stat st;
      64                 :            :         uint64_t p;
      65                 :            : 
      66                 :            :         /* journal_file_open requires a valid machine id */
      67         [ -  + ]:          4 :         if (access("/etc/machine-id", F_OK) != 0)
      68                 :          0 :                 return log_tests_skipped("/etc/machine-id not found");
      69                 :            : 
      70                 :          4 :         test_setup_logging(LOG_DEBUG);
      71                 :            : 
      72         [ -  + ]:          4 :         assert_se(mkdtemp(t));
      73         [ -  + ]:          4 :         assert_se(chdir(t) >= 0);
      74                 :          4 :         (void) chattr_path(t, FS_NOCOW_FL, FS_NOCOW_FL, NULL);
      75                 :            : 
      76         [ +  - ]:          4 :         log_info("Generating...");
      77                 :            : 
      78         [ -  + ]:          4 :         assert_se(journal_file_open(-1, "test.journal", O_RDWR|O_CREAT, 0666, true, (uint64_t) -1, !!verification_key, NULL, NULL, NULL, NULL, &f) == 0);
      79                 :            : 
      80         [ +  + ]:      24004 :         for (n = 0; n < N_ENTRIES; n++) {
      81                 :            :                 struct iovec iovec;
      82                 :            :                 struct dual_timestamp ts;
      83                 :            :                 char *test;
      84                 :            : 
      85                 :      24000 :                 dual_timestamp_get(&ts);
      86                 :            : 
      87         [ -  + ]:      24000 :                 assert_se(asprintf(&test, "RANDOM=%lu", random() % RANDOM_RANGE));
      88                 :            : 
      89                 :      24000 :                 iovec = IOVEC_MAKE_STRING(test);
      90                 :            : 
      91         [ -  + ]:      24000 :                 assert_se(journal_file_append_entry(f, &ts, NULL, &iovec, 1, NULL, NULL, NULL) == 0);
      92                 :            : 
      93                 :      24000 :                 free(test);
      94                 :            :         }
      95                 :            : 
      96                 :          4 :         (void) journal_file_close(f);
      97                 :            : 
      98         [ +  - ]:          4 :         log_info("Verifying...");
      99                 :            : 
     100         [ -  + ]:          4 :         assert_se(journal_file_open(-1, "test.journal", O_RDONLY, 0666, true, (uint64_t) -1, !!verification_key, NULL, NULL, NULL, NULL, &f) == 0);
     101                 :            :         /* journal_file_print_header(f); */
     102                 :          4 :         journal_file_dump(f);
     103                 :            : 
     104         [ -  + ]:          4 :         assert_se(journal_file_verify(f, verification_key, &from, &to, &total, true) >= 0);
     105                 :            : 
     106   [ -  +  #  # ]:          4 :         if (verification_key && JOURNAL_HEADER_SEALED(f->header))
     107   [ #  #  #  # ]:          0 :                 log_info("=> Validated from %s to %s, %s missing",
     108                 :            :                          format_timestamp(a, sizeof(a), from),
     109                 :            :                          format_timestamp(b, sizeof(b), to),
     110                 :            :                          format_timespan(c, sizeof(c), total > to ? total - to : 0, 0));
     111                 :            : 
     112                 :          4 :         (void) journal_file_close(f);
     113                 :            : 
     114         [ -  + ]:          4 :         if (verification_key) {
     115         [ #  # ]:          0 :                 log_info("Toggling bits...");
     116                 :            : 
     117         [ #  # ]:          0 :                 assert_se(stat("test.journal", &st) >= 0);
     118                 :            : 
     119         [ #  # ]:          0 :                 for (p = 38448*8+0; p < ((uint64_t) st.st_size * 8); p ++) {
     120                 :          0 :                         bit_toggle("test.journal", p);
     121                 :            : 
     122         [ #  # ]:          0 :                         log_info("[ %"PRIu64"+%"PRIu64"]", p / 8, p % 8);
     123                 :            : 
     124         [ #  # ]:          0 :                         if (raw_verify("test.journal", verification_key) >= 0)
     125         [ #  # ]:          0 :                                 log_notice(ANSI_HIGHLIGHT_RED ">>>> %"PRIu64" (bit %"PRIu64") can be toggled without detection." ANSI_NORMAL, p / 8, p % 8);
     126                 :            : 
     127                 :          0 :                         bit_toggle("test.journal", p);
     128                 :            :                 }
     129                 :            :         }
     130                 :            : 
     131         [ +  - ]:          4 :         log_info("Exiting...");
     132                 :            : 
     133         [ -  + ]:          4 :         assert_se(rm_rf(t, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
     134                 :            : 
     135                 :          4 :         return 0;
     136                 :            : }

Generated by: LCOV version 1.14