Merge "Replace manual dm ioctls with libdm." am: bc5818774c
am: f1fa57d602
Change-Id: I8f49bf924272195c6ae2e827cfb78766d644d154
diff --git a/Android.bp b/Android.bp
index 1045dc2..03e9a3f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -30,6 +30,7 @@
static_libs: [
"libavb",
"libbootloader_message",
+ "libdm",
"libfec",
"libfec_rs",
"libfs_avb",
diff --git a/Devmapper.cpp b/Devmapper.cpp
index b42467c..d55d92d 100644
--- a/Devmapper.cpp
+++ b/Devmapper.cpp
@@ -23,7 +23,6 @@
#include <string.h>
#include <unistd.h>
-#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -32,239 +31,72 @@
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
+#include <libdm/dm.h>
#include <utils/Trace.h>
#include "Devmapper.h"
-#define DEVMAPPER_BUFFER_SIZE 4096
-
using android::base::StringPrintf;
+using namespace android::dm;
static const char* kVoldPrefix = "vold:";
-void Devmapper::ioctlInit(struct dm_ioctl* io, size_t dataSize, const char* name, unsigned flags) {
- memset(io, 0, dataSize);
- io->data_size = dataSize;
- io->data_start = sizeof(struct dm_ioctl);
- io->version[0] = 4;
- io->version[1] = 0;
- io->version[2] = 0;
- io->flags = flags;
- if (name) {
- size_t ret = strlcpy(io->name, name, sizeof(io->name));
- if (ret >= sizeof(io->name)) abort();
- }
-}
-
int Devmapper::create(const char* name_raw, const char* loopFile, const char* key,
unsigned long numSectors, char* ubuffer, size_t len) {
+ auto& dm = DeviceMapper::Instance();
auto name_string = StringPrintf("%s%s", kVoldPrefix, name_raw);
- const char* name = name_string.c_str();
- char* buffer = (char*)malloc(DEVMAPPER_BUFFER_SIZE);
- if (!buffer) {
- PLOG(ERROR) << "Failed malloc";
+ DmTable table;
+ table.Emplace<DmTargetCrypt>(0, numSectors, "twofish", key, 0, loopFile, 0);
+
+ if (!dm.CreateDevice(name_string, table)) {
+ LOG(ERROR) << "Failed to create device-mapper device " << name_string;
return -1;
}
- int fd;
- if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
- PLOG(ERROR) << "Failed open";
- free(buffer);
+ std::string path;
+ if (!dm.GetDmDevicePathByName(name_string, &path)) {
+ LOG(ERROR) << "Failed to get device-mapper device path for " << name_string;
return -1;
}
-
- struct dm_ioctl* io = (struct dm_ioctl*)buffer;
-
- // Create the DM device
- ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0);
-
- if (ioctl(fd, DM_DEV_CREATE, io)) {
- PLOG(ERROR) << "Failed DM_DEV_CREATE";
- free(buffer);
- close(fd);
- return -1;
- }
-
- // Set the legacy geometry
- ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0);
-
- char* geoParams = buffer + sizeof(struct dm_ioctl);
- // bps=512 spc=8 res=32 nft=2 sec=8190 mid=0xf0 spt=63 hds=64 hid=0 bspf=8 rdcl=2 infs=1 bkbs=2
- strlcpy(geoParams, "0 64 63 0", DEVMAPPER_BUFFER_SIZE - sizeof(struct dm_ioctl));
- geoParams += strlen(geoParams) + 1;
- geoParams = (char*)_align(geoParams, 8);
- if (ioctl(fd, DM_DEV_SET_GEOMETRY, io)) {
- PLOG(ERROR) << "Failed DM_DEV_SET_GEOMETRY";
- free(buffer);
- close(fd);
- return -1;
- }
-
- // Retrieve the device number we were allocated
- ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0);
- if (ioctl(fd, DM_DEV_STATUS, io)) {
- PLOG(ERROR) << "Failed DM_DEV_STATUS";
- free(buffer);
- close(fd);
- return -1;
- }
-
- unsigned minor = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00);
- snprintf(ubuffer, len, "/dev/block/dm-%u", minor);
-
- // Load the table
- struct dm_target_spec* tgt;
- tgt = (struct dm_target_spec*)&buffer[sizeof(struct dm_ioctl)];
-
- ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, DM_STATUS_TABLE_FLAG);
- io->target_count = 1;
- tgt->status = 0;
-
- tgt->sector_start = 0;
- tgt->length = numSectors;
-
- strlcpy(tgt->target_type, "crypt", sizeof(tgt->target_type));
-
- char* cryptParams = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec);
- snprintf(cryptParams,
- DEVMAPPER_BUFFER_SIZE - (sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec)),
- "twofish %s 0 %s 0", key, loopFile);
- cryptParams += strlen(cryptParams) + 1;
- cryptParams = (char*)_align(cryptParams, 8);
- tgt->next = cryptParams - buffer;
-
- if (ioctl(fd, DM_TABLE_LOAD, io)) {
- PLOG(ERROR) << "Failed DM_TABLE_LOAD";
- free(buffer);
- close(fd);
- return -1;
- }
-
- // Resume the new table
- ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0);
-
- if (ioctl(fd, DM_DEV_SUSPEND, io)) {
- PLOG(ERROR) << "Failed DM_DEV_SUSPEND";
- free(buffer);
- close(fd);
- return -1;
- }
-
- free(buffer);
-
- close(fd);
+ snprintf(ubuffer, len, "%s", path.c_str());
return 0;
}
int Devmapper::destroy(const char* name_raw) {
+ auto& dm = DeviceMapper::Instance();
+
auto name_string = StringPrintf("%s%s", kVoldPrefix, name_raw);
- const char* name = name_string.c_str();
-
- char* buffer = (char*)malloc(DEVMAPPER_BUFFER_SIZE);
- if (!buffer) {
- PLOG(ERROR) << "Failed malloc";
- return -1;
- }
-
- int fd;
- if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
- PLOG(ERROR) << "Failed open";
- free(buffer);
- return -1;
- }
-
- struct dm_ioctl* io = (struct dm_ioctl*)buffer;
-
- // Create the DM device
- ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0);
-
- if (ioctl(fd, DM_DEV_REMOVE, io)) {
+ if (!dm.DeleteDevice(name_string)) {
if (errno != ENXIO) {
PLOG(ERROR) << "Failed DM_DEV_REMOVE";
}
- free(buffer);
- close(fd);
return -1;
}
-
- free(buffer);
- close(fd);
return 0;
}
int Devmapper::destroyAll() {
ATRACE_NAME("Devmapper::destroyAll");
- char* buffer = (char*)malloc(1024 * 64);
- if (!buffer) {
- PLOG(ERROR) << "Failed malloc";
- return -1;
- }
- memset(buffer, 0, (1024 * 64));
- char* buffer2 = (char*)malloc(DEVMAPPER_BUFFER_SIZE);
- if (!buffer2) {
- PLOG(ERROR) << "Failed malloc";
- free(buffer);
+ auto& dm = DeviceMapper::Instance();
+ std::vector<DeviceMapper::DmBlockDevice> devices;
+ if (!dm.GetAvailableDevices(&devices)) {
+ LOG(ERROR) << "Failed to get dm devices";
return -1;
}
- int fd;
- if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
- PLOG(ERROR) << "Failed open";
- free(buffer);
- free(buffer2);
- return -1;
- }
-
- struct dm_ioctl* io = (struct dm_ioctl*)buffer;
- ioctlInit(io, (1024 * 64), NULL, 0);
-
- if (ioctl(fd, DM_LIST_DEVICES, io)) {
- PLOG(ERROR) << "Failed DM_LIST_DEVICES";
- free(buffer);
- free(buffer2);
- close(fd);
- return -1;
- }
-
- struct dm_name_list* n = (struct dm_name_list*)(((char*)buffer) + io->data_start);
- if (!n->dev) {
- free(buffer);
- free(buffer2);
- close(fd);
- return 0;
- }
-
- unsigned nxt = 0;
- do {
- n = (struct dm_name_list*)(((char*)n) + nxt);
- auto name = std::string(n->name);
- if (android::base::StartsWith(name, kVoldPrefix)) {
- LOG(DEBUG) << "Tearing down stale dm device named " << name;
-
- memset(buffer2, 0, DEVMAPPER_BUFFER_SIZE);
- struct dm_ioctl* io2 = (struct dm_ioctl*)buffer2;
- ioctlInit(io2, DEVMAPPER_BUFFER_SIZE, n->name, 0);
- if (ioctl(fd, DM_DEV_REMOVE, io2)) {
+ for (const auto& device : devices) {
+ if (android::base::StartsWith(device.name(), kVoldPrefix)) {
+ LOG(DEBUG) << "Tearing down stale dm device named " << device.name();
+ if (!dm.DeleteDevice(device.name())) {
if (errno != ENXIO) {
- PLOG(WARNING) << "Failed to destroy dm device named " << name;
+ PLOG(WARNING) << "Failed to destroy dm device named " << device.name();
}
}
} else {
- LOG(DEBUG) << "Found unmanaged dm device named " << name;
+ LOG(DEBUG) << "Found unmanaged dm device named " << device.name();
}
- nxt = n->next;
- } while (nxt);
-
- free(buffer);
- free(buffer2);
- close(fd);
+ }
return 0;
}
-
-void* Devmapper::_align(void* ptr, unsigned int a) {
- unsigned long agn = --a;
-
- return (void*)(((unsigned long)ptr + agn) & ~agn);
-}
diff --git a/Devmapper.h b/Devmapper.h
index b1f6dfa..9d4896e 100644
--- a/Devmapper.h
+++ b/Devmapper.h
@@ -26,10 +26,6 @@
unsigned long numSectors, char* buffer, size_t len);
static int destroy(const char* name);
static int destroyAll();
-
- private:
- static void* _align(void* ptr, unsigned int a);
- static void ioctlInit(struct dm_ioctl* io, size_t data_size, const char* name, unsigned flags);
};
#endif
diff --git a/MetadataCrypt.cpp b/MetadataCrypt.cpp
index deb7194..573d4cc 100644
--- a/MetadataCrypt.cpp
+++ b/MetadataCrypt.cpp
@@ -23,19 +23,17 @@
#include <vector>
#include <fcntl.h>
-#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <linux/dm-ioctl.h>
-
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/unique_fd.h>
#include <cutils/fs.h>
#include <fs_mgr.h>
+#include <libdm/dm.h>
#include "Checkpoint.h"
#include "EncryptInplace.h"
@@ -45,13 +43,12 @@
#include "Utils.h"
#include "VoldUtil.h"
-#define DM_CRYPT_BUF_SIZE 4096
#define TABLE_LOAD_RETRIES 10
-#define DEFAULT_KEY_TARGET_TYPE "default-key"
using android::fs_mgr::FstabEntry;
using android::fs_mgr::GetEntryForMountPoint;
using android::vold::KeyBuffer;
+using namespace android::dm;
static const std::string kDmNameUserdata = "userdata";
@@ -146,16 +143,6 @@
} // namespace vold
} // namespace android
-static KeyBuffer default_key_params(const std::string& real_blkdev, const KeyBuffer& key) {
- KeyBuffer hex_key;
- if (android::vold::StrToHex(key, hex_key) != android::OK) {
- LOG(ERROR) << "Failed to turn key to hex";
- return KeyBuffer();
- }
- auto res = KeyBuffer() + "AES-256-XTS " + hex_key + " " + real_blkdev.c_str() + " 0";
- return res;
-}
-
static bool get_number_of_sectors(const std::string& real_blkdev, uint64_t* nr_sec) {
if (android::vold::GetBlockDev512Sectors(real_blkdev, nr_sec) != android::OK) {
PLOG(ERROR) << "Unable to measure size of " << real_blkdev;
@@ -164,86 +151,35 @@
return true;
}
-static struct dm_ioctl* dm_ioctl_init(char* buffer, size_t buffer_size, const std::string& dm_name) {
- if (buffer_size < sizeof(dm_ioctl)) {
- LOG(ERROR) << "dm_ioctl buffer too small";
- return nullptr;
- }
-
- memset(buffer, 0, buffer_size);
- struct dm_ioctl* io = (struct dm_ioctl*)buffer;
- io->data_size = buffer_size;
- io->data_start = sizeof(struct dm_ioctl);
- io->version[0] = 4;
- io->version[1] = 0;
- io->version[2] = 0;
- io->flags = 0;
- dm_name.copy(io->name, sizeof(io->name));
- return io;
-}
-
static bool create_crypto_blk_dev(const std::string& dm_name, uint64_t nr_sec,
- const std::string& target_type, const KeyBuffer& crypt_params,
+ const std::string& real_blkdev, const KeyBuffer& key,
std::string* crypto_blkdev) {
- android::base::unique_fd dm_fd(
- TEMP_FAILURE_RETRY(open("/dev/device-mapper", O_RDWR | O_CLOEXEC, 0)));
- if (dm_fd == -1) {
- PLOG(ERROR) << "Cannot open device-mapper";
+ auto& dm = DeviceMapper::Instance();
+
+ KeyBuffer hex_key_buffer;
+ if (android::vold::StrToHex(key, hex_key_buffer) != android::OK) {
+ LOG(ERROR) << "Failed to turn key to hex";
return false;
}
- alignas(struct dm_ioctl) char buffer[DM_CRYPT_BUF_SIZE];
- auto io = dm_ioctl_init(buffer, sizeof(buffer), dm_name);
- if (!io || ioctl(dm_fd.get(), DM_DEV_CREATE, io) != 0) {
- PLOG(ERROR) << "Cannot create dm-crypt device " << dm_name;
- return false;
- }
+ std::string hex_key(hex_key_buffer.data(), hex_key_buffer.size());
- // Get the device status, in particular, the name of its device file
- io = dm_ioctl_init(buffer, sizeof(buffer), dm_name);
- if (ioctl(dm_fd.get(), DM_DEV_STATUS, io) != 0) {
- PLOG(ERROR) << "Cannot retrieve dm-crypt device status " << dm_name;
- return false;
- }
- *crypto_blkdev = std::string() + "/dev/block/dm-" +
- std::to_string((io->dev & 0xff) | ((io->dev >> 12) & 0xfff00));
-
- io = dm_ioctl_init(buffer, sizeof(buffer), dm_name);
- size_t paramix = io->data_start + sizeof(struct dm_target_spec);
- size_t nullix = paramix + crypt_params.size();
- size_t endix = (nullix + 1 + 7) & 8; // Add room for \0 and align to 8 byte boundary
-
- if (endix > sizeof(buffer)) {
- LOG(ERROR) << "crypt_params too big for DM_CRYPT_BUF_SIZE";
- return false;
- }
-
- io->target_count = 1;
- auto tgt = (struct dm_target_spec*)(buffer + io->data_start);
- tgt->status = 0;
- tgt->sector_start = 0;
- tgt->length = nr_sec;
- target_type.copy(tgt->target_type, sizeof(tgt->target_type));
- memcpy(buffer + paramix, crypt_params.data(),
- std::min(crypt_params.size(), sizeof(buffer) - paramix));
- buffer[nullix] = '\0';
- tgt->next = endix;
+ DmTable table;
+ table.Emplace<DmTargetDefaultKey>(0, nr_sec, "AES-256-XTS", hex_key, real_blkdev, 0);
for (int i = 0;; i++) {
- if (ioctl(dm_fd.get(), DM_TABLE_LOAD, io) == 0) {
+ if (dm.CreateDevice(dm_name, table)) {
break;
}
if (i + 1 >= TABLE_LOAD_RETRIES) {
- PLOG(ERROR) << "DM_TABLE_LOAD ioctl failed";
+ LOG(ERROR) << "Could not create default-key device " << dm_name;
return false;
}
- PLOG(INFO) << "DM_TABLE_LOAD ioctl failed, retrying";
+ PLOG(INFO) << "Could not create default-key device, retrying";
usleep(500000);
}
- // Resume this device to activate it
- io = dm_ioctl_init(buffer, sizeof(buffer), dm_name);
- if (ioctl(dm_fd.get(), DM_DEV_SUSPEND, io)) {
- PLOG(ERROR) << "Cannot resume dm-crypt device " << dm_name;
+ if (!dm.GetDmDevicePathByName(dm_name, crypto_blkdev)) {
+ LOG(ERROR) << "Cannot retrieve default-key device status " << dm_name;
return false;
}
return true;
@@ -267,8 +203,7 @@
uint64_t nr_sec;
if (!get_number_of_sectors(data_rec->blk_device, &nr_sec)) return false;
std::string crypto_blkdev;
- if (!create_crypto_blk_dev(kDmNameUserdata, nr_sec, DEFAULT_KEY_TARGET_TYPE,
- default_key_params(data_rec->blk_device, key), &crypto_blkdev))
+ if (!create_crypto_blk_dev(kDmNameUserdata, nr_sec, data_rec->blk_device, key, &crypto_blkdev))
return false;
// FIXME handle the corrupt case
if (needs_encrypt) {
diff --git a/cryptfs.cpp b/cryptfs.cpp
index 0b7101e..c5d0307 100644
--- a/cryptfs.cpp
+++ b/cryptfs.cpp
@@ -45,6 +45,7 @@
#include <fs_mgr.h>
#include <fscrypt/fscrypt.h>
#include <hardware_legacy/power.h>
+#include <libdm/dm.h>
#include <log/log.h>
#include <logwrap/logwrap.h>
#include <openssl/evp.h>
@@ -56,13 +57,11 @@
#include <fcntl.h>
#include <inttypes.h>
#include <libgen.h>
-#include <linux/dm-ioctl.h>
#include <linux/kdev_t.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/param.h>
#include <sys/stat.h>
@@ -78,12 +77,11 @@
using android::base::ParseUint;
using android::base::StringPrintf;
using android::fs_mgr::GetEntryForMountPoint;
+using namespace android::dm;
using namespace std::chrono_literals;
#define UNUSED __attribute__((unused))
-#define DM_CRYPT_BUF_SIZE 4096
-
#define HASH_COUNT 2000
constexpr size_t INTERMEDIATE_KEY_LEN_BYTES = 16;
@@ -253,19 +251,6 @@
return;
}
-static void ioctl_init(struct dm_ioctl* io, size_t dataSize, const char* name, unsigned flags) {
- memset(io, 0, dataSize);
- io->data_size = dataSize;
- io->data_start = sizeof(struct dm_ioctl);
- io->version[0] = 4;
- io->version[1] = 0;
- io->version[2] = 0;
- io->flags = flags;
- if (name) {
- strlcpy(io->name, name, sizeof(io->name));
- }
-}
-
namespace {
struct CryptoType;
@@ -973,109 +958,12 @@
master_key_ascii[a] = '\0';
}
-static int load_crypto_mapping_table(struct crypt_mnt_ftr* crypt_ftr,
- const unsigned char* master_key, const char* real_blk_name,
- const char* name, int fd, const char* extra_params) {
- alignas(struct dm_ioctl) char buffer[DM_CRYPT_BUF_SIZE];
- struct dm_ioctl* io;
- struct dm_target_spec* tgt;
- char* crypt_params;
- // We need two ASCII characters to represent each byte, and need space for
- // the '\0' terminator.
- char master_key_ascii[MAX_KEY_LEN * 2 + 1];
- size_t buff_offset;
- int i;
-
- io = (struct dm_ioctl*)buffer;
-
- /* Load the mapping table for this device */
- tgt = (struct dm_target_spec*)&buffer[sizeof(struct dm_ioctl)];
-
- ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
- io->target_count = 1;
- tgt->status = 0;
- tgt->sector_start = 0;
- tgt->length = crypt_ftr->fs_size;
- strlcpy(tgt->target_type, "crypt", DM_MAX_TYPE_NAME);
-
- crypt_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec);
- convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii);
-
- buff_offset = crypt_params - buffer;
- SLOGI(
- "Creating crypto dev \"%s\"; cipher=%s, keysize=%u, real_dev=%s, len=%llu, params=\"%s\"\n",
- name, crypt_ftr->crypto_type_name, crypt_ftr->keysize, real_blk_name, tgt->length * 512,
- extra_params);
- snprintf(crypt_params, sizeof(buffer) - buff_offset, "%s %s 0 %s 0 %s",
- crypt_ftr->crypto_type_name, master_key_ascii, real_blk_name, extra_params);
- crypt_params += strlen(crypt_params) + 1;
- crypt_params =
- (char*)(((unsigned long)crypt_params + 7) & ~8); /* Align to an 8 byte boundary */
- tgt->next = crypt_params - buffer;
-
- for (i = 0; i < TABLE_LOAD_RETRIES; i++) {
- if (!ioctl(fd, DM_TABLE_LOAD, io)) {
- break;
- }
- usleep(500000);
- }
-
- if (i == TABLE_LOAD_RETRIES) {
- /* We failed to load the table, return an error */
- return -1;
- } else {
- return i + 1;
- }
-}
-
-static int get_dm_crypt_version(int fd, const char* name, int* version) {
- char buffer[DM_CRYPT_BUF_SIZE];
- struct dm_ioctl* io;
- struct dm_target_versions* v;
-
- io = (struct dm_ioctl*)buffer;
-
- ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
-
- if (ioctl(fd, DM_LIST_VERSIONS, io)) {
- return -1;
- }
-
- /* Iterate over the returned versions, looking for name of "crypt".
- * When found, get and return the version.
- */
- v = (struct dm_target_versions*)&buffer[sizeof(struct dm_ioctl)];
- while (v->next) {
- if (!strcmp(v->name, "crypt")) {
- /* We found the crypt driver, return the version, and get out */
- version[0] = v->version[0];
- version[1] = v->version[1];
- version[2] = v->version[2];
- return 0;
- }
- v = (struct dm_target_versions*)(((char*)v) + v->next);
- }
-
- return -1;
-}
-
-static std::string extra_params_as_string(const std::vector<std::string>& extra_params_vec) {
- if (extra_params_vec.empty()) return "";
- std::string extra_params = std::to_string(extra_params_vec.size());
- for (const auto& p : extra_params_vec) {
- extra_params.append(" ");
- extra_params.append(p);
- }
- return extra_params;
-}
-
/*
* If the ro.crypto.fde_sector_size system property is set, append the
* parameters to make dm-crypt use the specified crypto sector size and round
* the crypto device size down to a crypto sector boundary.
*/
-static int add_sector_size_param(std::vector<std::string>* extra_params_vec,
- struct crypt_mnt_ftr* ftr) {
+static int add_sector_size_param(DmTargetCrypt* target, struct crypt_mnt_ftr* ftr) {
constexpr char DM_CRYPT_SECTOR_SIZE[] = "ro.crypto.fde_sector_size";
char value[PROPERTY_VALUE_MAX];
@@ -1089,12 +977,11 @@
return -1;
}
- std::string param = StringPrintf("sector_size:%u", sector_size);
- extra_params_vec->push_back(std::move(param));
+ target->SetSectorSize(sector_size);
// With this option, IVs will match the sector numbering, instead
// of being hard-coded to being based on 512-byte sectors.
- extra_params_vec->emplace_back("iv_large_sectors");
+ target->SetIvLargeSectors();
// Round the crypto device size down to a crypto sector boundary.
ftr->fs_size &= ~((sector_size / 512) - 1);
@@ -1105,112 +992,67 @@
static int create_crypto_blk_dev(struct crypt_mnt_ftr* crypt_ftr, const unsigned char* master_key,
const char* real_blk_name, char* crypto_blk_name, const char* name,
uint32_t flags) {
- char buffer[DM_CRYPT_BUF_SIZE];
- struct dm_ioctl* io;
- unsigned int minor;
- int fd = 0;
- int err;
- int retval = -1;
- int version[3];
- int load_count;
- std::vector<std::string> extra_params_vec;
+ auto& dm = DeviceMapper::Instance();
- if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
- SLOGE("Cannot open device-mapper\n");
- goto errout;
- }
+ // We need two ASCII characters to represent each byte, and need space for
+ // the '\0' terminator.
+ char master_key_ascii[MAX_KEY_LEN * 2 + 1];
+ convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii);
- io = (struct dm_ioctl*)buffer;
+ auto target = std::make_unique<DmTargetCrypt>(0, crypt_ftr->fs_size,
+ (const char*)crypt_ftr->crypto_type_name,
+ master_key_ascii, 0, real_blk_name, 0);
+ target->AllowDiscards();
- ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
- err = ioctl(fd, DM_DEV_CREATE, io);
- if (err) {
- SLOGE("Cannot create dm-crypt device %s: %s\n", name, strerror(errno));
- goto errout;
- }
-
- /* Get the device status, in particular, the name of it's device file */
- ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
- if (ioctl(fd, DM_DEV_STATUS, io)) {
- SLOGE("Cannot retrieve dm-crypt device status\n");
- goto errout;
- }
- minor = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00);
- snprintf(crypto_blk_name, MAXPATHLEN, "/dev/block/dm-%u", minor);
-
- if (!get_dm_crypt_version(fd, name, version)) {
- /* Support for allow_discards was added in version 1.11.0 */
- if ((version[0] >= 2) || ((version[0] == 1) && (version[1] >= 11))) {
- extra_params_vec.emplace_back("allow_discards");
- }
- }
if (flags & CREATE_CRYPTO_BLK_DEV_FLAGS_ALLOW_ENCRYPT_OVERRIDE) {
- extra_params_vec.emplace_back("allow_encrypt_override");
+ target->AllowEncryptOverride();
}
- if (add_sector_size_param(&extra_params_vec, crypt_ftr)) {
+ if (add_sector_size_param(target.get(), crypt_ftr)) {
SLOGE("Error processing dm-crypt sector size param\n");
- goto errout;
+ return -1;
}
- load_count = load_crypto_mapping_table(crypt_ftr, master_key, real_blk_name, name, fd,
- extra_params_as_string(extra_params_vec).c_str());
- if (load_count < 0) {
+
+ DmTable table;
+ table.AddTarget(std::move(target));
+
+ int load_count = 1;
+ while (load_count < TABLE_LOAD_RETRIES) {
+ if (dm.CreateDevice(name, table)) {
+ break;
+ }
+ load_count++;
+ }
+
+ if (load_count >= TABLE_LOAD_RETRIES) {
SLOGE("Cannot load dm-crypt mapping table.\n");
- goto errout;
- } else if (load_count > 1) {
+ return -1;
+ }
+ if (load_count > 1) {
SLOGI("Took %d tries to load dmcrypt table.\n", load_count);
}
- /* Resume this device to activate it */
- ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
-
- if (ioctl(fd, DM_DEV_SUSPEND, io)) {
- SLOGE("Cannot resume the dm-crypt device\n");
- goto errout;
+ std::string path;
+ if (!dm.GetDmDevicePathByName(name, &path)) {
+ SLOGE("Cannot determine dm-crypt path for %s.\n", name);
+ return -1;
}
+ snprintf(crypto_blk_name, MAXPATHLEN, "%s", path.c_str());
/* Ensure the dm device has been created before returning. */
if (android::vold::WaitForFile(crypto_blk_name, 1s) < 0) {
// WaitForFile generates a suitable log message
- goto errout;
+ return -1;
}
-
- /* We made it here with no errors. Woot! */
- retval = 0;
-
-errout:
- close(fd); /* If fd is <0 from a failed open call, it's safe to just ignore the close error */
-
- return retval;
+ return 0;
}
-static int delete_crypto_blk_dev(const char* name) {
- int fd;
- char buffer[DM_CRYPT_BUF_SIZE];
- struct dm_ioctl* io;
- int retval = -1;
- int err;
-
- if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
- SLOGE("Cannot open device-mapper\n");
- goto errout;
+static int delete_crypto_blk_dev(const std::string& name) {
+ auto& dm = DeviceMapper::Instance();
+ if (!dm.DeleteDevice(name)) {
+ SLOGE("Cannot remove dm-crypt device %s: %s\n", name.c_str(), strerror(errno));
+ return -1;
}
-
- io = (struct dm_ioctl*)buffer;
-
- ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
- err = ioctl(fd, DM_DEV_REMOVE, io);
- if (err) {
- SLOGE("Cannot remove dm-crypt device %s: %s\n", name, strerror(errno));
- goto errout;
- }
-
- /* We made it here with no errors. Woot! */
- retval = 0;
-
-errout:
- close(fd); /* If fd is <0 from a failed open call, it's safe to just ignore the close error */
-
- return retval;
+ return 0;
}
static int pbkdf2(const char* passwd, const unsigned char* salt, unsigned char* ikey,
@@ -1924,7 +1766,7 @@
* storage volume.
*/
int cryptfs_revert_ext_volume(const char* label) {
- return delete_crypto_blk_dev((char*)label);
+ return delete_crypto_blk_dev(label);
}
int cryptfs_crypto_complete(void) {