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