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