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