fs_mgr_avb.cpp revision 72ffff70fcd540a38b0a344386d10315c3b560c1
1/*
2 * Copyright (C) 2016 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 <errno.h>
18#include <fcntl.h>
19#include <inttypes.h>
20#include <libgen.h>
21#include <stdio.h>
22#include <string.h>
23#include <sys/stat.h>
24#include <sys/types.h>
25#include <unistd.h>
26#include <vector>
27
28#include <android-base/file.h>
29#include <android-base/parseint.h>
30#include <android-base/properties.h>
31#include <android-base/strings.h>
32#include <android-base/unique_fd.h>
33#include <cutils/properties.h>
34#include <libavb/libavb.h>
35#include <openssl/sha.h>
36#include <sys/ioctl.h>
37#include <utils/Compat.h>
38
39#include "fs_mgr.h"
40#include "fs_mgr_avb_ops.h"
41#include "fs_mgr_priv.h"
42#include "fs_mgr_priv_avb.h"
43#include "fs_mgr_priv_dm_ioctl.h"
44#include "fs_mgr_priv_sha.h"
45
46/* The format of dm-verity construction parameters:
47 *     <version> <dev> <hash_dev> <data_block_size> <hash_block_size>
48 *     <num_data_blocks> <hash_start_block> <algorithm> <digest> <salt>
49 */
50#define VERITY_TABLE_FORMAT \
51    "%u %s %s %u %u "       \
52    "%" PRIu64 " %" PRIu64 " %s %s %s "
53
54#define VERITY_TABLE_PARAMS(hashtree_desc, blk_device, digest, salt)  \
55    hashtree_desc.dm_verity_version, blk_device, blk_device,          \
56        hashtree_desc.data_block_size, hashtree_desc.hash_block_size, \
57        hashtree_desc.image_size /                                    \
58            hashtree_desc.data_block_size, /* num_data_blocks. */     \
59        hashtree_desc.tree_offset /                                   \
60            hashtree_desc.hash_block_size, /* hash_start_block. */    \
61        (char *)hashtree_desc.hash_algorithm, digest, salt
62
63#define VERITY_TABLE_OPT_RESTART "restart_on_corruption"
64#define VERITY_TABLE_OPT_IGNZERO "ignore_zero_blocks"
65
66/* The default format of dm-verity optional parameters:
67 *     <#opt_params> ignore_zero_blocks restart_on_corruption
68 */
69#define VERITY_TABLE_OPT_DEFAULT_FORMAT "2 %s %s"
70#define VERITY_TABLE_OPT_DEFAULT_PARAMS \
71    VERITY_TABLE_OPT_IGNZERO, VERITY_TABLE_OPT_RESTART
72
73/* The FEC (forward error correction) format of dm-verity optional parameters:
74 *     <#opt_params> use_fec_from_device <fec_dev>
75 *     fec_roots <num> fec_blocks <num> fec_start <offset>
76 *     ignore_zero_blocks restart_on_corruption
77 */
78#define VERITY_TABLE_OPT_FEC_FORMAT                              \
79    "10 use_fec_from_device %s fec_roots %u fec_blocks %" PRIu64 \
80    " fec_start %" PRIu64 " %s %s"
81
82/* Note that fec_blocks is the size that FEC covers, *not* the
83 * size of the FEC data. Since we use FEC for everything up until
84 * the FEC data, it's the same as the offset (fec_start).
85 */
86#define VERITY_TABLE_OPT_FEC_PARAMS(hashtree_desc, blk_device) \
87    blk_device, hashtree_desc.fec_num_roots,                   \
88        hashtree_desc.fec_offset /                             \
89            hashtree_desc.data_block_size, /* fec_blocks */    \
90        hashtree_desc.fec_offset /                             \
91            hashtree_desc.data_block_size, /* fec_start */     \
92        VERITY_TABLE_OPT_IGNZERO, VERITY_TABLE_OPT_RESTART
93
94AvbSlotVerifyData *fs_mgr_avb_verify_data = nullptr;
95AvbOps *fs_mgr_avb_ops = nullptr;
96
97enum HashAlgorithm {
98    kInvalid = 0,
99    kSHA256 = 1,
100    kSHA512 = 2,
101};
102
103struct androidboot_vbmeta {
104    HashAlgorithm hash_alg;
105    uint8_t digest[SHA512_DIGEST_LENGTH];
106    size_t vbmeta_size;
107    bool allow_verification_error;
108};
109
110androidboot_vbmeta fs_mgr_vbmeta_prop;
111
112static inline bool nibble_value(const char &c, uint8_t *value)
113{
114    FS_MGR_CHECK(value != nullptr);
115
116    switch (c) {
117        case '0' ... '9':
118            *value = c - '0';
119            break;
120        case 'a' ... 'f':
121            *value = c - 'a' + 10;
122            break;
123        case 'A' ... 'F':
124            *value = c - 'A' + 10;
125            break;
126        default:
127            return false;
128    }
129
130    return true;
131}
132
133static bool hex_to_bytes(uint8_t *bytes,
134                         size_t bytes_len,
135                         const std::string &hex)
136{
137    FS_MGR_CHECK(bytes != nullptr);
138
139    if (hex.size() % 2 != 0) {
140        return false;
141    }
142    if (hex.size() / 2 > bytes_len) {
143        return false;
144    }
145    for (size_t i = 0, j = 0, n = hex.size(); i < n; i += 2, ++j) {
146        uint8_t high;
147        if (!nibble_value(hex[i], &high)) {
148            return false;
149        }
150        uint8_t low;
151        if (!nibble_value(hex[i + 1], &low)) {
152            return false;
153        }
154        bytes[j] = (high << 4) | low;
155    }
156    return true;
157}
158
159static std::string bytes_to_hex(const uint8_t *bytes, size_t bytes_len)
160{
161    FS_MGR_CHECK(bytes != nullptr);
162
163    static const char *hex_digits = "0123456789abcdef";
164    std::string hex;
165
166    for (size_t i = 0; i < bytes_len; i++) {
167        hex.push_back(hex_digits[(bytes[i] & 0xF0) >> 4]);
168        hex.push_back(hex_digits[bytes[i] & 0x0F]);
169    }
170    return hex;
171}
172
173static bool load_vbmeta_prop(androidboot_vbmeta *vbmeta_prop)
174{
175    FS_MGR_CHECK(vbmeta_prop != nullptr);
176
177    std::string cmdline;
178    android::base::ReadFileToString("/proc/cmdline", &cmdline);
179
180    std::string hash_alg;
181    std::string digest;
182
183    for (const auto &entry :
184         android::base::Split(android::base::Trim(cmdline), " ")) {
185        std::vector<std::string> pieces = android::base::Split(entry, "=");
186        const std::string &key = pieces[0];
187        const std::string &value = pieces[1];
188
189        if (key == "androidboot.vbmeta.device_state") {
190            vbmeta_prop->allow_verification_error = (value == "unlocked");
191        } else if (key == "androidboot.vbmeta.hash_alg") {
192            hash_alg = value;
193        } else if (key == "androidboot.vbmeta.size") {
194            if (!android::base::ParseUint(value.c_str(),
195                                          &vbmeta_prop->vbmeta_size)) {
196                return false;
197            }
198        } else if (key == "androidboot.vbmeta.digest") {
199            digest = value;
200        }
201    }
202
203    // Reads hash algorithm.
204    size_t expected_digest_size = 0;
205    if (hash_alg == "sha256") {
206        expected_digest_size = SHA256_DIGEST_LENGTH * 2;
207        vbmeta_prop->hash_alg = kSHA256;
208    } else if (hash_alg == "sha512") {
209        expected_digest_size = SHA512_DIGEST_LENGTH * 2;
210        vbmeta_prop->hash_alg = kSHA512;
211    } else {
212        LERROR << "Unknown hash algorithm: " << hash_alg.c_str();
213        return false;
214    }
215
216    // Reads digest.
217    if (digest.size() != expected_digest_size) {
218        LERROR << "Unexpected digest size: " << digest.size()
219               << " (expected: " << expected_digest_size << ")";
220        return false;
221    }
222
223    if (!hex_to_bytes(vbmeta_prop->digest, sizeof(vbmeta_prop->digest),
224                      digest)) {
225        LERROR << "Hash digest contains non-hexidecimal character: "
226               << digest.c_str();
227        return false;
228    }
229
230    return true;
231}
232
233template <typename Hasher>
234static std::pair<size_t, bool> verify_vbmeta_digest(
235    const AvbSlotVerifyData &verify_data, const androidboot_vbmeta &vbmeta_prop)
236{
237    size_t total_size = 0;
238    Hasher hasher;
239    for (size_t n = 0; n < verify_data.num_vbmeta_images; n++) {
240        hasher.update(verify_data.vbmeta_images[n].vbmeta_data,
241                      verify_data.vbmeta_images[n].vbmeta_size);
242        total_size += verify_data.vbmeta_images[n].vbmeta_size;
243    }
244
245    bool matched = (memcmp(hasher.finalize(), vbmeta_prop.digest,
246                           Hasher::DIGEST_SIZE) == 0);
247
248    return std::make_pair(total_size, matched);
249}
250
251static bool verify_vbmeta_images(const AvbSlotVerifyData &verify_data,
252                                 const androidboot_vbmeta &vbmeta_prop)
253{
254    if (verify_data.num_vbmeta_images == 0) {
255        LERROR << "No vbmeta images";
256        return false;
257    }
258
259    size_t total_size = 0;
260    bool digest_matched = false;
261
262    if (vbmeta_prop.hash_alg == kSHA256) {
263        std::tie(total_size, digest_matched) =
264            verify_vbmeta_digest<SHA256Hasher>(verify_data, vbmeta_prop);
265    } else if (vbmeta_prop.hash_alg == kSHA512) {
266        std::tie(total_size, digest_matched) =
267            verify_vbmeta_digest<SHA512Hasher>(verify_data, vbmeta_prop);
268    }
269
270    if (total_size != vbmeta_prop.vbmeta_size) {
271        LERROR << "total vbmeta size mismatch: " << total_size
272               << " (expected: " << vbmeta_prop.vbmeta_size << ")";
273        return false;
274    }
275
276    if (!digest_matched) {
277        LERROR << "vbmeta digest mismatch";
278        return false;
279    }
280
281    return true;
282}
283
284static bool hashtree_load_verity_table(
285    struct dm_ioctl *io,
286    const std::string &dm_device_name,
287    int fd,
288    const std::string &blk_device,
289    const AvbHashtreeDescriptor &hashtree_desc,
290    const std::string &salt,
291    const std::string &root_digest)
292{
293    fs_mgr_verity_ioctl_init(io, dm_device_name, DM_STATUS_TABLE_FLAG);
294
295    // The buffer consists of [dm_ioctl][dm_target_spec][verity_params].
296    char *buffer = (char *)io;
297
298    // Builds the dm_target_spec arguments.
299    struct dm_target_spec *dm_target =
300        (struct dm_target_spec *)&buffer[sizeof(struct dm_ioctl)];
301    io->target_count = 1;
302    dm_target->status = 0;
303    dm_target->sector_start = 0;
304    dm_target->length = hashtree_desc.image_size / 512;
305    strcpy(dm_target->target_type, "verity");
306
307    // Builds the verity params.
308    char *verity_params =
309        buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec);
310    size_t bufsize = DM_BUF_SIZE - (verity_params - buffer);
311
312    int res = 0;
313    if (hashtree_desc.fec_size > 0) {
314        res = snprintf(
315            verity_params, bufsize,
316            VERITY_TABLE_FORMAT VERITY_TABLE_OPT_FEC_FORMAT,
317            VERITY_TABLE_PARAMS(hashtree_desc, blk_device.c_str(),
318                                root_digest.c_str(), salt.c_str()),
319            VERITY_TABLE_OPT_FEC_PARAMS(hashtree_desc, blk_device.c_str()));
320    } else {
321        res = snprintf(verity_params, bufsize,
322                       VERITY_TABLE_FORMAT VERITY_TABLE_OPT_DEFAULT_FORMAT,
323                       VERITY_TABLE_PARAMS(hashtree_desc, blk_device.c_str(),
324                                           root_digest.c_str(), salt.c_str()),
325                       VERITY_TABLE_OPT_DEFAULT_PARAMS);
326    }
327
328    if (res < 0 || (size_t)res >= bufsize) {
329        LERROR << "Error building verity table; insufficient buffer size?";
330        return false;
331    }
332
333    LINFO << "Loading verity table: '" << verity_params << "'";
334
335    // Sets ext target boundary.
336    verity_params += strlen(verity_params) + 1;
337    verity_params = (char *)(((unsigned long)verity_params + 7) & ~7);
338    dm_target->next = verity_params - buffer;
339
340    // Sends the ioctl to load the verity table.
341    if (ioctl(fd, DM_TABLE_LOAD, io)) {
342        PERROR << "Error loading verity table";
343        return false;
344    }
345
346    return true;
347}
348
349static bool hashtree_dm_verity_setup(struct fstab_rec *fstab_entry,
350                                     const AvbHashtreeDescriptor &hashtree_desc,
351                                     const std::string &salt,
352                                     const std::string &root_digest)
353{
354    // Gets the device mapper fd.
355    android::base::unique_fd fd(open("/dev/device-mapper", O_RDWR));
356    if (fd < 0) {
357        PERROR << "Error opening device mapper";
358        return false;
359    }
360
361    // Creates the device.
362    alignas(dm_ioctl) char buffer[DM_BUF_SIZE];
363    struct dm_ioctl *io = (struct dm_ioctl *)buffer;
364    const std::string mount_point(basename(fstab_entry->mount_point));
365    if (!fs_mgr_create_verity_device(io, mount_point, fd)) {
366        LERROR << "Couldn't create verity device!";
367        return false;
368    }
369
370    // Gets the name of the device file.
371    std::string verity_blk_name;
372    if (!fs_mgr_get_verity_device_name(io, mount_point, fd, &verity_blk_name)) {
373        LERROR << "Couldn't get verity device number!";
374        return false;
375    }
376
377    // Loads the verity mapping table.
378    if (!hashtree_load_verity_table(io, mount_point, fd,
379                                    std::string(fstab_entry->blk_device),
380                                    hashtree_desc, salt, root_digest)) {
381        LERROR << "Couldn't load verity table!";
382        return false;
383    }
384
385    // Activates the device.
386    if (!fs_mgr_resume_verity_table(io, mount_point, fd)) {
387        return false;
388    }
389
390    // Marks the underlying block device as read-only.
391    fs_mgr_set_blk_ro(fstab_entry->blk_device);
392
393    // TODO(bowgotsai): support verified all partition at boot.
394    // Updates fstab_rec->blk_device to verity device name.
395    free(fstab_entry->blk_device);
396    fstab_entry->blk_device = strdup(verity_blk_name.c_str());
397
398    // Makes sure we've set everything up properly.
399    if (fs_mgr_test_access(verity_blk_name.c_str()) < 0) {
400        return false;
401    }
402
403    return true;
404}
405
406static bool get_hashtree_descriptor(const std::string &partition_name,
407                                    const AvbSlotVerifyData &verify_data,
408                                    AvbHashtreeDescriptor *out_hashtree_desc,
409                                    std::string *out_salt,
410                                    std::string *out_digest)
411{
412    bool found = false;
413    const uint8_t *desc_partition_name;
414
415    for (size_t i = 0; i < verify_data.num_vbmeta_images && !found; i++) {
416        // Get descriptors from vbmeta_images[i].
417        size_t num_descriptors;
418        std::unique_ptr<const AvbDescriptor *[], decltype(&avb_free)>
419            descriptors(
420                avb_descriptor_get_all(verify_data.vbmeta_images[i].vbmeta_data,
421                                       verify_data.vbmeta_images[i].vbmeta_size,
422                                       &num_descriptors),
423                avb_free);
424
425        if (!descriptors || num_descriptors < 1) {
426            continue;
427        }
428
429        // Ensures that hashtree descriptor is either in /vbmeta or in
430        // the same partition for verity setup.
431        std::string vbmeta_partition_name(
432            verify_data.vbmeta_images[i].partition_name);
433        if (vbmeta_partition_name != "vbmeta" &&
434            vbmeta_partition_name != partition_name) {
435            LWARNING << "Skip vbmeta image at "
436                     << verify_data.vbmeta_images[i].partition_name
437                     << " for partition: " << partition_name.c_str();
438            continue;
439        }
440
441        for (size_t j = 0; j < num_descriptors && !found; j++) {
442            AvbDescriptor desc;
443            if (!avb_descriptor_validate_and_byteswap(descriptors[j], &desc)) {
444                LWARNING << "Descriptor[" << j << "] is invalid";
445                continue;
446            }
447            if (desc.tag == AVB_DESCRIPTOR_TAG_HASHTREE) {
448                desc_partition_name = (const uint8_t *)descriptors[j] +
449                                      sizeof(AvbHashtreeDescriptor);
450                if (!avb_hashtree_descriptor_validate_and_byteswap(
451                        (AvbHashtreeDescriptor *)descriptors[j],
452                        out_hashtree_desc)) {
453                    continue;
454                }
455                if (out_hashtree_desc->partition_name_len !=
456                    partition_name.length()) {
457                    continue;
458                }
459                // Notes that desc_partition_name is not NUL-terminated.
460                std::string hashtree_partition_name(
461                    (const char *)desc_partition_name,
462                    out_hashtree_desc->partition_name_len);
463                if (hashtree_partition_name == partition_name) {
464                    found = true;
465                }
466            }
467        }
468    }
469
470    if (!found) {
471        LERROR << "Partition descriptor not found: " << partition_name.c_str();
472        return false;
473    }
474
475    const uint8_t *desc_salt =
476        desc_partition_name + out_hashtree_desc->partition_name_len;
477    *out_salt = bytes_to_hex(desc_salt, out_hashtree_desc->salt_len);
478
479    const uint8_t *desc_digest = desc_salt + out_hashtree_desc->salt_len;
480    *out_digest = bytes_to_hex(desc_digest, out_hashtree_desc->root_digest_len);
481
482    return true;
483}
484
485static bool init_is_avb_used()
486{
487    // When AVB is used, boot loader should set androidboot.vbmeta.{hash_alg,
488    // size, digest} in kernel cmdline. They will then be imported by init
489    // process to system properties: ro.boot.vbmeta.{hash_alg, size, digest}.
490    //
491    // Checks hash_alg as an indicator for whether AVB is used.
492    // We don't have to parse and check all of them here. The check will
493    // be done in fs_mgr_load_vbmeta_images() and FS_MGR_SETUP_AVB_FAIL will
494    // be returned when there is an error.
495
496    std::string hash_alg =
497        android::base::GetProperty("ro.boot.vbmeta.hash_alg", "");
498
499    if (hash_alg == "sha256" || hash_alg == "sha512") {
500        return true;
501    }
502
503    return false;
504}
505
506bool fs_mgr_is_avb_used()
507{
508    static bool result = init_is_avb_used();
509    return result;
510}
511
512int fs_mgr_load_vbmeta_images(struct fstab *fstab)
513{
514    FS_MGR_CHECK(fstab != nullptr);
515
516    // Gets the expected hash value of vbmeta images from
517    // kernel cmdline.
518    if (!load_vbmeta_prop(&fs_mgr_vbmeta_prop)) {
519        return FS_MGR_SETUP_AVB_FAIL;
520    }
521
522    fs_mgr_avb_ops = fs_mgr_dummy_avb_ops_new(fstab);
523    if (fs_mgr_avb_ops == nullptr) {
524        LERROR << "Failed to allocate dummy avb_ops";
525        return FS_MGR_SETUP_AVB_FAIL;
526    }
527
528    // Invokes avb_slot_verify() to load and verify all vbmeta images.
529    // Sets requested_partitions to nullptr as it's to copy the contents
530    // of HASH partitions into fs_mgr_avb_verify_data, which is not required as
531    // fs_mgr only deals with HASHTREE partitions.
532    const char *requested_partitions[] = {nullptr};
533    const char *ab_suffix =
534        android::base::GetProperty("ro.boot.slot_suffix", "").c_str();
535    AvbSlotVerifyResult verify_result = avb_slot_verify(
536        fs_mgr_avb_ops, requested_partitions, ab_suffix,
537        fs_mgr_vbmeta_prop.allow_verification_error, &fs_mgr_avb_verify_data);
538
539    // Only allow two verify results:
540    //   - AVB_SLOT_VERIFY_RESULT_OK.
541    //   - AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION (for UNLOCKED state).
542    if (verify_result == AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION) {
543        if (!fs_mgr_vbmeta_prop.allow_verification_error) {
544            LERROR << "ERROR_VERIFICATION isn't allowed";
545            goto fail;
546        }
547    } else if (verify_result != AVB_SLOT_VERIFY_RESULT_OK) {
548        LERROR << "avb_slot_verify failed, result: " << verify_result;
549        goto fail;
550    }
551
552    // Verifies vbmeta images against the digest passed from bootloader.
553    if (!verify_vbmeta_images(*fs_mgr_avb_verify_data, fs_mgr_vbmeta_prop)) {
554        LERROR << "verify_vbmeta_images failed";
555        goto fail;
556    } else {
557        // Checks whether FLAGS_HASHTREE_DISABLED is set.
558        AvbVBMetaImageHeader vbmeta_header;
559        avb_vbmeta_image_header_to_host_byte_order(
560            (AvbVBMetaImageHeader *)fs_mgr_avb_verify_data->vbmeta_images[0]
561                .vbmeta_data,
562            &vbmeta_header);
563
564        bool hashtree_disabled = ((AvbVBMetaImageFlags)vbmeta_header.flags &
565                                  AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
566        if (hashtree_disabled) {
567            return FS_MGR_SETUP_AVB_HASHTREE_DISABLED;
568        }
569    }
570
571    if (verify_result == AVB_SLOT_VERIFY_RESULT_OK) {
572        return FS_MGR_SETUP_AVB_SUCCESS;
573    }
574
575fail:
576    fs_mgr_unload_vbmeta_images();
577    return FS_MGR_SETUP_AVB_FAIL;
578}
579
580void fs_mgr_unload_vbmeta_images()
581{
582    if (fs_mgr_avb_verify_data != nullptr) {
583        avb_slot_verify_data_free(fs_mgr_avb_verify_data);
584    }
585
586    if (fs_mgr_avb_ops != nullptr) {
587        fs_mgr_dummy_avb_ops_free(fs_mgr_avb_ops);
588    }
589}
590
591int fs_mgr_setup_avb(struct fstab_rec *fstab_entry)
592{
593    if (!fstab_entry || !fs_mgr_avb_verify_data ||
594        fs_mgr_avb_verify_data->num_vbmeta_images < 1) {
595        return FS_MGR_SETUP_AVB_FAIL;
596    }
597
598    std::string partition_name(basename(fstab_entry->mount_point));
599    if (!avb_validate_utf8((const uint8_t *)partition_name.c_str(),
600                           partition_name.length())) {
601        LERROR << "Partition name: " << partition_name.c_str()
602               << " is not valid UTF-8.";
603        return FS_MGR_SETUP_AVB_FAIL;
604    }
605
606    AvbHashtreeDescriptor hashtree_descriptor;
607    std::string salt;
608    std::string root_digest;
609    if (!get_hashtree_descriptor(partition_name, *fs_mgr_avb_verify_data,
610                                 &hashtree_descriptor, &salt, &root_digest)) {
611        return FS_MGR_SETUP_AVB_FAIL;
612    }
613
614    // Converts HASHTREE descriptor to verity_table_params.
615    if (!hashtree_dm_verity_setup(fstab_entry, hashtree_descriptor, salt,
616                                  root_digest)) {
617        return FS_MGR_SETUP_AVB_FAIL;
618    }
619
620    return FS_MGR_SETUP_AVB_SUCCESS;
621}
622