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 <fs_mgr/file_wait.h>
39 #include <libdm/dm.h>
40 #include <logwrap/logwrap.h>
41 #include <openssl/obj_mac.h>
42 #include <openssl/rsa.h>
43 #include <openssl/sha.h>
44
45 #include "fec/io.h"
46
47 #include "fs_mgr.h"
48 #include "fs_mgr_dm_linear.h"
49 #include "fs_mgr_priv.h"
50
51 // Realistically, this file should be part of the android::fs_mgr namespace;
52 using namespace android::fs_mgr;
53
54 #define VERITY_TABLE_RSA_KEY "/verity_key"
55 #define VERITY_TABLE_HASH_IDX 8
56 #define VERITY_TABLE_SALT_IDX 9
57
58 #define VERITY_TABLE_OPT_RESTART "restart_on_corruption"
59 #define VERITY_TABLE_OPT_LOGGING "ignore_corruption"
60 #define VERITY_TABLE_OPT_IGNZERO "ignore_zero_blocks"
61
62 #define VERITY_TABLE_OPT_FEC_FORMAT \
63 "use_fec_from_device %s fec_start %" PRIu64 " fec_blocks %" PRIu64 \
64 " fec_roots %u " VERITY_TABLE_OPT_IGNZERO
65 #define VERITY_TABLE_OPT_FEC_ARGS 9
66
67 #define METADATA_MAGIC 0x01564c54
68 #define METADATA_TAG_MAX_LENGTH 63
69 #define METADATA_EOD "eod"
70
71 #define VERITY_LASTSIG_TAG "verity_lastsig"
72
73 #define VERITY_STATE_TAG "verity_state"
74 #define VERITY_STATE_HEADER 0x83c0ae9d
75 #define VERITY_STATE_VERSION 1
76
77 #define VERITY_KMSG_RESTART "dm-verity device corrupted"
78 #define VERITY_KMSG_BUFSIZE 1024
79
80 #define READ_BUF_SIZE 4096
81
82 #define __STRINGIFY(x) #x
83 #define STRINGIFY(x) __STRINGIFY(x)
84
85 struct verity_state {
86 uint32_t header;
87 uint32_t version;
88 int32_t mode;
89 };
90
91 extern struct fs_info info;
92
load_key(const char * path)93 static RSA *load_key(const char *path)
94 {
95 uint8_t key_data[ANDROID_PUBKEY_ENCODED_SIZE];
96
97 auto f = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path, "re"), fclose};
98 if (!f) {
99 LERROR << "Can't open " << path;
100 return nullptr;
101 }
102
103 if (!fread(key_data, sizeof(key_data), 1, f.get())) {
104 LERROR << "Could not read key!";
105 return nullptr;
106 }
107
108 RSA* key = nullptr;
109 if (!android_pubkey_decode(key_data, sizeof(key_data), &key)) {
110 LERROR << "Could not parse key!";
111 return nullptr;
112 }
113
114 return key;
115 }
116
verify_table(const uint8_t * signature,size_t signature_size,const char * table,uint32_t table_length)117 static int verify_table(const uint8_t *signature, size_t signature_size,
118 const char *table, uint32_t table_length)
119 {
120 RSA *key;
121 uint8_t hash_buf[SHA256_DIGEST_LENGTH];
122 int retval = -1;
123
124 // Hash the table
125 SHA256((uint8_t*)table, table_length, hash_buf);
126
127 // Now get the public key from the keyfile
128 key = load_key(VERITY_TABLE_RSA_KEY);
129 if (!key) {
130 LERROR << "Couldn't load verity keys";
131 goto out;
132 }
133
134 // verify the result
135 if (!RSA_verify(NID_sha256, hash_buf, sizeof(hash_buf), signature,
136 signature_size, key)) {
137 LERROR << "Couldn't verify table";
138 goto out;
139 }
140
141 retval = 0;
142
143 out:
144 RSA_free(key);
145 return retval;
146 }
147
verify_verity_signature(const struct fec_verity_metadata & verity)148 static int verify_verity_signature(const struct fec_verity_metadata& verity)
149 {
150 if (verify_table(verity.signature, sizeof(verity.signature),
151 verity.table, verity.table_length) == 0 ||
152 verify_table(verity.ecc_signature, sizeof(verity.ecc_signature),
153 verity.table, verity.table_length) == 0) {
154 return 0;
155 }
156
157 return -1;
158 }
159
invalidate_table(char * table,size_t table_length)160 static int invalidate_table(char *table, size_t table_length)
161 {
162 size_t n = 0;
163 size_t idx = 0;
164 size_t cleared = 0;
165
166 while (n < table_length) {
167 if (table[n++] == ' ') {
168 ++idx;
169 }
170
171 if (idx != VERITY_TABLE_HASH_IDX && idx != VERITY_TABLE_SALT_IDX) {
172 continue;
173 }
174
175 while (n < table_length && table[n] != ' ') {
176 table[n++] = '0';
177 }
178
179 if (++cleared == 2) {
180 return 0;
181 }
182 }
183
184 return -1;
185 }
186
187 struct verity_table_params {
188 char *table;
189 int mode;
190 struct fec_ecc_metadata ecc;
191 const char *ecc_dev;
192 };
193
194 typedef bool (*format_verity_table_func)(char *buf, const size_t bufsize,
195 const struct verity_table_params *params);
196
format_verity_table(char * buf,const size_t bufsize,const struct verity_table_params * params)197 static bool format_verity_table(char *buf, const size_t bufsize,
198 const struct verity_table_params *params)
199 {
200 const char *mode_flag = NULL;
201 int res = -1;
202
203 if (params->mode == VERITY_MODE_RESTART) {
204 mode_flag = VERITY_TABLE_OPT_RESTART;
205 } else if (params->mode == VERITY_MODE_LOGGING) {
206 mode_flag = VERITY_TABLE_OPT_LOGGING;
207 }
208
209 if (params->ecc.valid) {
210 if (mode_flag) {
211 res = snprintf(buf, bufsize,
212 "%s %u %s " VERITY_TABLE_OPT_FEC_FORMAT,
213 params->table, 1 + VERITY_TABLE_OPT_FEC_ARGS, mode_flag, params->ecc_dev,
214 params->ecc.start / FEC_BLOCKSIZE, params->ecc.blocks, params->ecc.roots);
215 } else {
216 res = snprintf(buf, bufsize,
217 "%s %u " VERITY_TABLE_OPT_FEC_FORMAT,
218 params->table, VERITY_TABLE_OPT_FEC_ARGS, params->ecc_dev,
219 params->ecc.start / FEC_BLOCKSIZE, params->ecc.blocks, params->ecc.roots);
220 }
221 } else if (mode_flag) {
222 res = snprintf(buf, bufsize, "%s 2 " VERITY_TABLE_OPT_IGNZERO " %s", params->table,
223 mode_flag);
224 } else {
225 res = snprintf(buf, bufsize, "%s 1 " VERITY_TABLE_OPT_IGNZERO, params->table);
226 }
227
228 if (res < 0 || (size_t)res >= bufsize) {
229 LERROR << "Error building verity table; insufficient buffer size?";
230 return false;
231 }
232
233 return true;
234 }
235
format_legacy_verity_table(char * buf,const size_t bufsize,const struct verity_table_params * params)236 static bool format_legacy_verity_table(char *buf, const size_t bufsize,
237 const struct verity_table_params *params)
238 {
239 int res;
240
241 if (params->mode == VERITY_MODE_EIO) {
242 res = strlcpy(buf, params->table, bufsize);
243 } else {
244 res = snprintf(buf, bufsize, "%s %d", params->table, params->mode);
245 }
246
247 if (res < 0 || (size_t)res >= bufsize) {
248 LERROR << "Error building verity table; insufficient buffer size?";
249 return false;
250 }
251
252 return true;
253 }
254
load_verity_table(android::dm::DeviceMapper & dm,const std::string & name,uint64_t device_size,const struct verity_table_params * params,format_verity_table_func format)255 static int load_verity_table(android::dm::DeviceMapper& dm, const std::string& name,
256 uint64_t device_size, const struct verity_table_params* params,
257 format_verity_table_func format) {
258 android::dm::DmTable table;
259 table.set_readonly(true);
260
261 char buffer[DM_BUF_SIZE];
262 if (!format(buffer, sizeof(buffer), params)) {
263 LERROR << "Failed to format verity parameters";
264 return -1;
265 }
266
267 android::dm::DmTargetVerityString target(0, device_size / 512, buffer);
268 if (!table.AddTarget(std::make_unique<decltype(target)>(target))) {
269 LERROR << "Failed to add verity target";
270 return -1;
271 }
272 if (!dm.CreateDevice(name, table)) {
273 LERROR << "Failed to create verity device \"" << name << "\"";
274 return -1;
275 }
276 return 0;
277 }
278
read_partition(const char * path,uint64_t size)279 static int read_partition(const char *path, uint64_t size)
280 {
281 char buf[READ_BUF_SIZE];
282 ssize_t size_read;
283 android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC)));
284
285 if (fd == -1) {
286 PERROR << "Failed to open " << path;
287 return -errno;
288 }
289
290 while (size) {
291 size_read = TEMP_FAILURE_RETRY(read(fd, buf, READ_BUF_SIZE));
292 if (size_read == -1) {
293 PERROR << "Error in reading partition " << path;
294 return -errno;
295 }
296 size -= size_read;
297 }
298
299 return 0;
300 }
301
fs_mgr_load_verity_state(int * mode)302 bool fs_mgr_load_verity_state(int* mode) {
303 // unless otherwise specified, use EIO mode.
304 *mode = VERITY_MODE_EIO;
305
306 // The bootloader communicates verity mode via the kernel commandline
307 std::string verity_mode;
308 if (!fs_mgr_get_boot_config("veritymode", &verity_mode)) {
309 return false;
310 }
311
312 if (verity_mode == "enforcing") {
313 *mode = VERITY_MODE_DEFAULT;
314 } else if (verity_mode == "logging") {
315 *mode = VERITY_MODE_LOGGING;
316 }
317
318 return true;
319 }
320
321 // Update the verity table using the actual block device path.
322 // Two cases:
323 // Case-1: verity table is shared for devices with different by-name prefix.
324 // Example:
325 // verity table token: /dev/block/bootdevice/by-name/vendor
326 // blk_device-1 (non-A/B): /dev/block/platform/soc.0/7824900.sdhci/by-name/vendor
327 // blk_device-2 (A/B): /dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor_a
328 //
329 // Case-2: append A/B suffix in the verity table.
330 // Example:
331 // verity table token: /dev/block/platform/soc.0/7824900.sdhci/by-name/vendor
332 // blk_device: /dev/block/platform/soc.0/7824900.sdhci/by-name/vendor_a
update_verity_table_blk_device(const std::string & blk_device,char ** table,bool slot_select)333 static void update_verity_table_blk_device(const std::string& blk_device, char** table,
334 bool slot_select) {
335 bool updated = false;
336 std::string result, ab_suffix;
337 auto tokens = android::base::Split(*table, " ");
338
339 // If slot_select is set, it means blk_device is already updated with ab_suffix.
340 if (slot_select) ab_suffix = fs_mgr_get_slot_suffix();
341
342 for (const auto& token : tokens) {
343 std::string new_token;
344 if (android::base::StartsWith(token, "/dev/block/")) {
345 if (token == blk_device) return; // no need to update if they're already the same.
346 std::size_t found1 = blk_device.find("by-name");
347 std::size_t found2 = token.find("by-name");
348 if (found1 != std::string::npos && found2 != std::string::npos &&
349 blk_device.substr(found1) == token.substr(found2) + ab_suffix) {
350 new_token = blk_device;
351 }
352 }
353
354 if (!new_token.empty()) {
355 updated = true;
356 LINFO << "Verity table: updated block device from '" << token << "' to '" << new_token
357 << "'";
358 } else {
359 new_token = token;
360 }
361
362 if (result.empty()) {
363 result = new_token;
364 } else {
365 result += " " + new_token;
366 }
367 }
368
369 if (!updated) {
370 return;
371 }
372
373 free(*table);
374 *table = strdup(result.c_str());
375 }
376
377 // prepares the verity enabled (MF_VERIFY / MF_VERIFYATBOOT) fstab record for
378 // mount. The 'wait_for_verity_dev' parameter makes this function wait for the
379 // verity device to get created before return
fs_mgr_setup_verity(FstabEntry * entry,bool wait_for_verity_dev)380 int fs_mgr_setup_verity(FstabEntry* entry, bool wait_for_verity_dev) {
381 int retval = FS_MGR_SETUP_VERITY_FAIL;
382 int fd = -1;
383 std::string verity_blk_name;
384 struct fec_handle *f = NULL;
385 struct fec_verity_metadata verity;
386 struct verity_table_params params = { .table = NULL };
387
388 const std::string mount_point(basename(entry->mount_point.c_str()));
389 bool verified_at_boot = false;
390
391 android::dm::DeviceMapper& dm = android::dm::DeviceMapper::Instance();
392
393 if (fec_open(&f, entry->blk_device.c_str(), O_RDONLY, FEC_VERITY_DISABLE, FEC_DEFAULT_ROOTS) <
394 0) {
395 PERROR << "Failed to open '" << entry->blk_device << "'";
396 return retval;
397 }
398
399 // read verity metadata
400 if (fec_verity_get_metadata(f, &verity) < 0) {
401 PERROR << "Failed to get verity metadata '" << entry->blk_device << "'";
402 // Allow verity disabled when the device is unlocked without metadata
403 if (fs_mgr_is_device_unlocked()) {
404 retval = FS_MGR_SETUP_VERITY_SKIPPED;
405 LWARNING << "Allow invalid metadata when the device is unlocked";
406 }
407 goto out;
408 }
409
410 #ifdef ALLOW_ADBD_DISABLE_VERITY
411 if (verity.disabled) {
412 retval = FS_MGR_SETUP_VERITY_DISABLED;
413 LINFO << "Attempt to cleanly disable verity - only works in USERDEBUG/ENG";
414 goto out;
415 }
416 #endif
417
418 // read ecc metadata
419 if (fec_ecc_get_metadata(f, ¶ms.ecc) < 0) {
420 params.ecc.valid = false;
421 }
422
423 params.ecc_dev = entry->blk_device.c_str();
424
425 if (!fs_mgr_load_verity_state(¶ms.mode)) {
426 /* if accessing or updating the state failed, switch to the default
427 * safe mode. This makes sure the device won't end up in an endless
428 * restart loop, and no corrupted data will be exposed to userspace
429 * without a warning. */
430 params.mode = VERITY_MODE_EIO;
431 }
432
433 if (!verity.table) {
434 goto out;
435 }
436
437 params.table = strdup(verity.table);
438 if (!params.table) {
439 goto out;
440 }
441
442 // verify the signature on the table
443 if (verify_verity_signature(verity) < 0) {
444 // Allow signature verification error when the device is unlocked
445 if (fs_mgr_is_device_unlocked()) {
446 retval = FS_MGR_SETUP_VERITY_SKIPPED;
447 LWARNING << "Allow signature verification error when the device is unlocked";
448 goto out;
449 }
450 if (params.mode == VERITY_MODE_LOGGING) {
451 // the user has been warned, allow mounting without dm-verity
452 retval = FS_MGR_SETUP_VERITY_SKIPPED;
453 goto out;
454 }
455
456 // invalidate root hash and salt to trigger device-specific recovery
457 if (invalidate_table(params.table, verity.table_length) < 0) {
458 goto out;
459 }
460 }
461
462 LINFO << "Enabling dm-verity for " << mount_point.c_str()
463 << " (mode " << params.mode << ")";
464
465 // Update the verity params using the actual block device path
466 update_verity_table_blk_device(entry->blk_device, ¶ms.table,
467 entry->fs_mgr_flags.slot_select);
468
469 // load the verity mapping table
470 if (load_verity_table(dm, mount_point, verity.data_size, ¶ms, format_verity_table) == 0) {
471 goto loaded;
472 }
473
474 if (params.ecc.valid) {
475 // kernel may not support error correction, try without
476 LINFO << "Disabling error correction for " << mount_point.c_str();
477 params.ecc.valid = false;
478
479 if (load_verity_table(dm, mount_point, verity.data_size, ¶ms, format_verity_table) == 0) {
480 goto loaded;
481 }
482 }
483
484 // try the legacy format for backwards compatibility
485 if (load_verity_table(dm, mount_point, verity.data_size, ¶ms, format_legacy_verity_table) ==
486 0) {
487 goto loaded;
488 }
489
490 if (params.mode != VERITY_MODE_EIO) {
491 // as a last resort, EIO mode should always be supported
492 LINFO << "Falling back to EIO mode for " << mount_point.c_str();
493 params.mode = VERITY_MODE_EIO;
494
495 if (load_verity_table(dm, mount_point, verity.data_size, ¶ms,
496 format_legacy_verity_table) == 0) {
497 goto loaded;
498 }
499 }
500
501 LERROR << "Failed to load verity table for " << mount_point.c_str();
502 goto out;
503
504 loaded:
505 if (!dm.GetDmDevicePathByName(mount_point, &verity_blk_name)) {
506 LERROR << "Couldn't get verity device number!";
507 goto out;
508 }
509
510 // mark the underlying block device as read-only
511 fs_mgr_set_blk_ro(entry->blk_device);
512
513 // Verify the entire partition in one go
514 // If there is an error, allow it to mount as a normal verity partition.
515 if (entry->fs_mgr_flags.verify_at_boot) {
516 LINFO << "Verifying partition " << entry->blk_device << " at boot";
517 int err = read_partition(verity_blk_name.c_str(), verity.data_size);
518 if (!err) {
519 LINFO << "Verified verity partition " << entry->blk_device << " at boot";
520 verified_at_boot = true;
521 }
522 }
523
524 // assign the new verity block device as the block device
525 if (!verified_at_boot) {
526 entry->blk_device = verity_blk_name;
527 } else if (!dm.DeleteDevice(mount_point)) {
528 LERROR << "Failed to remove verity device " << mount_point.c_str();
529 goto out;
530 }
531
532 // make sure we've set everything up properly
533 if (wait_for_verity_dev && !WaitForFile(entry->blk_device, 1s)) {
534 goto out;
535 }
536
537 retval = FS_MGR_SETUP_VERITY_SUCCESS;
538
539 out:
540 if (fd != -1) {
541 close(fd);
542 }
543
544 fec_close(f);
545 free(params.table);
546
547 return retval;
548 }
549
fs_mgr_teardown_verity(FstabEntry * entry)550 bool fs_mgr_teardown_verity(FstabEntry* entry) {
551 const std::string mount_point(basename(entry->mount_point.c_str()));
552 if (!android::fs_mgr::UnmapDevice(mount_point)) {
553 return false;
554 }
555 LINFO << "Unmapped verity device " << mount_point;
556 return true;
557 }
558