From 3de625d109f47e04bf7bf9d0db3cfc9f2718964d Mon Sep 17 00:00:00 2001 From: bowgotsai Date: Fri, 11 Nov 2016 21:05:44 +0800 Subject: [PATCH] fs_mgr: moves common functions out of fs_mgr_verity.cpp This commits moves some common functions out of fs_mgr_verity.cpp to be reused by other verified boot flows. It includes: - Move common functions into fs_mgr.c - Move dm_ioctl related functions to a new file: fs_mgr_dm_ioctl.cpp Bug: 31264231 Test: check device can boot with dm-verity Change-Id: Iaa0d8031efbaae12aa28f872f62d3fc3d3763b51 --- fs_mgr/Android.mk | 1 + fs_mgr/fs_mgr.c | 11 +++++ fs_mgr/fs_mgr_dm_ioctl.cpp | 82 +++++++++++++++++++++++++++++++++ fs_mgr/fs_mgr_priv.h | 1 + fs_mgr/fs_mgr_priv_dm_ioctl.h | 32 +++++++++++++ fs_mgr/fs_mgr_verity.cpp | 85 ++++------------------------------- 6 files changed, 135 insertions(+), 77 deletions(-) create mode 100644 fs_mgr/fs_mgr_dm_ioctl.cpp create mode 100644 fs_mgr/fs_mgr_priv_dm_ioctl.h diff --git a/fs_mgr/Android.mk b/fs_mgr/Android.mk index 9e06bc520..051acfa89 100644 --- a/fs_mgr/Android.mk +++ b/fs_mgr/Android.mk @@ -18,6 +18,7 @@ LOCAL_CLANG := true LOCAL_SANITIZE := integer LOCAL_SRC_FILES:= \ fs_mgr.c \ + fs_mgr_dm_ioctl.cpp \ fs_mgr_format.c \ fs_mgr_fstab.c \ fs_mgr_slotselect.c \ diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c index 7fac2fb42..9a53d6202 100644 --- a/fs_mgr/fs_mgr.c +++ b/fs_mgr/fs_mgr.c @@ -646,6 +646,17 @@ static int handle_encryptable(const struct fstab_rec* rec) } } +int fs_mgr_test_access(const char *device) { + int tries = 25; + while (tries--) { + if (!access(device, F_OK) || errno != ENOENT) { + return 0; + } + usleep(40 * 1000); + } + return -1; +} + /* When multiple fstab records share the same mount_point, it will * try to mount each one in turn, and ignore any duplicates after a * first successful mount. diff --git a/fs_mgr/fs_mgr_dm_ioctl.cpp b/fs_mgr/fs_mgr_dm_ioctl.cpp new file mode 100644 index 000000000..489415ad7 --- /dev/null +++ b/fs_mgr/fs_mgr_dm_ioctl.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "fs_mgr_priv.h" +#include "fs_mgr_priv_dm_ioctl.h" + +void fs_mgr_verity_ioctl_init(struct dm_ioctl *io, const char *name, unsigned flags) +{ + memset(io, 0, DM_BUF_SIZE); + io->data_size = DM_BUF_SIZE; + io->data_start = sizeof(struct dm_ioctl); + io->version[0] = 4; + io->version[1] = 0; + io->version[2] = 0; + io->flags = flags | DM_READONLY_FLAG; + if (name) { + strlcpy(io->name, name, sizeof(io->name)); + } +} + +int fs_mgr_create_verity_device(struct dm_ioctl *io, char *name, int fd) +{ + fs_mgr_verity_ioctl_init(io, name, 1); + if (ioctl(fd, DM_DEV_CREATE, io)) { + ERROR("Error creating device mapping (%s)", strerror(errno)); + return -1; + } + return 0; +} + +int fs_mgr_destroy_verity_device(struct dm_ioctl *io, char *name, int fd) +{ + fs_mgr_verity_ioctl_init(io, name, 0); + if (ioctl(fd, DM_DEV_REMOVE, io)) { + ERROR("Error removing device mapping (%s)", strerror(errno)); + return -1; + } + return 0; +} + +int fs_mgr_get_verity_device_name(struct dm_ioctl *io, char *name, int fd, char **dev_name) +{ + fs_mgr_verity_ioctl_init(io, name, 0); + if (ioctl(fd, DM_DEV_STATUS, io)) { + ERROR("Error fetching verity device number (%s)", strerror(errno)); + return -1; + } + int dev_num = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00); + if (asprintf(dev_name, "/dev/block/dm-%u", dev_num) < 0) { + ERROR("Error getting verity block device name (%s)", strerror(errno)); + return -1; + } + return 0; +} + +int fs_mgr_resume_verity_table(struct dm_ioctl *io, char *name, int fd) +{ + fs_mgr_verity_ioctl_init(io, name, 0); + if (ioctl(fd, DM_DEV_SUSPEND, io)) { + ERROR("Error activating verity device (%s)", strerror(errno)); + return -1; + } + return 0; +} + diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h index db86afa85..7f917d9e6 100644 --- a/fs_mgr/fs_mgr_priv.h +++ b/fs_mgr/fs_mgr_priv.h @@ -93,6 +93,7 @@ __BEGIN_DECLS #define DM_BUF_SIZE 4096 int fs_mgr_set_blk_ro(const char *blockdev); +int fs_mgr_test_access(const char *device); int fs_mgr_update_for_slotselect(struct fstab *fstab); __END_DECLS diff --git a/fs_mgr/fs_mgr_priv_dm_ioctl.h b/fs_mgr/fs_mgr_priv_dm_ioctl.h new file mode 100644 index 000000000..cf535d229 --- /dev/null +++ b/fs_mgr/fs_mgr_priv_dm_ioctl.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CORE_FS_MGR_PRIV_DM_IOCTL_H +#define __CORE_FS_MGR_PRIV_DM_IOCTL_H + +#include + +__BEGIN_DECLS + +void fs_mgr_verity_ioctl_init(struct dm_ioctl *io, const char *name, unsigned flags); +int fs_mgr_create_verity_device(struct dm_ioctl *io, char *name, int fd); +int fs_mgr_destroy_verity_device(struct dm_ioctl *io, char *name, int fd); +int fs_mgr_get_verity_device_name(struct dm_ioctl *io, char *name, int fd, char **dev_name); +int fs_mgr_resume_verity_table(struct dm_ioctl *io, char *name, int fd); + +__END_DECLS + +#endif /* __CORE_FS_MGR_PRIV_DM_IOCTL_H */ diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp index d43c75699..ab56cd7db 100644 --- a/fs_mgr/fs_mgr_verity.cpp +++ b/fs_mgr/fs_mgr_verity.cpp @@ -44,6 +44,7 @@ #include "fs_mgr.h" #include "fs_mgr_priv.h" +#include "fs_mgr_priv_dm_ioctl.h" #include "fs_mgr_priv_verity.h" #define FSTAB_PREFIX "/fstab." @@ -184,55 +185,6 @@ static int invalidate_table(char *table, size_t table_length) return -1; } -static void verity_ioctl_init(struct dm_ioctl *io, const char *name, unsigned flags) -{ - memset(io, 0, DM_BUF_SIZE); - io->data_size = DM_BUF_SIZE; - io->data_start = sizeof(struct dm_ioctl); - io->version[0] = 4; - io->version[1] = 0; - io->version[2] = 0; - io->flags = flags | DM_READONLY_FLAG; - if (name) { - strlcpy(io->name, name, sizeof(io->name)); - } -} - -static int create_verity_device(struct dm_ioctl *io, char *name, int fd) -{ - verity_ioctl_init(io, name, 1); - if (ioctl(fd, DM_DEV_CREATE, io)) { - ERROR("Error creating device mapping (%s)", strerror(errno)); - return -1; - } - return 0; -} - -static int destroy_verity_device(struct dm_ioctl *io, char *name, int fd) -{ - verity_ioctl_init(io, name, 0); - if (ioctl(fd, DM_DEV_REMOVE, io)) { - ERROR("Error removing device mapping (%s)", strerror(errno)); - return -1; - } - return 0; -} - -static int get_verity_device_name(struct dm_ioctl *io, char *name, int fd, char **dev_name) -{ - verity_ioctl_init(io, name, 0); - if (ioctl(fd, DM_DEV_STATUS, io)) { - ERROR("Error fetching verity device number (%s)", strerror(errno)); - return -1; - } - int dev_num = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00); - if (asprintf(dev_name, "/dev/block/dm-%u", dev_num) < 0) { - ERROR("Error getting verity block device name (%s)", strerror(errno)); - return -1; - } - return 0; -} - struct verity_table_params { char *table; int mode; @@ -308,7 +260,7 @@ static int load_verity_table(struct dm_ioctl *io, char *name, uint64_t device_si char *buffer = (char*) io; size_t bufsize; - verity_ioctl_init(io, name, DM_STATUS_TABLE_FLAG); + fs_mgr_verity_ioctl_init(io, name, DM_STATUS_TABLE_FLAG); struct dm_target_spec *tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)]; @@ -344,27 +296,6 @@ static int load_verity_table(struct dm_ioctl *io, char *name, uint64_t device_si return 0; } -static int resume_verity_table(struct dm_ioctl *io, char *name, int fd) -{ - verity_ioctl_init(io, name, 0); - if (ioctl(fd, DM_DEV_SUSPEND, io)) { - ERROR("Error activating verity device (%s)", strerror(errno)); - return -1; - } - return 0; -} - -static int test_access(char *device) { - int tries = 25; - while (tries--) { - if (!access(device, F_OK) || errno != ENOENT) { - return 0; - } - usleep(40 * 1000); - } - return -1; -} - static int check_verity_restart(const char *fname) { char buffer[VERITY_KMSG_BUFSIZE + 1]; @@ -872,7 +803,7 @@ int fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback) mount_point = basename(fstab->recs[i].mount_point); } - verity_ioctl_init(io, mount_point, 0); + fs_mgr_verity_ioctl_init(io, mount_point, 0); if (ioctl(fd, DM_TABLE_STATUS, io)) { if (fstab->recs[i].fs_mgr_flags & MF_VERIFYATBOOT) { @@ -983,13 +914,13 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab, bool verify_dev) } // create the device - if (create_verity_device(io, mount_point, fd) < 0) { + if (fs_mgr_create_verity_device(io, mount_point, fd) < 0) { ERROR("Couldn't create verity device!\n"); goto out; } // get the name of the device file - if (get_verity_device_name(io, mount_point, fd, &verity_blk_name) < 0) { + if (fs_mgr_get_verity_device_name(io, mount_point, fd, &verity_blk_name) < 0) { ERROR("Couldn't get verity device number!\n"); goto out; } @@ -1072,7 +1003,7 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab, bool verify_dev) loaded: // activate the device - if (resume_verity_table(io, mount_point, fd) < 0) { + if (fs_mgr_resume_verity_table(io, mount_point, fd) < 0) { goto out; } @@ -1095,13 +1026,13 @@ loaded: free(fstab->blk_device); fstab->blk_device = verity_blk_name; verity_blk_name = 0; - } else if (destroy_verity_device(io, mount_point, fd) < 0) { + } else if (fs_mgr_destroy_verity_device(io, mount_point, fd) < 0) { ERROR("Failed to remove verity device %s\n", mount_point); goto out; } // make sure we've set everything up properly - if (verify_dev && test_access(fstab->blk_device) < 0) { + if (verify_dev && fs_mgr_test_access(fstab->blk_device) < 0) { goto out; }