fs_mgr_verity.cpp revision 092345346212f329010b453f4b1d2cb5292f7876
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <inttypes.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <unistd.h>
22#include <fcntl.h>
23#include <ctype.h>
24#include <sys/mount.h>
25#include <sys/stat.h>
26#include <errno.h>
27#include <sys/types.h>
28#include <sys/wait.h>
29#include <libgen.h>
30#include <time.h>
31
32#include <base/file.h>
33#include <private/android_filesystem_config.h>
34#include <cutils/properties.h>
35#include <logwrap/logwrap.h>
36
37#include "mincrypt/rsa.h"
38#include "mincrypt/sha.h"
39#include "mincrypt/sha256.h"
40
41#include "ext4_sb.h"
42#include "squashfs_utils.h"
43
44#include "fs_mgr.h"
45#include "fs_mgr_priv.h"
46#include "fs_mgr_priv_verity.h"
47
48#define FSTAB_PREFIX "/fstab."
49
50#define VERITY_METADATA_SIZE 32768
51#define VERITY_TABLE_RSA_KEY "/verity_key"
52#define VERITY_TABLE_HASH_IDX 8
53#define VERITY_TABLE_SALT_IDX 9
54
55#define METADATA_MAGIC 0x01564c54
56#define METADATA_TAG_MAX_LENGTH 63
57#define METADATA_EOD "eod"
58
59#define VERITY_LASTSIG_TAG "verity_lastsig"
60
61#define VERITY_STATE_TAG "verity_state"
62#define VERITY_STATE_HEADER 0x83c0ae9d
63#define VERITY_STATE_VERSION 1
64
65#define VERITY_KMSG_RESTART "dm-verity device corrupted"
66#define VERITY_KMSG_BUFSIZE 1024
67
68#define __STRINGIFY(x) #x
69#define STRINGIFY(x) __STRINGIFY(x)
70
71struct verity_state {
72    uint32_t header;
73    uint32_t version;
74    int32_t mode;
75};
76
77extern struct fs_info info;
78
79static RSAPublicKey *load_key(const char *path)
80{
81    RSAPublicKey* key = static_cast<RSAPublicKey*>(malloc(sizeof(RSAPublicKey)));
82    if (!key) {
83        ERROR("Can't malloc key\n");
84        return NULL;
85    }
86
87    FILE* f = fopen(path, "r");
88    if (!f) {
89        ERROR("Can't open '%s'\n", path);
90        free(key);
91        return NULL;
92    }
93
94    if (!fread(key, sizeof(*key), 1, f)) {
95        ERROR("Could not read key!");
96        fclose(f);
97        free(key);
98        return NULL;
99    }
100
101    if (key->len != RSANUMWORDS) {
102        ERROR("Invalid key length %d\n", key->len);
103        fclose(f);
104        free(key);
105        return NULL;
106    }
107
108    fclose(f);
109    return key;
110}
111
112static int verify_table(char *signature, char *table, int table_length)
113{
114    RSAPublicKey *key;
115    uint8_t hash_buf[SHA256_DIGEST_SIZE];
116    int retval = -1;
117
118    // Hash the table
119    SHA256_hash((uint8_t*)table, table_length, hash_buf);
120
121    // Now get the public key from the keyfile
122    key = load_key(VERITY_TABLE_RSA_KEY);
123    if (!key) {
124        ERROR("Couldn't load verity keys");
125        goto out;
126    }
127
128    // verify the result
129    if (!RSA_verify(key,
130                    (uint8_t*) signature,
131                    RSANUMBYTES,
132                    (uint8_t*) hash_buf,
133                    SHA256_DIGEST_SIZE)) {
134        ERROR("Couldn't verify table.");
135        goto out;
136    }
137
138    retval = 0;
139
140out:
141    free(key);
142    return retval;
143}
144
145static int invalidate_table(char *table, int table_length)
146{
147    int n = 0;
148    int idx = 0;
149    int cleared = 0;
150
151    while (n < table_length) {
152        if (table[n++] == ' ') {
153            ++idx;
154        }
155
156        if (idx != VERITY_TABLE_HASH_IDX && idx != VERITY_TABLE_SALT_IDX) {
157            continue;
158        }
159
160        while (n < table_length && table[n] != ' ') {
161            table[n++] = '0';
162        }
163
164        if (++cleared == 2) {
165            return 0;
166        }
167    }
168
169    return -1;
170}
171
172static int squashfs_get_target_device_size(char *blk_device, uint64_t *device_size)
173{
174    struct squashfs_info sq_info;
175
176    if (squashfs_parse_sb(blk_device, &sq_info) >= 0) {
177        *device_size = sq_info.bytes_used_4K_padded;
178        return 0;
179    } else {
180        return -1;
181    }
182}
183
184static int ext4_get_target_device_size(char *blk_device, uint64_t *device_size)
185{
186    int data_device;
187    struct ext4_super_block sb;
188    struct fs_info info;
189
190    info.len = 0;  /* Only len is set to 0 to ask the device for real size. */
191
192    data_device = TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC));
193    if (data_device == -1) {
194        ERROR("Error opening block device (%s)", strerror(errno));
195        return -1;
196    }
197
198    if (TEMP_FAILURE_RETRY(lseek64(data_device, 1024, SEEK_SET)) < 0) {
199        ERROR("Error seeking to superblock");
200        close(data_device);
201        return -1;
202    }
203
204    if (!android::base::ReadFully(data_device, &sb, sizeof(sb))) {
205        ERROR("Error reading superblock");
206        close(data_device);
207        return -1;
208    }
209
210    ext4_parse_sb(&sb, &info);
211    *device_size = info.len;
212
213    close(data_device);
214    return 0;
215}
216
217static int get_fs_size(char *fs_type, char *blk_device, uint64_t *device_size) {
218    if (!strcmp(fs_type, "ext4")) {
219        if (ext4_get_target_device_size(blk_device, device_size) < 0) {
220            ERROR("Failed to get ext4 fs size on %s.", blk_device);
221            return -1;
222        }
223    } else if (!strcmp(fs_type, "squashfs")) {
224        if (squashfs_get_target_device_size(blk_device, device_size) < 0) {
225            ERROR("Failed to get squashfs fs size on %s.", blk_device);
226            return -1;
227        }
228    } else {
229        ERROR("%s: Unsupported filesystem for verity.", fs_type);
230        return -1;
231    }
232    return 0;
233}
234
235static int read_verity_metadata(uint64_t device_size, char *block_device, char **signature,
236        char **table)
237{
238    unsigned magic_number;
239    unsigned table_length;
240    int protocol_version;
241    int device;
242    int retval = FS_MGR_SETUP_VERITY_FAIL;
243
244    *signature = NULL;
245
246    if (table) {
247        *table = NULL;
248    }
249
250    device = TEMP_FAILURE_RETRY(open(block_device, O_RDONLY | O_CLOEXEC));
251    if (device == -1) {
252        ERROR("Could not open block device %s (%s).\n", block_device, strerror(errno));
253        goto out;
254    }
255
256    if (TEMP_FAILURE_RETRY(lseek64(device, device_size, SEEK_SET)) < 0) {
257        ERROR("Could not seek to start of verity metadata block.\n");
258        goto out;
259    }
260    // check the magic number
261    if (!android::base::ReadFully(device, &magic_number, sizeof(magic_number))) {
262        ERROR("Couldn't read magic number!\n");
263        goto out;
264    }
265
266#ifdef ALLOW_ADBD_DISABLE_VERITY
267    if (magic_number == VERITY_METADATA_MAGIC_DISABLE) {
268        retval = FS_MGR_SETUP_VERITY_DISABLED;
269        INFO("Attempt to cleanly disable verity - only works in USERDEBUG");
270        goto out;
271    }
272#endif
273
274    if (magic_number != VERITY_METADATA_MAGIC_NUMBER) {
275        ERROR("Couldn't find verity metadata at offset %" PRIu64 "!\n", device_size);
276        goto out;
277    }
278
279    // check the protocol version
280    if (!android::base::ReadFully(device, &protocol_version,
281            sizeof(protocol_version))) {
282        ERROR("Couldn't read verity metadata protocol version!\n");
283        goto out;
284    }
285    if (protocol_version != 0) {
286        ERROR("Got unknown verity metadata protocol version %d!\n", protocol_version);
287        goto out;
288    }
289
290    // get the signature
291    *signature = (char*) malloc(RSANUMBYTES);
292    if (!*signature) {
293        ERROR("Couldn't allocate memory for signature!\n");
294        goto out;
295    }
296    if (!android::base::ReadFully(device, *signature, RSANUMBYTES)) {
297        ERROR("Couldn't read signature from verity metadata!\n");
298        goto out;
299    }
300
301    if (!table) {
302        retval = FS_MGR_SETUP_VERITY_SUCCESS;
303        goto out;
304    }
305
306    // get the size of the table
307    if (!android::base::ReadFully(device, &table_length, sizeof(table_length))) {
308        ERROR("Couldn't get the size of the verity table from metadata!\n");
309        goto out;
310    }
311
312    // get the table + null terminator
313    *table = static_cast<char*>(malloc(table_length + 1));
314    if (!*table) {
315        ERROR("Couldn't allocate memory for verity table!\n");
316        goto out;
317    }
318    if (!android::base::ReadFully(device, *table, table_length)) {
319        ERROR("Couldn't read the verity table from metadata!\n");
320        goto out;
321    }
322
323    (*table)[table_length] = 0;
324    retval = FS_MGR_SETUP_VERITY_SUCCESS;
325
326out:
327    if (device != -1)
328        close(device);
329
330    if (retval != FS_MGR_SETUP_VERITY_SUCCESS) {
331        free(*signature);
332        *signature = NULL;
333
334        if (table) {
335            free(*table);
336            *table = NULL;
337        }
338    }
339
340    return retval;
341}
342
343static void verity_ioctl_init(struct dm_ioctl *io, char *name, unsigned flags)
344{
345    memset(io, 0, DM_BUF_SIZE);
346    io->data_size = DM_BUF_SIZE;
347    io->data_start = sizeof(struct dm_ioctl);
348    io->version[0] = 4;
349    io->version[1] = 0;
350    io->version[2] = 0;
351    io->flags = flags | DM_READONLY_FLAG;
352    if (name) {
353        strlcpy(io->name, name, sizeof(io->name));
354    }
355}
356
357static int create_verity_device(struct dm_ioctl *io, char *name, int fd)
358{
359    verity_ioctl_init(io, name, 1);
360    if (ioctl(fd, DM_DEV_CREATE, io)) {
361        ERROR("Error creating device mapping (%s)", strerror(errno));
362        return -1;
363    }
364    return 0;
365}
366
367static int get_verity_device_name(struct dm_ioctl *io, char *name, int fd, char **dev_name)
368{
369    verity_ioctl_init(io, name, 0);
370    if (ioctl(fd, DM_DEV_STATUS, io)) {
371        ERROR("Error fetching verity device number (%s)", strerror(errno));
372        return -1;
373    }
374    int dev_num = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00);
375    if (asprintf(dev_name, "/dev/block/dm-%u", dev_num) < 0) {
376        ERROR("Error getting verity block device name (%s)", strerror(errno));
377        return -1;
378    }
379    return 0;
380}
381
382static int load_verity_table(struct dm_ioctl *io, char *name, uint64_t device_size, int fd, char *table,
383        int mode)
384{
385    char *verity_params;
386    char *buffer = (char*) io;
387    size_t bufsize;
388
389    verity_ioctl_init(io, name, DM_STATUS_TABLE_FLAG);
390
391    struct dm_target_spec *tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)];
392
393    // set tgt arguments here
394    io->target_count = 1;
395    tgt->status=0;
396    tgt->sector_start=0;
397    tgt->length=device_size/512;
398    strcpy(tgt->target_type, "verity");
399
400    // build the verity params here
401    verity_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec);
402    bufsize = DM_BUF_SIZE - (verity_params - buffer);
403
404    if (mode == VERITY_MODE_EIO) {
405        // allow operation with older dm-verity drivers that are unaware
406        // of the mode parameter by omitting it; this also means that we
407        // cannot use logging mode with these drivers, they always cause
408        // an I/O error for corrupted blocks
409        strcpy(verity_params, table);
410    } else if (snprintf(verity_params, bufsize, "%s %d", table, mode) < 0) {
411        return -1;
412    }
413
414    // set next target boundary
415    verity_params += strlen(verity_params) + 1;
416    verity_params = (char*) (((unsigned long)verity_params + 7) & ~8);
417    tgt->next = verity_params - buffer;
418
419    // send the ioctl to load the verity table
420    if (ioctl(fd, DM_TABLE_LOAD, io)) {
421        ERROR("Error loading verity table (%s)", strerror(errno));
422        return -1;
423    }
424
425    return 0;
426}
427
428static int resume_verity_table(struct dm_ioctl *io, char *name, int fd)
429{
430    verity_ioctl_init(io, name, 0);
431    if (ioctl(fd, DM_DEV_SUSPEND, io)) {
432        ERROR("Error activating verity device (%s)", strerror(errno));
433        return -1;
434    }
435    return 0;
436}
437
438static int test_access(char *device) {
439    int tries = 25;
440    while (tries--) {
441        if (!access(device, F_OK) || errno != ENOENT) {
442            return 0;
443        }
444        usleep(40 * 1000);
445    }
446    return -1;
447}
448
449static int check_verity_restart(const char *fname)
450{
451    char buffer[VERITY_KMSG_BUFSIZE + 1];
452    int fd;
453    int rc = 0;
454    ssize_t size;
455    struct stat s;
456
457    fd = TEMP_FAILURE_RETRY(open(fname, O_RDONLY | O_CLOEXEC));
458
459    if (fd == -1) {
460        if (errno != ENOENT) {
461            ERROR("Failed to open %s (%s)\n", fname, strerror(errno));
462        }
463        goto out;
464    }
465
466    if (fstat(fd, &s) == -1) {
467        ERROR("Failed to fstat %s (%s)\n", fname, strerror(errno));
468        goto out;
469    }
470
471    size = VERITY_KMSG_BUFSIZE;
472
473    if (size > s.st_size) {
474        size = s.st_size;
475    }
476
477    if (lseek(fd, s.st_size - size, SEEK_SET) == -1) {
478        ERROR("Failed to lseek %jd %s (%s)\n", (intmax_t)(s.st_size - size), fname,
479            strerror(errno));
480        goto out;
481    }
482
483    if (!android::base::ReadFully(fd, buffer, size)) {
484        ERROR("Failed to read %zd bytes from %s (%s)\n", size, fname,
485            strerror(errno));
486        goto out;
487    }
488
489    buffer[size] = '\0';
490
491    if (strstr(buffer, VERITY_KMSG_RESTART) != NULL) {
492        rc = 1;
493    }
494
495out:
496    if (fd != -1) {
497        close(fd);
498    }
499
500    return rc;
501}
502
503static int was_verity_restart()
504{
505    static const char *files[] = {
506        "/sys/fs/pstore/console-ramoops",
507        "/proc/last_kmsg",
508        NULL
509    };
510    int i;
511
512    for (i = 0; files[i]; ++i) {
513        if (check_verity_restart(files[i])) {
514            return 1;
515        }
516    }
517
518    return 0;
519}
520
521static int metadata_add(FILE *fp, long start, const char *tag,
522        unsigned int length, off64_t *offset)
523{
524    if (fseek(fp, start, SEEK_SET) < 0 ||
525        fprintf(fp, "%s %u\n", tag, length) < 0) {
526        return -1;
527    }
528
529    *offset = ftell(fp);
530
531    if (fseek(fp, length, SEEK_CUR) < 0 ||
532        fprintf(fp, METADATA_EOD " 0\n") < 0) {
533        return -1;
534    }
535
536    return 0;
537}
538
539static int metadata_find(const char *fname, const char *stag,
540        unsigned int slength, off64_t *offset)
541{
542    FILE *fp = NULL;
543    char tag[METADATA_TAG_MAX_LENGTH + 1];
544    int rc = -1;
545    int n;
546    long start = 0x4000; /* skip cryptfs metadata area */
547    uint32_t magic;
548    unsigned int length = 0;
549
550    if (!fname) {
551        return -1;
552    }
553
554    fp = fopen(fname, "r+");
555
556    if (!fp) {
557        ERROR("Failed to open %s (%s)\n", fname, strerror(errno));
558        goto out;
559    }
560
561    /* check magic */
562    if (fseek(fp, start, SEEK_SET) < 0 ||
563        fread(&magic, sizeof(magic), 1, fp) != 1) {
564        ERROR("Failed to read magic from %s (%s)\n", fname, strerror(errno));
565        goto out;
566    }
567
568    if (magic != METADATA_MAGIC) {
569        magic = METADATA_MAGIC;
570
571        if (fseek(fp, start, SEEK_SET) < 0 ||
572            fwrite(&magic, sizeof(magic), 1, fp) != 1) {
573            ERROR("Failed to write magic to %s (%s)\n", fname, strerror(errno));
574            goto out;
575        }
576
577        rc = metadata_add(fp, start + sizeof(magic), stag, slength, offset);
578        if (rc < 0) {
579            ERROR("Failed to add metadata to %s: %s\n", fname, strerror(errno));
580        }
581
582        goto out;
583    }
584
585    start += sizeof(magic);
586
587    while (1) {
588        n = fscanf(fp, "%" STRINGIFY(METADATA_TAG_MAX_LENGTH) "s %u\n",
589                tag, &length);
590
591        if (n == 2 && strcmp(tag, METADATA_EOD)) {
592            /* found a tag */
593            start = ftell(fp);
594
595            if (!strcmp(tag, stag) && length == slength) {
596                *offset = start;
597                rc = 0;
598                goto out;
599            }
600
601            start += length;
602
603            if (fseek(fp, length, SEEK_CUR) < 0) {
604                ERROR("Failed to seek %s (%s)\n", fname, strerror(errno));
605                goto out;
606            }
607        } else {
608            rc = metadata_add(fp, start, stag, slength, offset);
609            if (rc < 0) {
610                ERROR("Failed to write metadata to %s: %s\n", fname,
611                    strerror(errno));
612            }
613            goto out;
614        }
615   }
616
617out:
618    if (fp) {
619        fflush(fp);
620        fclose(fp);
621    }
622
623    return rc;
624}
625
626static int write_verity_state(const char *fname, off64_t offset, int32_t mode)
627{
628    int fd;
629    int rc = -1;
630    struct verity_state s = { VERITY_STATE_HEADER, VERITY_STATE_VERSION, mode };
631
632    fd = TEMP_FAILURE_RETRY(open(fname, O_WRONLY | O_SYNC | O_CLOEXEC));
633
634    if (fd == -1) {
635        ERROR("Failed to open %s (%s)\n", fname, strerror(errno));
636        goto out;
637    }
638
639    if (TEMP_FAILURE_RETRY(pwrite64(fd, &s, sizeof(s), offset)) != sizeof(s)) {
640        ERROR("Failed to write %zu bytes to %s to offset %" PRIu64 " (%s)\n",
641            sizeof(s), fname, offset, strerror(errno));
642        goto out;
643    }
644
645    rc = 0;
646
647out:
648    if (fd != -1) {
649        close(fd);
650    }
651
652    return rc;
653}
654
655static int read_verity_state(const char *fname, off64_t offset, int *mode)
656{
657    int fd = -1;
658    int rc = -1;
659    struct verity_state s;
660
661    fd = TEMP_FAILURE_RETRY(open(fname, O_RDONLY | O_CLOEXEC));
662
663    if (fd == -1) {
664        ERROR("Failed to open %s (%s)\n", fname, strerror(errno));
665        goto out;
666    }
667
668    if (TEMP_FAILURE_RETRY(pread64(fd, &s, sizeof(s), offset)) != sizeof(s)) {
669        ERROR("Failed to read %zu bytes from %s offset %" PRIu64 " (%s)\n",
670            sizeof(s), fname, offset, strerror(errno));
671        goto out;
672    }
673
674    if (s.header != VERITY_STATE_HEADER) {
675        /* space allocated, but no state written. write default state */
676        *mode = VERITY_MODE_DEFAULT;
677        rc = write_verity_state(fname, offset, *mode);
678        goto out;
679    }
680
681    if (s.version != VERITY_STATE_VERSION) {
682        ERROR("Unsupported verity state version (%u)\n", s.version);
683        goto out;
684    }
685
686    if (s.mode < VERITY_MODE_EIO ||
687        s.mode > VERITY_MODE_LAST) {
688        ERROR("Unsupported verity mode (%u)\n", s.mode);
689        goto out;
690    }
691
692    *mode = s.mode;
693    rc = 0;
694
695out:
696    if (fd != -1) {
697        close(fd);
698    }
699
700    return rc;
701}
702
703static int compare_last_signature(struct fstab_rec *fstab, int *match)
704{
705    char tag[METADATA_TAG_MAX_LENGTH + 1];
706    char *signature = NULL;
707    int fd = -1;
708    int rc = -1;
709    uint8_t curr[SHA256_DIGEST_SIZE];
710    uint8_t prev[SHA256_DIGEST_SIZE];
711    off64_t offset = 0;
712    uint64_t device_size;
713
714    *match = 1;
715
716    // get verity filesystem size
717    if (get_fs_size(fstab->fs_type, fstab->blk_device, &device_size) < 0) {
718        ERROR("Failed to get filesystem size\n");
719        goto out;
720    }
721
722    if (read_verity_metadata(device_size, fstab->blk_device, &signature, NULL) < 0) {
723        ERROR("Failed to read verity signature from %s\n", fstab->mount_point);
724        goto out;
725    }
726
727    SHA256_hash(signature, RSANUMBYTES, curr);
728
729    if (snprintf(tag, sizeof(tag), VERITY_LASTSIG_TAG "_%s",
730            basename(fstab->mount_point)) >= (int)sizeof(tag)) {
731        ERROR("Metadata tag name too long for %s\n", fstab->mount_point);
732        goto out;
733    }
734
735    if (metadata_find(fstab->verity_loc, tag, SHA256_DIGEST_SIZE,
736            &offset) < 0) {
737        goto out;
738    }
739
740    fd = TEMP_FAILURE_RETRY(open(fstab->verity_loc, O_RDWR | O_SYNC | O_CLOEXEC));
741
742    if (fd == -1) {
743        ERROR("Failed to open %s: %s\n", fstab->verity_loc, strerror(errno));
744        goto out;
745    }
746
747    if (TEMP_FAILURE_RETRY(pread64(fd, prev, sizeof(prev),
748            offset)) != sizeof(prev)) {
749        ERROR("Failed to read %zu bytes from %s offset %" PRIu64 " (%s)\n",
750            sizeof(prev), fstab->verity_loc, offset, strerror(errno));
751        goto out;
752    }
753
754    *match = !memcmp(curr, prev, SHA256_DIGEST_SIZE);
755
756    if (!*match) {
757        /* update current signature hash */
758        if (TEMP_FAILURE_RETRY(pwrite64(fd, curr, sizeof(curr),
759                offset)) != sizeof(curr)) {
760            ERROR("Failed to write %zu bytes to %s offset %" PRIu64 " (%s)\n",
761                sizeof(curr), fstab->verity_loc, offset, strerror(errno));
762            goto out;
763        }
764    }
765
766    rc = 0;
767
768out:
769    free(signature);
770
771    if (fd != -1) {
772        close(fd);
773    }
774
775    return rc;
776}
777
778static int get_verity_state_offset(struct fstab_rec *fstab, off64_t *offset)
779{
780    char tag[METADATA_TAG_MAX_LENGTH + 1];
781
782    if (snprintf(tag, sizeof(tag), VERITY_STATE_TAG "_%s",
783            basename(fstab->mount_point)) >= (int)sizeof(tag)) {
784        ERROR("Metadata tag name too long for %s\n", fstab->mount_point);
785        return -1;
786    }
787
788    return metadata_find(fstab->verity_loc, tag, sizeof(struct verity_state),
789                offset);
790}
791
792static int load_verity_state(struct fstab_rec *fstab, int *mode)
793{
794    char propbuf[PROPERTY_VALUE_MAX];
795    int match = 0;
796    off64_t offset = 0;
797
798    /* use the kernel parameter if set */
799    property_get("ro.boot.veritymode", propbuf, "");
800
801    if (*propbuf != '\0') {
802        if (!strcmp(propbuf, "enforcing")) {
803            *mode = VERITY_MODE_DEFAULT;
804            return 0;
805        } else if (!strcmp(propbuf, "logging")) {
806            *mode = VERITY_MODE_LOGGING;
807            return 0;
808        } else {
809            INFO("Unknown value %s for veritymode; ignoring", propbuf);
810        }
811    }
812
813    if (get_verity_state_offset(fstab, &offset) < 0) {
814        /* fall back to stateless behavior */
815        *mode = VERITY_MODE_EIO;
816        return 0;
817    }
818
819    if (was_verity_restart()) {
820        /* device was restarted after dm-verity detected a corrupted
821         * block, so switch to logging mode */
822        *mode = VERITY_MODE_LOGGING;
823        return write_verity_state(fstab->verity_loc, offset, *mode);
824    }
825
826    if (!compare_last_signature(fstab, &match) && !match) {
827        /* partition has been reflashed, reset dm-verity state */
828        *mode = VERITY_MODE_DEFAULT;
829        return write_verity_state(fstab->verity_loc, offset, *mode);
830    }
831
832    return read_verity_state(fstab->verity_loc, offset, mode);
833}
834
835int fs_mgr_load_verity_state(int *mode)
836{
837    char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
838    char propbuf[PROPERTY_VALUE_MAX];
839    int rc = -1;
840    int i;
841    int current;
842    struct fstab *fstab = NULL;
843
844    /* return the default mode, unless any of the verified partitions are in
845     * logging mode, in which case return that */
846    *mode = VERITY_MODE_DEFAULT;
847
848    property_get("ro.hardware", propbuf, "");
849    snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
850
851    fstab = fs_mgr_read_fstab(fstab_filename);
852
853    if (!fstab) {
854        ERROR("Failed to read %s\n", fstab_filename);
855        goto out;
856    }
857
858    for (i = 0; i < fstab->num_entries; i++) {
859        if (!fs_mgr_is_verified(&fstab->recs[i])) {
860            continue;
861        }
862
863        rc = load_verity_state(&fstab->recs[i], &current);
864        if (rc < 0) {
865            continue;
866        }
867
868        if (current == VERITY_MODE_LOGGING) {
869            *mode = current;
870        }
871    }
872
873    rc = 0;
874
875out:
876    if (fstab) {
877        fs_mgr_free_fstab(fstab);
878    }
879
880    return rc;
881}
882
883int fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback)
884{
885    alignas(dm_ioctl) char buffer[DM_BUF_SIZE];
886    bool use_state = true;
887    char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
888    char *mount_point;
889    char propbuf[PROPERTY_VALUE_MAX];
890    char *status;
891    int fd = -1;
892    int i;
893    int mode;
894    int rc = -1;
895    off64_t offset = 0;
896    struct dm_ioctl *io = (struct dm_ioctl *) buffer;
897    struct fstab *fstab = NULL;
898
899    /* check if we need to store the state */
900    property_get("ro.boot.veritymode", propbuf, "");
901
902    if (*propbuf != '\0') {
903        if (fs_mgr_load_verity_state(&mode) == -1) {
904            return -1;
905        }
906        use_state = false; /* state is kept by the bootloader */
907    }
908
909    fd = TEMP_FAILURE_RETRY(open("/dev/device-mapper", O_RDWR | O_CLOEXEC));
910
911    if (fd == -1) {
912        ERROR("Error opening device mapper (%s)\n", strerror(errno));
913        goto out;
914    }
915
916    property_get("ro.hardware", propbuf, "");
917    snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
918
919    fstab = fs_mgr_read_fstab(fstab_filename);
920
921    if (!fstab) {
922        ERROR("Failed to read %s\n", fstab_filename);
923        goto out;
924    }
925
926    for (i = 0; i < fstab->num_entries; i++) {
927        if (!fs_mgr_is_verified(&fstab->recs[i])) {
928            continue;
929        }
930
931        if (use_state) {
932            if (get_verity_state_offset(&fstab->recs[i], &offset) < 0 ||
933                read_verity_state(fstab->recs[i].verity_loc, offset, &mode) < 0) {
934                continue;
935            }
936        }
937
938        mount_point = basename(fstab->recs[i].mount_point);
939        verity_ioctl_init(io, mount_point, 0);
940
941        if (ioctl(fd, DM_TABLE_STATUS, io)) {
942            ERROR("Failed to query DM_TABLE_STATUS for %s (%s)\n", mount_point,
943                strerror(errno));
944            continue;
945        }
946
947        status = &buffer[io->data_start + sizeof(struct dm_target_spec)];
948
949        if (use_state && *status == 'C') {
950            if (write_verity_state(fstab->recs[i].verity_loc, offset,
951                    VERITY_MODE_LOGGING) < 0) {
952                continue;
953            }
954        }
955
956        if (callback) {
957            callback(&fstab->recs[i], mount_point, mode, *status);
958        }
959    }
960
961    rc = 0;
962
963out:
964    if (fstab) {
965        fs_mgr_free_fstab(fstab);
966    }
967
968    if (fd) {
969        close(fd);
970    }
971
972    return rc;
973}
974
975int fs_mgr_setup_verity(struct fstab_rec *fstab) {
976
977    int retval = FS_MGR_SETUP_VERITY_FAIL;
978    int fd = -1;
979    int mode;
980
981    char *verity_blk_name = 0;
982    char *verity_table = 0;
983    char *verity_table_signature = 0;
984    int verity_table_length = 0;
985    uint64_t device_size = 0;
986
987    alignas(dm_ioctl) char buffer[DM_BUF_SIZE];
988    struct dm_ioctl *io = (struct dm_ioctl *) buffer;
989    char *mount_point = basename(fstab->mount_point);
990
991    // get verity filesystem size
992    if (get_fs_size(fstab->fs_type, fstab->blk_device, &device_size) < 0) {
993        return retval;
994    }
995
996    // read the verity block at the end of the block device
997    // send error code up the chain so we can detect attempts to disable verity
998    retval = read_verity_metadata(device_size,
999                                  fstab->blk_device,
1000                                  &verity_table_signature,
1001                                  &verity_table);
1002    if (retval < 0) {
1003        goto out;
1004    }
1005
1006    retval = FS_MGR_SETUP_VERITY_FAIL;
1007    verity_table_length = strlen(verity_table);
1008
1009    // get the device mapper fd
1010    if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
1011        ERROR("Error opening device mapper (%s)", strerror(errno));
1012        goto out;
1013    }
1014
1015    // create the device
1016    if (create_verity_device(io, mount_point, fd) < 0) {
1017        ERROR("Couldn't create verity device!");
1018        goto out;
1019    }
1020
1021    // get the name of the device file
1022    if (get_verity_device_name(io, mount_point, fd, &verity_blk_name) < 0) {
1023        ERROR("Couldn't get verity device number!");
1024        goto out;
1025    }
1026
1027    if (load_verity_state(fstab, &mode) < 0) {
1028        /* if accessing or updating the state failed, switch to the default
1029         * safe mode. This makes sure the device won't end up in an endless
1030         * restart loop, and no corrupted data will be exposed to userspace
1031         * without a warning. */
1032        mode = VERITY_MODE_EIO;
1033    }
1034
1035    // verify the signature on the table
1036    if (verify_table(verity_table_signature,
1037                            verity_table,
1038                            verity_table_length) < 0) {
1039        if (mode == VERITY_MODE_LOGGING) {
1040            // the user has been warned, allow mounting without dm-verity
1041            retval = FS_MGR_SETUP_VERITY_SUCCESS;
1042            goto out;
1043        }
1044
1045        // invalidate root hash and salt to trigger device-specific recovery
1046        if (invalidate_table(verity_table, verity_table_length) < 0) {
1047            goto out;
1048        }
1049    }
1050
1051    INFO("Enabling dm-verity for %s (mode %d)\n",  mount_point, mode);
1052
1053    // load the verity mapping table
1054    if (load_verity_table(io, mount_point, device_size, fd, verity_table,
1055            mode) < 0) {
1056        goto out;
1057    }
1058
1059    // activate the device
1060    if (resume_verity_table(io, mount_point, fd) < 0) {
1061        goto out;
1062    }
1063
1064    // mark the underlying block device as read-only
1065    fs_mgr_set_blk_ro(fstab->blk_device);
1066
1067    // assign the new verity block device as the block device
1068    free(fstab->blk_device);
1069    fstab->blk_device = verity_blk_name;
1070    verity_blk_name = 0;
1071
1072    // make sure we've set everything up properly
1073    if (test_access(fstab->blk_device) < 0) {
1074        goto out;
1075    }
1076
1077    retval = FS_MGR_SETUP_VERITY_SUCCESS;
1078
1079out:
1080    if (fd != -1) {
1081        close(fd);
1082    }
1083
1084    free(verity_table);
1085    free(verity_table_signature);
1086    free(verity_blk_name);
1087
1088    return retval;
1089}
1090