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