fs_mgr_verity.c revision a88fb24ab43eec9710a0d4d15aedb6d4bc51a2ec
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <inttypes.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <unistd.h>
22#include <fcntl.h>
23#include <ctype.h>
24#include <sys/mount.h>
25#include <sys/stat.h>
26#include <errno.h>
27#include <sys/types.h>
28#include <sys/wait.h>
29#include <libgen.h>
30#include <time.h>
31
32#include <private/android_filesystem_config.h>
33#include <cutils/properties.h>
34#include <logwrap/logwrap.h>
35
36#include "mincrypt/rsa.h"
37#include "mincrypt/sha.h"
38#include "mincrypt/sha256.h"
39
40#include "ext4_sb.h"
41
42#include "fs_mgr_priv.h"
43#include "fs_mgr_priv_verity.h"
44
45#define FSTAB_PREFIX "/fstab."
46
47#define VERITY_METADATA_SIZE 32768
48#define VERITY_TABLE_RSA_KEY "/verity_key"
49
50#define VERITY_STATE_HEADER 0x83c0ae9d
51#define VERITY_STATE_VERSION 1
52
53#define VERITY_KMSG_RESTART "dm-verity device corrupted"
54#define VERITY_KMSG_BUFSIZE 1024
55
56struct verity_state {
57    uint32_t header;
58    uint32_t version;
59    uint32_t size;
60    int32_t mode;
61};
62
63extern struct fs_info info;
64
65static RSAPublicKey *load_key(char *path)
66{
67    FILE *f;
68    RSAPublicKey *key;
69
70    key = malloc(sizeof(RSAPublicKey));
71    if (!key) {
72        ERROR("Can't malloc key\n");
73        return NULL;
74    }
75
76    f = fopen(path, "r");
77    if (!f) {
78        ERROR("Can't open '%s'\n", path);
79        free(key);
80        return NULL;
81    }
82
83    if (!fread(key, sizeof(*key), 1, f)) {
84        ERROR("Could not read key!");
85        fclose(f);
86        free(key);
87        return NULL;
88    }
89
90    if (key->len != RSANUMWORDS) {
91        ERROR("Invalid key length %d\n", key->len);
92        fclose(f);
93        free(key);
94        return NULL;
95    }
96
97    fclose(f);
98    return key;
99}
100
101static int verify_table(char *signature, char *table, int table_length)
102{
103    RSAPublicKey *key;
104    uint8_t hash_buf[SHA_DIGEST_SIZE];
105    int retval = -1;
106
107    // Hash the table
108    SHA_hash((uint8_t*)table, table_length, hash_buf);
109
110    // Now get the public key from the keyfile
111    key = load_key(VERITY_TABLE_RSA_KEY);
112    if (!key) {
113        ERROR("Couldn't load verity keys");
114        goto out;
115    }
116
117    // verify the result
118    if (!RSA_verify(key,
119                    (uint8_t*) signature,
120                    RSANUMBYTES,
121                    (uint8_t*) hash_buf,
122                    SHA_DIGEST_SIZE)) {
123        ERROR("Couldn't verify table.");
124        goto out;
125    }
126
127    retval = 0;
128
129out:
130    free(key);
131    return retval;
132}
133
134static int get_target_device_size(char *blk_device, uint64_t *device_size)
135{
136    int data_device;
137    struct ext4_super_block sb;
138    struct fs_info info;
139
140    info.len = 0;  /* Only len is set to 0 to ask the device for real size. */
141
142    data_device = TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC));
143    if (data_device == -1) {
144        ERROR("Error opening block device (%s)", strerror(errno));
145        return -1;
146    }
147
148    if (TEMP_FAILURE_RETRY(lseek64(data_device, 1024, SEEK_SET)) < 0) {
149        ERROR("Error seeking to superblock");
150        TEMP_FAILURE_RETRY(close(data_device));
151        return -1;
152    }
153
154    if (TEMP_FAILURE_RETRY(read(data_device, &sb, sizeof(sb))) != sizeof(sb)) {
155        ERROR("Error reading superblock");
156        TEMP_FAILURE_RETRY(close(data_device));
157        return -1;
158    }
159
160    ext4_parse_sb(&sb, &info);
161    *device_size = info.len;
162
163    TEMP_FAILURE_RETRY(close(data_device));
164    return 0;
165}
166
167static int read_verity_metadata(char *block_device, char **signature, char **table)
168{
169    unsigned magic_number;
170    unsigned table_length;
171    uint64_t device_length;
172    int protocol_version;
173    int device;
174    int retval = FS_MGR_SETUP_VERITY_FAIL;
175    *signature = 0;
176    *table = 0;
177
178    device = TEMP_FAILURE_RETRY(open(block_device, O_RDONLY | O_CLOEXEC));
179    if (device == -1) {
180        ERROR("Could not open block device %s (%s).\n", block_device, strerror(errno));
181        goto out;
182    }
183
184    // find the start of the verity metadata
185    if (get_target_device_size(block_device, &device_length) < 0) {
186        ERROR("Could not get target device size.\n");
187        goto out;
188    }
189    if (TEMP_FAILURE_RETRY(lseek64(device, device_length, SEEK_SET)) < 0) {
190        ERROR("Could not seek to start of verity metadata block.\n");
191        goto out;
192    }
193
194    // check the magic number
195    if (TEMP_FAILURE_RETRY(read(device, &magic_number, sizeof(magic_number))) !=
196            sizeof(magic_number)) {
197        ERROR("Couldn't read magic number!\n");
198        goto out;
199    }
200
201#ifdef ALLOW_ADBD_DISABLE_VERITY
202    if (magic_number == VERITY_METADATA_MAGIC_DISABLE) {
203        retval = FS_MGR_SETUP_VERITY_DISABLED;
204        INFO("Attempt to cleanly disable verity - only works in USERDEBUG");
205        goto out;
206    }
207#endif
208
209    if (magic_number != VERITY_METADATA_MAGIC_NUMBER) {
210        ERROR("Couldn't find verity metadata at offset %"PRIu64"!\n",
211              device_length);
212        goto out;
213    }
214
215    // check the protocol version
216    if (TEMP_FAILURE_RETRY(read(device, &protocol_version,
217            sizeof(protocol_version))) != sizeof(protocol_version)) {
218        ERROR("Couldn't read verity metadata protocol version!\n");
219        goto out;
220    }
221    if (protocol_version != 0) {
222        ERROR("Got unknown verity metadata protocol version %d!\n", protocol_version);
223        goto out;
224    }
225
226    // get the signature
227    *signature = (char*) malloc(RSANUMBYTES);
228    if (!*signature) {
229        ERROR("Couldn't allocate memory for signature!\n");
230        goto out;
231    }
232    if (TEMP_FAILURE_RETRY(read(device, *signature, RSANUMBYTES)) != RSANUMBYTES) {
233        ERROR("Couldn't read signature from verity metadata!\n");
234        goto out;
235    }
236
237    // get the size of the table
238    if (TEMP_FAILURE_RETRY(read(device, &table_length, sizeof(table_length))) !=
239            sizeof(table_length)) {
240        ERROR("Couldn't get the size of the verity table from metadata!\n");
241        goto out;
242    }
243
244    // get the table + null terminator
245    *table = malloc(table_length + 1);
246    if (!*table) {
247        ERROR("Couldn't allocate memory for verity table!\n");
248        goto out;
249    }
250    if (TEMP_FAILURE_RETRY(read(device, *table, table_length)) !=
251            (ssize_t)table_length) {
252        ERROR("Couldn't read the verity table from metadata!\n");
253        goto out;
254    }
255
256    (*table)[table_length] = 0;
257    retval = FS_MGR_SETUP_VERITY_SUCCESS;
258
259out:
260    if (device != -1)
261        TEMP_FAILURE_RETRY(close(device));
262
263    if (retval != FS_MGR_SETUP_VERITY_SUCCESS) {
264        free(*table);
265        free(*signature);
266        *table = 0;
267        *signature = 0;
268    }
269
270    return retval;
271}
272
273static void verity_ioctl_init(struct dm_ioctl *io, char *name, unsigned flags)
274{
275    memset(io, 0, DM_BUF_SIZE);
276    io->data_size = DM_BUF_SIZE;
277    io->data_start = sizeof(struct dm_ioctl);
278    io->version[0] = 4;
279    io->version[1] = 0;
280    io->version[2] = 0;
281    io->flags = flags | DM_READONLY_FLAG;
282    if (name) {
283        strlcpy(io->name, name, sizeof(io->name));
284    }
285}
286
287static int create_verity_device(struct dm_ioctl *io, char *name, int fd)
288{
289    verity_ioctl_init(io, name, 1);
290    if (ioctl(fd, DM_DEV_CREATE, io)) {
291        ERROR("Error creating device mapping (%s)", strerror(errno));
292        return -1;
293    }
294    return 0;
295}
296
297static int get_verity_device_name(struct dm_ioctl *io, char *name, int fd, char **dev_name)
298{
299    verity_ioctl_init(io, name, 0);
300    if (ioctl(fd, DM_DEV_STATUS, io)) {
301        ERROR("Error fetching verity device number (%s)", strerror(errno));
302        return -1;
303    }
304    int dev_num = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00);
305    if (asprintf(dev_name, "/dev/block/dm-%u", dev_num) < 0) {
306        ERROR("Error getting verity block device name (%s)", strerror(errno));
307        return -1;
308    }
309    return 0;
310}
311
312static int load_verity_table(struct dm_ioctl *io, char *name, char *blockdev, int fd, char *table,
313        int mode)
314{
315    char *verity_params;
316    char *buffer = (char*) io;
317    size_t bufsize;
318    uint64_t device_size = 0;
319
320    if (get_target_device_size(blockdev, &device_size) < 0) {
321        return -1;
322    }
323
324    verity_ioctl_init(io, name, DM_STATUS_TABLE_FLAG);
325
326    struct dm_target_spec *tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)];
327
328    // set tgt arguments here
329    io->target_count = 1;
330    tgt->status=0;
331    tgt->sector_start=0;
332    tgt->length=device_size/512;
333    strcpy(tgt->target_type, "verity");
334
335    // build the verity params here
336    verity_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec);
337    bufsize = DM_BUF_SIZE - (verity_params - buffer);
338
339    if (mode == VERITY_MODE_EIO) {
340        // allow operation with older dm-verity drivers that are unaware
341        // of the mode parameter by omitting it; this also means that we
342        // cannot use logging mode with these drivers, they always cause
343        // an I/O error for corrupted blocks
344        strcpy(verity_params, table);
345    } else if (snprintf(verity_params, bufsize, "%s %d", table, mode) < 0) {
346        return -1;
347    }
348
349    // set next target boundary
350    verity_params += strlen(verity_params) + 1;
351    verity_params = (char*) (((unsigned long)verity_params + 7) & ~8);
352    tgt->next = verity_params - buffer;
353
354    // send the ioctl to load the verity table
355    if (ioctl(fd, DM_TABLE_LOAD, io)) {
356        ERROR("Error loading verity table (%s)", strerror(errno));
357        return -1;
358    }
359
360    return 0;
361}
362
363static int resume_verity_table(struct dm_ioctl *io, char *name, int fd)
364{
365    verity_ioctl_init(io, name, 0);
366    if (ioctl(fd, DM_DEV_SUSPEND, io)) {
367        ERROR("Error activating verity device (%s)", strerror(errno));
368        return -1;
369    }
370    return 0;
371}
372
373static int test_access(char *device) {
374    int tries = 25;
375    while (tries--) {
376        if (!access(device, F_OK) || errno != ENOENT) {
377            return 0;
378        }
379        usleep(40 * 1000);
380    }
381    return -1;
382}
383
384static int set_verified_property(char *name) {
385    int ret;
386    char *key;
387    ret = asprintf(&key, "partition.%s.verified", name);
388    if (ret < 0) {
389        ERROR("Error formatting verified property\n");
390        return ret;
391    }
392    ret = PROP_NAME_MAX - strlen(key);
393    if (ret < 0) {
394        ERROR("Verified property name is too long\n");
395        free(key);
396        return -1;
397    }
398    ret = property_set(key, "1");
399    if (ret < 0)
400        ERROR("Error setting verified property %s: %d\n", key, ret);
401    free(key);
402    return ret;
403}
404
405static int check_verity_restart(const char *fname)
406{
407    char buffer[VERITY_KMSG_BUFSIZE + 1];
408    int fd;
409    int rc = 0;
410    ssize_t size;
411    struct stat s;
412
413    fd = TEMP_FAILURE_RETRY(open(fname, O_RDONLY | O_CLOEXEC));
414
415    if (fd == -1) {
416        if (errno != ENOENT) {
417            ERROR("Failed to open %s (%s)\n", fname, strerror(errno));
418        }
419        goto out;
420    }
421
422    if (fstat(fd, &s) == -1) {
423        ERROR("Failed to fstat %s (%s)\n", fname, strerror(errno));
424        goto out;
425    }
426
427    size = VERITY_KMSG_BUFSIZE;
428
429    if (size > s.st_size) {
430        size = s.st_size;
431    }
432
433    if (lseek(fd, s.st_size - size, SEEK_SET) == -1) {
434        ERROR("Failed to lseek %zu %s (%s)\n", s.st_size - size, fname,
435            strerror(errno));
436        goto out;
437    }
438
439    if (TEMP_FAILURE_RETRY(read(fd, buffer, size)) != size) {
440        ERROR("Failed to read %zd bytes from %s (%s)\n", size, fname,
441            strerror(errno));
442        goto out;
443    }
444
445    buffer[size] = '\0';
446
447    if (strstr(buffer, VERITY_KMSG_RESTART) != NULL) {
448        rc = 1;
449    }
450
451out:
452    if (fd != -1) {
453        TEMP_FAILURE_RETRY(close(fd));
454    }
455
456    return rc;
457}
458
459static int was_verity_restart()
460{
461    static const char *files[] = {
462        "/sys/fs/pstore/console-ramoops",
463        "/proc/last_kmsg",
464        NULL
465    };
466    int i;
467
468    for (i = 0; files[i]; ++i) {
469        if (check_verity_restart(files[i])) {
470            return 1;
471        }
472    }
473
474    return 0;
475}
476
477static int write_verity_state(const char *fname, off64_t offset, int32_t mode)
478{
479    int fd;
480    int rc = -1;
481
482    struct verity_state s = {
483        VERITY_STATE_HEADER,
484        VERITY_STATE_VERSION,
485        sizeof(struct verity_state),
486        mode
487    };
488
489    fd = TEMP_FAILURE_RETRY(open(fname, O_WRONLY | O_SYNC | O_CLOEXEC));
490
491    if (fd == -1) {
492        ERROR("Failed to open %s (%s)\n", fname, strerror(errno));
493        goto out;
494    }
495
496    if (TEMP_FAILURE_RETRY(lseek64(fd, offset, SEEK_SET)) < 0) {
497        ERROR("Failed to seek %s to %" PRIu64 " (%s)\n", fname, offset, strerror(errno));
498        goto out;
499    }
500
501    if (TEMP_FAILURE_RETRY(write(fd, &s, sizeof(s))) != sizeof(s)) {
502        ERROR("Failed to write %zu bytes to %s (%s)\n", sizeof(s), fname, strerror(errno));
503        goto out;
504    }
505
506    rc = 0;
507
508out:
509    if (fd != -1) {
510        TEMP_FAILURE_RETRY(close(fd));
511    }
512
513    return rc;
514}
515
516static int get_verity_state_location(char *location, off64_t *offset)
517{
518    char state_off[PROPERTY_VALUE_MAX];
519
520    if (property_get("ro.verity.state.location", location, NULL) <= 0) {
521        return -1;
522    }
523
524    if (*location != '/' || access(location, R_OK | W_OK) == -1) {
525        ERROR("Failed to access verity state %s (%s)\n", location, strerror(errno));
526        return -1;
527    }
528
529    *offset = 0;
530
531    if (property_get("ro.verity.state.offset", state_off, NULL) > 0) {
532        *offset = strtoll(state_off, NULL, 0);
533
534        if (errno == ERANGE || errno == EINVAL) {
535            ERROR("Invalid value in ro.verity.state.offset (%s)\n", state_off);
536            return -1;
537        }
538    }
539
540    return 0;
541}
542
543int fs_mgr_load_verity_state(int *mode)
544{
545    char fname[PROPERTY_VALUE_MAX];
546    int fd = -1;
547    int rc = -1;
548    off64_t offset = 0;
549    struct verity_state s;
550
551    if (get_verity_state_location(fname, &offset) < 0) {
552        /* location for dm-verity state is not specified, fall back to
553         * default behavior: return -EIO for corrupted blocks */
554        *mode = VERITY_MODE_EIO;
555        rc = 0;
556        goto out;
557    }
558
559    if (was_verity_restart()) {
560        /* device was restarted after dm-verity detected a corrupted
561         * block, so switch to logging mode */
562        *mode = VERITY_MODE_LOGGING;
563        rc = write_verity_state(fname, offset, *mode);
564        goto out;
565    }
566
567    fd = TEMP_FAILURE_RETRY(open(fname, O_RDONLY | O_CLOEXEC));
568
569    if (fd == -1) {
570        ERROR("Failed to open %s (%s)\n", fname, strerror(errno));
571        goto out;
572    }
573
574    if (TEMP_FAILURE_RETRY(lseek64(fd, offset, SEEK_SET)) < 0) {
575        ERROR("Failed to seek %s to %" PRIu64 " (%s)\n", fname, offset, strerror(errno));
576        goto out;
577    }
578
579    if (TEMP_FAILURE_RETRY(read(fd, &s, sizeof(s))) != sizeof(s)) {
580        ERROR("Failed to read %zu bytes from %s (%s)\n", sizeof(s), fname, strerror(errno));
581        goto out;
582    }
583
584    if (s.header != VERITY_STATE_HEADER) {
585        goto out;
586    }
587
588    if (s.version != VERITY_STATE_VERSION) {
589        ERROR("Unsupported verity state version (%u)\n", s.version);
590        goto out;
591    }
592
593    if (s.size != sizeof(s)) {
594        ERROR("Unexpected verity state size (%u)\n", s.size);
595        goto out;
596    }
597
598    if (s.mode < VERITY_MODE_EIO ||
599        s.mode > VERITY_MODE_LAST) {
600        ERROR("Unsupported verity mode (%u)\n", s.mode);
601        goto out;
602    }
603
604    *mode = s.mode;
605    rc = 0;
606
607out:
608    if (fd != -1) {
609        TEMP_FAILURE_RETRY(close(fd));
610    }
611
612    return rc;
613}
614
615int fs_mgr_update_verity_state()
616{
617    _Alignas(struct dm_ioctl) char buffer[DM_BUF_SIZE];
618    char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
619    char *mount_point;
620    char propbuf[PROPERTY_VALUE_MAX];
621    char state_loc[PROPERTY_VALUE_MAX];
622    char *status;
623    int fd = -1;
624    int i;
625    int rc = -1;
626    off64_t offset = 0;
627    struct dm_ioctl *io = (struct dm_ioctl *) buffer;
628    struct fstab *fstab = NULL;
629
630    if (get_verity_state_location(state_loc, &offset) < 0) {
631        goto out;
632    }
633
634    fd = TEMP_FAILURE_RETRY(open("/dev/device-mapper", O_RDWR | O_CLOEXEC));
635
636    if (fd == -1) {
637        ERROR("Error opening device mapper (%s)\n", strerror(errno));
638        goto out;
639    }
640
641    property_get("ro.hardware", propbuf, "");
642    snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
643
644    fstab = fs_mgr_read_fstab(fstab_filename);
645
646    if (!fstab) {
647        ERROR("Failed to read %s\n", fstab_filename);
648        goto out;
649    }
650
651    for (i = 0; i < fstab->num_entries; i++) {
652        if (!fs_mgr_is_verified(&fstab->recs[i])) {
653            continue;
654        }
655
656        mount_point = basename(fstab->recs[i].mount_point);
657        verity_ioctl_init(io, mount_point, 0);
658
659        if (ioctl(fd, DM_TABLE_STATUS, io)) {
660            ERROR("Failed to query DM_TABLE_STATUS for %s (%s)\n", mount_point,
661                strerror(errno));
662            goto out;
663        }
664
665        status = &buffer[io->data_start + sizeof(struct dm_target_spec)];
666
667        if (*status == 'C') {
668            rc = write_verity_state(state_loc, offset, VERITY_MODE_LOGGING);
669            goto out;
670        }
671    }
672
673    /* Don't overwrite possible previous state if there's no corruption. */
674    rc = 0;
675
676out:
677    if (fstab) {
678        fs_mgr_free_fstab(fstab);
679    }
680
681    if (fd) {
682        TEMP_FAILURE_RETRY(close(fd));
683    }
684
685    return rc;
686}
687
688int fs_mgr_setup_verity(struct fstab_rec *fstab) {
689
690    int retval = FS_MGR_SETUP_VERITY_FAIL;
691    int fd = -1;
692    int mode;
693
694    char *verity_blk_name = 0;
695    char *verity_table = 0;
696    char *verity_table_signature = 0;
697
698    _Alignas(struct dm_ioctl) char buffer[DM_BUF_SIZE];
699    struct dm_ioctl *io = (struct dm_ioctl *) buffer;
700    char *mount_point = basename(fstab->mount_point);
701
702    // set the dm_ioctl flags
703    io->flags |= 1;
704    io->target_count = 1;
705
706    // check to ensure that the verity device is ext4
707    // TODO: support non-ext4 filesystems
708    if (strcmp(fstab->fs_type, "ext4")) {
709        ERROR("Cannot verify non-ext4 device (%s)", fstab->fs_type);
710        return retval;
711    }
712
713    // read the verity block at the end of the block device
714    // send error code up the chain so we can detect attempts to disable verity
715    retval = read_verity_metadata(fstab->blk_device,
716                                  &verity_table_signature,
717                                  &verity_table);
718    if (retval < 0) {
719        goto out;
720    }
721
722    retval = FS_MGR_SETUP_VERITY_FAIL;
723
724    // get the device mapper fd
725    if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
726        ERROR("Error opening device mapper (%s)", strerror(errno));
727        goto out;
728    }
729
730    // create the device
731    if (create_verity_device(io, mount_point, fd) < 0) {
732        ERROR("Couldn't create verity device!");
733        goto out;
734    }
735
736    // get the name of the device file
737    if (get_verity_device_name(io, mount_point, fd, &verity_blk_name) < 0) {
738        ERROR("Couldn't get verity device number!");
739        goto out;
740    }
741
742    // verify the signature on the table
743    if (verify_table(verity_table_signature,
744                            verity_table,
745                            strlen(verity_table)) < 0) {
746        goto out;
747    }
748
749    if (fs_mgr_load_verity_state(&mode) < 0) {
750        mode = VERITY_MODE_RESTART; /* default dm-verity mode */
751    }
752
753    // load the verity mapping table
754    if (load_verity_table(io, mount_point, fstab->blk_device, fd, verity_table,
755            mode) < 0) {
756        goto out;
757    }
758
759    // activate the device
760    if (resume_verity_table(io, mount_point, fd) < 0) {
761        goto out;
762    }
763
764    // mark the underlying block device as read-only
765    fs_mgr_set_blk_ro(fstab->blk_device);
766
767    // assign the new verity block device as the block device
768    free(fstab->blk_device);
769    fstab->blk_device = verity_blk_name;
770    verity_blk_name = 0;
771
772    // make sure we've set everything up properly
773    if (test_access(fstab->blk_device) < 0) {
774        goto out;
775    }
776
777    if (mode == VERITY_MODE_LOGGING) {
778        retval = FS_MGR_SETUP_VERITY_SUCCESS;
779    } else {
780        // set the property indicating that the partition is verified
781        retval = set_verified_property(mount_point);
782    }
783
784out:
785    if (fd != -1) {
786        close(fd);
787    }
788
789    free(verity_table);
790    free(verity_table_signature);
791    free(verity_blk_name);
792
793    return retval;
794}
795