From 42b0ab437a6ef332dd33e1eda144d2c3d9a70d23 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Sun, 23 Jun 2013 15:26:45 +0200 Subject: [PATCH] Print a warning if system encryption is used and device is a partition. System encryption hav metadata in space located ouside of partition itself. Ideally the check should be automatic but for virtualized systems (where a partition could be "whole device" for another sustem this can be dangerous. --- lib/internal.h | 1 + lib/tcrypt/tcrypt.c | 11 +++++++++-- lib/utils_devpath.c | 27 +++++++++++++++++++++++---- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/lib/internal.h b/lib/internal.h index 71d5709..b1a1936 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -97,6 +97,7 @@ int crypt_confirm(struct crypt_device *cd, const char *msg); char *crypt_lookup_dev(const char *dev_id); int crypt_sysfs_get_rotational(int major, int minor, int *rotational); +int crypt_sysfs_get_partition(const char *dev_path, int *partition); ssize_t write_blockwise(int fd, int bsize, void *buf, size_t count); ssize_t read_blockwise(int fd, int bsize, void *_buf, size_t count); diff --git a/lib/tcrypt/tcrypt.c b/lib/tcrypt/tcrypt.c index 3bab4ba..6de62fa 100644 --- a/lib/tcrypt/tcrypt.c +++ b/lib/tcrypt/tcrypt.c @@ -565,7 +565,7 @@ int TCRYPT_read_phdr(struct crypt_device *cd, { struct device *device = crypt_metadata_device(cd); ssize_t hdr_size = sizeof(struct tcrypt_phdr); - int devfd = 0, r, bs; + int devfd = 0, r, bs, partition; assert(sizeof(struct tcrypt_phdr) == 512); @@ -585,8 +585,15 @@ int TCRYPT_read_phdr(struct crypt_device *cd, r = -EIO; if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER) { if (lseek(devfd, TCRYPT_HDR_SYSTEM_OFFSET, SEEK_SET) >= 0 && - read_blockwise(devfd, bs, hdr, hdr_size) == hdr_size) + read_blockwise(devfd, bs, hdr, hdr_size) == hdr_size) { r = TCRYPT_init_hdr(cd, hdr, params); + if (r == -EPERM && + crypt_sysfs_get_partition(device_path(device), &partition) && + partition) + log_std(cd, _("WARNING: device %s is a partition, for TCRYPT " + "system encryption you usually need to use " + "whole block device path.\n"), device_path(device)); + } } else if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER) { if (params->flags & CRYPT_TCRYPT_BACKUP_HEADER) { if (lseek(devfd, TCRYPT_HDR_HIDDEN_OFFSET_BCK, SEEK_END) >= 0 && diff --git a/lib/utils_devpath.c b/lib/utils_devpath.c index 835f040..6c07b5b 100644 --- a/lib/utils_devpath.c +++ b/lib/utils_devpath.c @@ -170,13 +170,13 @@ char *crypt_lookup_dev(const char *dev_id) return devpath; } -int crypt_sysfs_get_rotational(int major, int minor, int *rotational) +static int _sysfs_get_int(int major, int minor, int *value, const char *attr) { char path[PATH_MAX], tmp[64] = {0}; int fd, r; - if (snprintf(path, sizeof(path), "/sys/dev/block/%d:%d/queue/rotational", - major, minor) < 0) + if (snprintf(path, sizeof(path), "/sys/dev/block/%d:%d/%s", + major, minor, attr) < 0) return 0; if ((fd = open(path, O_RDONLY)) < 0) @@ -187,8 +187,27 @@ int crypt_sysfs_get_rotational(int major, int minor, int *rotational) if (r <= 0) return 0; - if (sscanf(tmp, "%d", rotational) != 1) + if (sscanf(tmp, "%d", value) != 1) return 0; return 1; } + +int crypt_sysfs_get_rotational(int major, int minor, int *rotational) +{ + return _sysfs_get_int(major, minor, rotational, "queue/rotational"); +} + +int crypt_sysfs_get_partition(const char *dev_path, int *partition) +{ + struct stat st; + + if (stat(dev_path, &st) < 0) + return 0; + + if (!S_ISBLK(st.st_mode)) + return 0; + + return _sysfs_get_int(major(st.st_rdev), minor(st.st_rdev), + partition, "partition"); +} -- 2.7.4