mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Use device alignment wrapper.
And cache the value to not call ioctl on every block read/write.
This commit is contained in:
@@ -40,7 +40,7 @@ static int INTEGRITY_read_superblock(struct crypt_device *cd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (read_lseek_blockwise(devfd, device_block_size(device),
|
if (read_lseek_blockwise(devfd, device_block_size(device),
|
||||||
sb, sizeof(*sb), offset) != sizeof(*sb) ||
|
device_alignment(device), sb, sizeof(*sb), offset) != sizeof(*sb) ||
|
||||||
memcmp(sb->magic, SB_MAGIC, sizeof(sb->magic)) ||
|
memcmp(sb->magic, SB_MAGIC, sizeof(sb->magic)) ||
|
||||||
sb->version != SB_VERSION) {
|
sb->version != SB_VERSION) {
|
||||||
log_std(cd, "No integrity superblock detected on %s.\n",
|
log_std(cd, "No integrity superblock detected on %s.\n",
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ int device_open(struct device *device, int flags);
|
|||||||
void device_disable_direct_io(struct device *device);
|
void device_disable_direct_io(struct device *device);
|
||||||
int device_is_identical(struct device *device1, struct device *device2);
|
int device_is_identical(struct device *device1, struct device *device2);
|
||||||
int device_is_rotational(struct device *device);
|
int device_is_rotational(struct device *device);
|
||||||
|
size_t device_alignment(struct device *device);
|
||||||
|
|
||||||
enum devcheck { DEV_OK = 0, DEV_EXCL = 1, DEV_SHARED = 2 };
|
enum devcheck { DEV_OK = 0, DEV_EXCL = 1, DEV_SHARED = 2 };
|
||||||
int device_block_adjust(struct crypt_device *cd,
|
int device_block_adjust(struct crypt_device *cd,
|
||||||
@@ -104,10 +105,10 @@ uint64_t crypt_dev_partition_offset(const char *dev_path);
|
|||||||
|
|
||||||
ssize_t write_buffer(int fd, const void *buf, size_t count);
|
ssize_t write_buffer(int fd, const void *buf, size_t count);
|
||||||
ssize_t read_buffer(int fd, void *buf, size_t count);
|
ssize_t read_buffer(int fd, void *buf, size_t count);
|
||||||
ssize_t write_blockwise(int fd, int bsize, void *buf, size_t count);
|
ssize_t write_blockwise(int fd, int bsize, size_t alignment, void *orig_buf, size_t count);
|
||||||
ssize_t read_blockwise(int fd, int bsize, void *buf, size_t count);
|
ssize_t read_blockwise(int fd, int bsize, size_t alignment, void *buf, size_t count);
|
||||||
ssize_t write_lseek_blockwise(int fd, int bsize, void *buf, size_t count, off_t offset);
|
ssize_t write_lseek_blockwise(int fd, int bsize, size_t alignment, void *buf, size_t count, off_t offset);
|
||||||
ssize_t read_lseek_blockwise(int fd, int bsize, void *buf, size_t count, off_t offset);
|
ssize_t read_lseek_blockwise(int fd, int bsize, size_t alignment, void *buf, size_t count, off_t offset);
|
||||||
|
|
||||||
unsigned crypt_getpagesize(void);
|
unsigned crypt_getpagesize(void);
|
||||||
int init_crypto(struct crypt_device *ctx);
|
int init_crypto(struct crypt_device *ctx);
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ static int LUKS_endec_template(char *src, size_t srcLength,
|
|||||||
const char *cipher, const char *cipher_mode,
|
const char *cipher, const char *cipher_mode,
|
||||||
struct volume_key *vk,
|
struct volume_key *vk,
|
||||||
unsigned int sector,
|
unsigned int sector,
|
||||||
ssize_t (*func)(int, int, void *, size_t),
|
ssize_t (*func)(int, int, size_t, void *, size_t),
|
||||||
int mode,
|
int mode,
|
||||||
struct crypt_device *ctx)
|
struct crypt_device *ctx)
|
||||||
{
|
{
|
||||||
@@ -65,11 +65,13 @@ static int LUKS_endec_template(char *src, size_t srcLength,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
int r, bsize, devfd = -1;
|
int r, bsize, devfd = -1;
|
||||||
|
size_t alignment;
|
||||||
|
|
||||||
log_dbg("Using dmcrypt to access keyslot area.");
|
log_dbg("Using dmcrypt to access keyslot area.");
|
||||||
|
|
||||||
bsize = device_block_size(dmd.data_device);
|
bsize = device_block_size(dmd.data_device);
|
||||||
if (bsize <= 0)
|
alignment = device_alignment(dmd.data_device);
|
||||||
|
if (bsize <= 0 || !alignment)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
dmd.size = size_round_up(srcLength, bsize) / SECTOR_SIZE;
|
dmd.size = size_round_up(srcLength, bsize) / SECTOR_SIZE;
|
||||||
@@ -113,7 +115,7 @@ static int LUKS_endec_template(char *src, size_t srcLength,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = func(devfd, bsize, src, srcLength);
|
r = func(devfd, bsize, alignment, src, srcLength);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_err(ctx, _("Failed to access temporary keystore device.\n"));
|
log_err(ctx, _("Failed to access temporary keystore device.\n"));
|
||||||
r = -EIO;
|
r = -EIO;
|
||||||
@@ -137,6 +139,7 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength,
|
|||||||
struct device *device = crypt_metadata_device(ctx);
|
struct device *device = crypt_metadata_device(ctx);
|
||||||
struct crypt_storage *s;
|
struct crypt_storage *s;
|
||||||
int devfd = -1, bsize, r = 0;
|
int devfd = -1, bsize, r = 0;
|
||||||
|
size_t alignment;
|
||||||
|
|
||||||
/* Only whole sector writes supported */
|
/* Only whole sector writes supported */
|
||||||
if (srcLength % SECTOR_SIZE)
|
if (srcLength % SECTOR_SIZE)
|
||||||
@@ -172,7 +175,8 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength,
|
|||||||
|
|
||||||
/* Write buffer to device */
|
/* Write buffer to device */
|
||||||
bsize = device_block_size(device);
|
bsize = device_block_size(device);
|
||||||
if (bsize <= 0)
|
alignment = device_alignment(device);
|
||||||
|
if (bsize <= 0 || !alignment)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
devfd = device_open(device, O_RDWR);
|
devfd = device_open(device, O_RDWR);
|
||||||
@@ -180,7 +184,7 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength,
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (lseek(devfd, sector * SECTOR_SIZE, SEEK_SET) == -1 ||
|
if (lseek(devfd, sector * SECTOR_SIZE, SEEK_SET) == -1 ||
|
||||||
write_blockwise(devfd, bsize, src, srcLength) == -1)
|
write_blockwise(devfd, bsize, alignment, src, srcLength) == -1)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
r = 0;
|
r = 0;
|
||||||
@@ -203,6 +207,7 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
|
|||||||
struct device *device = crypt_metadata_device(ctx);
|
struct device *device = crypt_metadata_device(ctx);
|
||||||
struct crypt_storage *s;
|
struct crypt_storage *s;
|
||||||
int devfd = -1, bsize, r = 0;
|
int devfd = -1, bsize, r = 0;
|
||||||
|
size_t alignment;
|
||||||
|
|
||||||
/* Only whole sector reads supported */
|
/* Only whole sector reads supported */
|
||||||
if (dstLength % SECTOR_SIZE)
|
if (dstLength % SECTOR_SIZE)
|
||||||
@@ -231,7 +236,8 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
|
|||||||
|
|
||||||
/* Read buffer from device */
|
/* Read buffer from device */
|
||||||
bsize = device_block_size(device);
|
bsize = device_block_size(device);
|
||||||
if (bsize <= 0)
|
alignment = device_alignment(device);
|
||||||
|
if (bsize <= 0 || !alignment)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
devfd = device_open(device, O_RDONLY);
|
devfd = device_open(device, O_RDONLY);
|
||||||
@@ -239,7 +245,7 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
|
|||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
if (lseek(devfd, sector * SECTOR_SIZE, SEEK_SET) == -1 ||
|
if (lseek(devfd, sector * SECTOR_SIZE, SEEK_SET) == -1 ||
|
||||||
read_blockwise(devfd, bsize, dst, dstLength) == -1)
|
read_blockwise(devfd, bsize, alignment, dst, dstLength) == -1)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
close(devfd);
|
close(devfd);
|
||||||
|
|||||||
@@ -182,7 +182,8 @@ int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read_blockwise(devfd, device_block_size(device), buffer, hdr_size) < hdr_size) {
|
if (read_blockwise(devfd, device_block_size(device), device_alignment(device),
|
||||||
|
buffer, hdr_size) < hdr_size) {
|
||||||
r = -EIO;
|
r = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -301,7 +302,8 @@ int LUKS_hdr_restore(
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (write_blockwise(devfd, device_block_size(device), buffer, buffer_size) < buffer_size) {
|
if (write_blockwise(devfd, device_block_size(device), device_alignment(device),
|
||||||
|
buffer, buffer_size) < buffer_size) {
|
||||||
r = -EIO;
|
r = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -537,7 +539,8 @@ int LUKS_read_phdr(struct luks_phdr *hdr,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read_blockwise(devfd, device_block_size(device), hdr, hdr_size) < hdr_size)
|
if (read_blockwise(devfd, device_block_size(device), device_alignment(device),
|
||||||
|
hdr, hdr_size) < hdr_size)
|
||||||
r = -EIO;
|
r = -EIO;
|
||||||
else
|
else
|
||||||
r = _check_and_convert_hdr(device_path(device), hdr, require_luks_device,
|
r = _check_and_convert_hdr(device_path(device), hdr, require_luks_device,
|
||||||
@@ -602,7 +605,8 @@ int LUKS_write_phdr(struct luks_phdr *hdr,
|
|||||||
convHdr.keyblock[i].stripes = htonl(hdr->keyblock[i].stripes);
|
convHdr.keyblock[i].stripes = htonl(hdr->keyblock[i].stripes);
|
||||||
}
|
}
|
||||||
|
|
||||||
r = write_blockwise(devfd, device_block_size(device), &convHdr, hdr_size) < hdr_size ? -EIO : 0;
|
r = write_blockwise(devfd, device_block_size(device), device_alignment(device),
|
||||||
|
&convHdr, hdr_size) < hdr_size ? -EIO : 0;
|
||||||
if (r)
|
if (r)
|
||||||
log_err(ctx, _("Error during update of LUKS header on device %s.\n"), device_path(device));
|
log_err(ctx, _("Error during update of LUKS header on device %s.\n"), device_path(device));
|
||||||
close(devfd);
|
close(devfd);
|
||||||
|
|||||||
@@ -601,6 +601,7 @@ int TCRYPT_read_phdr(struct crypt_device *cd,
|
|||||||
ssize_t hdr_size = sizeof(struct tcrypt_phdr);
|
ssize_t hdr_size = sizeof(struct tcrypt_phdr);
|
||||||
char *base_device_path;
|
char *base_device_path;
|
||||||
int devfd = 0, r, bs;
|
int devfd = 0, r, bs;
|
||||||
|
size_t alignment;
|
||||||
|
|
||||||
assert(sizeof(struct tcrypt_phdr) == 512);
|
assert(sizeof(struct tcrypt_phdr) == 512);
|
||||||
|
|
||||||
@@ -608,6 +609,7 @@ int TCRYPT_read_phdr(struct crypt_device *cd,
|
|||||||
hdr_size, device_path(device));
|
hdr_size, device_path(device));
|
||||||
|
|
||||||
bs = device_block_size(device);
|
bs = device_block_size(device);
|
||||||
|
alignment = device_alignment(device);
|
||||||
if (bs < 0)
|
if (bs < 0)
|
||||||
return bs;
|
return bs;
|
||||||
|
|
||||||
@@ -635,28 +637,28 @@ int TCRYPT_read_phdr(struct crypt_device *cd,
|
|||||||
|
|
||||||
r = -EIO;
|
r = -EIO;
|
||||||
if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER) {
|
if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER) {
|
||||||
if (read_lseek_blockwise(devfd, bs, hdr, hdr_size,
|
if (read_lseek_blockwise(devfd, bs, alignment, hdr, hdr_size,
|
||||||
TCRYPT_HDR_SYSTEM_OFFSET) == hdr_size) {
|
TCRYPT_HDR_SYSTEM_OFFSET) == hdr_size) {
|
||||||
r = TCRYPT_init_hdr(cd, hdr, params);
|
r = TCRYPT_init_hdr(cd, hdr, params);
|
||||||
}
|
}
|
||||||
} else if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER) {
|
} else if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER) {
|
||||||
if (params->flags & CRYPT_TCRYPT_BACKUP_HEADER) {
|
if (params->flags & CRYPT_TCRYPT_BACKUP_HEADER) {
|
||||||
if (read_lseek_blockwise(devfd, bs, hdr, hdr_size,
|
if (read_lseek_blockwise(devfd, bs, alignment, hdr, hdr_size,
|
||||||
TCRYPT_HDR_HIDDEN_OFFSET_BCK) == hdr_size)
|
TCRYPT_HDR_HIDDEN_OFFSET_BCK) == hdr_size)
|
||||||
r = TCRYPT_init_hdr(cd, hdr, params);
|
r = TCRYPT_init_hdr(cd, hdr, params);
|
||||||
} else {
|
} else {
|
||||||
if (read_lseek_blockwise(devfd, bs, hdr, hdr_size,
|
if (read_lseek_blockwise(devfd, bs, alignment, hdr, hdr_size,
|
||||||
TCRYPT_HDR_HIDDEN_OFFSET) == hdr_size)
|
TCRYPT_HDR_HIDDEN_OFFSET) == hdr_size)
|
||||||
r = TCRYPT_init_hdr(cd, hdr, params);
|
r = TCRYPT_init_hdr(cd, hdr, params);
|
||||||
if (r && read_lseek_blockwise(devfd, bs, hdr, hdr_size,
|
if (r && read_lseek_blockwise(devfd, bs, alignment, hdr, hdr_size,
|
||||||
TCRYPT_HDR_HIDDEN_OFFSET_OLD) == hdr_size)
|
TCRYPT_HDR_HIDDEN_OFFSET_OLD) == hdr_size)
|
||||||
r = TCRYPT_init_hdr(cd, hdr, params);
|
r = TCRYPT_init_hdr(cd, hdr, params);
|
||||||
}
|
}
|
||||||
} else if (params->flags & CRYPT_TCRYPT_BACKUP_HEADER) {
|
} else if (params->flags & CRYPT_TCRYPT_BACKUP_HEADER) {
|
||||||
if (read_lseek_blockwise(devfd, bs, hdr, hdr_size,
|
if (read_lseek_blockwise(devfd, bs, alignment, hdr, hdr_size,
|
||||||
TCRYPT_HDR_OFFSET_BCK) == hdr_size)
|
TCRYPT_HDR_OFFSET_BCK) == hdr_size)
|
||||||
r = TCRYPT_init_hdr(cd, hdr, params);
|
r = TCRYPT_init_hdr(cd, hdr, params);
|
||||||
} else if (read_blockwise(devfd, bs, hdr, hdr_size) == hdr_size)
|
} else if (read_blockwise(devfd, bs, alignment, hdr, hdr_size) == hdr_size)
|
||||||
r = TCRYPT_init_hdr(cd, hdr, params);
|
r = TCRYPT_init_hdr(cd, hdr, params);
|
||||||
|
|
||||||
close(devfd);
|
close(devfd);
|
||||||
|
|||||||
38
lib/utils.c
38
lib/utils.c
@@ -36,18 +36,6 @@ unsigned crypt_getpagesize(void)
|
|||||||
return r < 0 ? DEFAULT_MEM_ALIGNMENT : r;
|
return r < 0 ? DEFAULT_MEM_ALIGNMENT : r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t get_alignment(int fd)
|
|
||||||
{
|
|
||||||
long alignment = DEFAULT_MEM_ALIGNMENT;
|
|
||||||
|
|
||||||
#ifdef _PC_REC_XFER_ALIGN
|
|
||||||
alignment = fpathconf(fd, _PC_REC_XFER_ALIGN);
|
|
||||||
if (alignment < 0)
|
|
||||||
alignment = DEFAULT_MEM_ALIGNMENT;
|
|
||||||
#endif
|
|
||||||
return (size_t)alignment;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t read_buffer(int fd, void *buf, size_t count)
|
ssize_t read_buffer(int fd, void *buf, size_t count)
|
||||||
{
|
{
|
||||||
size_t read_size = 0;
|
size_t read_size = 0;
|
||||||
@@ -94,19 +82,18 @@ ssize_t write_buffer(int fd, const void *buf, size_t count)
|
|||||||
return (ssize_t)write_size;
|
return (ssize_t)write_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t write_blockwise(int fd, int bsize, void *orig_buf, size_t count)
|
ssize_t write_blockwise(int fd, int bsize, size_t alignment, void *orig_buf, size_t count)
|
||||||
{
|
{
|
||||||
void *hangover_buf = NULL, *buf = NULL;
|
void *hangover_buf = NULL, *buf = NULL;
|
||||||
int r;
|
int r;
|
||||||
size_t alignment, hangover, solid;
|
size_t hangover, solid;
|
||||||
ssize_t ret = -1;
|
ssize_t ret = -1;
|
||||||
|
|
||||||
if (fd == -1 || !orig_buf || bsize <= 0)
|
if (fd == -1 || !orig_buf || bsize <= 0 || !alignment)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
hangover = count % bsize;
|
hangover = count % bsize;
|
||||||
solid = count - hangover;
|
solid = count - hangover;
|
||||||
alignment = get_alignment(fd);
|
|
||||||
|
|
||||||
if ((size_t)orig_buf & (alignment - 1)) {
|
if ((size_t)orig_buf & (alignment - 1)) {
|
||||||
if (posix_memalign(&buf, alignment, count))
|
if (posix_memalign(&buf, alignment, count))
|
||||||
@@ -149,19 +136,18 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t read_blockwise(int fd, int bsize, void *orig_buf, size_t count)
|
ssize_t read_blockwise(int fd, int bsize, size_t alignment, void *orig_buf, size_t count)
|
||||||
{
|
{
|
||||||
void *hangover_buf = NULL, *buf = NULL;
|
void *hangover_buf = NULL, *buf = NULL;
|
||||||
int r;
|
int r;
|
||||||
size_t alignment, hangover, solid;
|
size_t hangover, solid;
|
||||||
ssize_t ret = -1;
|
ssize_t ret = -1;
|
||||||
|
|
||||||
if (fd == -1 || !orig_buf || bsize <= 0)
|
if (fd == -1 || !orig_buf || bsize <= 0 || !alignment)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
hangover = count % bsize;
|
hangover = count % bsize;
|
||||||
solid = count - hangover;
|
solid = count - hangover;
|
||||||
alignment = get_alignment(fd);
|
|
||||||
|
|
||||||
if ((size_t)orig_buf & (alignment - 1)) {
|
if ((size_t)orig_buf & (alignment - 1)) {
|
||||||
if (posix_memalign(&buf, alignment, count))
|
if (posix_memalign(&buf, alignment, count))
|
||||||
@@ -198,7 +184,7 @@ out:
|
|||||||
* is implicitly included in the read/write offset, which can not be set to non-aligned
|
* is implicitly included in the read/write offset, which can not be set to non-aligned
|
||||||
* boundaries. Hence, we combine llseek with write.
|
* boundaries. Hence, we combine llseek with write.
|
||||||
*/
|
*/
|
||||||
ssize_t write_lseek_blockwise(int fd, int bsize, void *buf, size_t count, off_t offset)
|
ssize_t write_lseek_blockwise(int fd, int bsize, size_t alignment, void *buf, size_t count, off_t offset)
|
||||||
{
|
{
|
||||||
void *frontPadBuf = NULL;
|
void *frontPadBuf = NULL;
|
||||||
int r, frontHang;
|
int r, frontHang;
|
||||||
@@ -220,7 +206,7 @@ ssize_t write_lseek_blockwise(int fd, int bsize, void *buf, size_t count, off_t
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (frontHang) {
|
if (frontHang) {
|
||||||
if (posix_memalign(&frontPadBuf, get_alignment(fd), bsize))
|
if (posix_memalign(&frontPadBuf, alignment, bsize))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
r = read_buffer(fd, frontPadBuf, bsize);
|
r = read_buffer(fd, frontPadBuf, bsize);
|
||||||
@@ -244,7 +230,7 @@ ssize_t write_lseek_blockwise(int fd, int bsize, void *buf, size_t count, off_t
|
|||||||
count -= innerCount;
|
count -= innerCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = count ? write_blockwise(fd, bsize, buf, count) : 0;
|
ret = count ? write_blockwise(fd, bsize, alignment, buf, count) : 0;
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
ret += innerCount;
|
ret += innerCount;
|
||||||
out:
|
out:
|
||||||
@@ -252,7 +238,7 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t read_lseek_blockwise(int fd, int bsize, void *buf, size_t count, off_t offset)
|
ssize_t read_lseek_blockwise(int fd, int bsize, size_t alignment, void *buf, size_t count, off_t offset)
|
||||||
{
|
{
|
||||||
void *frontPadBuf = NULL;
|
void *frontPadBuf = NULL;
|
||||||
int r, frontHang;
|
int r, frontHang;
|
||||||
@@ -274,7 +260,7 @@ ssize_t read_lseek_blockwise(int fd, int bsize, void *buf, size_t count, off_t o
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (frontHang) {
|
if (frontHang) {
|
||||||
if (posix_memalign(&frontPadBuf, get_alignment(fd), bsize))
|
if (posix_memalign(&frontPadBuf, alignment, bsize))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
r = read_buffer(fd, frontPadBuf, bsize);
|
r = read_buffer(fd, frontPadBuf, bsize);
|
||||||
@@ -291,7 +277,7 @@ ssize_t read_lseek_blockwise(int fd, int bsize, void *buf, size_t count, off_t o
|
|||||||
count -= innerCount;
|
count -= innerCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = read_blockwise(fd, bsize, buf, count);
|
ret = read_blockwise(fd, bsize, alignment, buf, count);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
ret += innerCount;
|
ret += innerCount;
|
||||||
out:
|
out:
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ struct device {
|
|||||||
|
|
||||||
int o_direct:1;
|
int o_direct:1;
|
||||||
int init_done:1;
|
int init_done:1;
|
||||||
|
|
||||||
|
/* cached values */
|
||||||
|
size_t alignment;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int device_block_size_fd(int fd, size_t *min_size)
|
static int device_block_size_fd(int fd, size_t *min_size)
|
||||||
@@ -79,15 +82,28 @@ static int device_block_size_fd(int fd, size_t *min_size)
|
|||||||
return bsize;
|
return bsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t device_alignment_fd(int devfd)
|
||||||
|
{
|
||||||
|
long alignment = DEFAULT_MEM_ALIGNMENT;
|
||||||
|
|
||||||
|
#ifdef _PC_REC_XFER_ALIGN
|
||||||
|
alignment = fpathconf(devfd, _PC_REC_XFER_ALIGN);
|
||||||
|
if (alignment < 0)
|
||||||
|
alignment = DEFAULT_MEM_ALIGNMENT;
|
||||||
|
#endif
|
||||||
|
return (size_t)alignment;
|
||||||
|
}
|
||||||
|
|
||||||
static int device_read_test(int devfd)
|
static int device_read_test(int devfd)
|
||||||
{
|
{
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
int blocksize, r = -EIO;
|
int blocksize, r = -EIO;
|
||||||
size_t minsize = 0;
|
size_t minsize = 0, alignment;
|
||||||
|
|
||||||
blocksize = device_block_size_fd(devfd, &minsize);
|
blocksize = device_block_size_fd(devfd, &minsize);
|
||||||
|
alignment = device_alignment_fd(devfd);
|
||||||
|
|
||||||
if (blocksize < 0)
|
if (blocksize <= 0 || !alignment)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (minsize == 0)
|
if (minsize == 0)
|
||||||
@@ -96,7 +112,7 @@ static int device_read_test(int devfd)
|
|||||||
if (minsize > sizeof(buffer))
|
if (minsize > sizeof(buffer))
|
||||||
minsize = sizeof(buffer);
|
minsize = sizeof(buffer);
|
||||||
|
|
||||||
if (read_blockwise(devfd, blocksize, buffer, minsize) == (ssize_t)minsize)
|
if (read_blockwise(devfd, blocksize, alignment, buffer, minsize) == (ssize_t)minsize)
|
||||||
r = 0;
|
r = 0;
|
||||||
|
|
||||||
crypt_memzero(buffer, sizeof(buffer));
|
crypt_memzero(buffer, sizeof(buffer));
|
||||||
@@ -148,6 +164,8 @@ static int device_ready(struct device *device, int check_directio)
|
|||||||
else if (!S_ISBLK(st.st_mode))
|
else if (!S_ISBLK(st.st_mode))
|
||||||
r = S_ISREG(st.st_mode) ? -ENOTBLK : -EINVAL;
|
r = S_ISREG(st.st_mode) ? -ENOTBLK : -EINVAL;
|
||||||
|
|
||||||
|
device->alignment = device_alignment_fd(devfd);
|
||||||
|
|
||||||
close(devfd);
|
close(devfd);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -566,3 +584,18 @@ int device_is_rotational(struct device *device)
|
|||||||
|
|
||||||
return crypt_dev_is_rotational(major(st.st_rdev), minor(st.st_rdev));
|
return crypt_dev_is_rotational(major(st.st_rdev), minor(st.st_rdev));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t device_alignment(struct device *device)
|
||||||
|
{
|
||||||
|
int devfd;
|
||||||
|
|
||||||
|
if (!device->alignment) {
|
||||||
|
devfd = open(device_path(device), O_RDONLY);
|
||||||
|
if (devfd != -1) {
|
||||||
|
device->alignment = device_alignment_fd(devfd);
|
||||||
|
close(devfd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return device->alignment;
|
||||||
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ static void wipeSpecial(char *buffer, size_t buffer_size, unsigned int turn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int crypt_wipe_special(int fd, int bsize, char *buffer,
|
static int crypt_wipe_special(int fd, int bsize, size_t alignment, char *buffer,
|
||||||
uint64_t offset, size_t size)
|
uint64_t offset, size_t size)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
@@ -74,7 +74,8 @@ static int crypt_wipe_special(int fd, int bsize, char *buffer,
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
written = write_lseek_blockwise(fd, bsize, buffer, size, offset);
|
written = write_lseek_blockwise(fd, bsize, alignment,
|
||||||
|
buffer, size, offset);
|
||||||
if (written < 0 || written != (ssize_t)size)
|
if (written < 0 || written != (ssize_t)size)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
@@ -83,7 +84,7 @@ static int crypt_wipe_special(int fd, int bsize, char *buffer,
|
|||||||
if (crypt_random_get(NULL, buffer, size, CRYPT_RND_NORMAL) < 0)
|
if (crypt_random_get(NULL, buffer, size, CRYPT_RND_NORMAL) < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
written = write_lseek_blockwise(fd, bsize, buffer, size, offset);
|
written = write_lseek_blockwise(fd, bsize, alignment, buffer, size, offset);
|
||||||
if (written < 0 || written != (ssize_t)size)
|
if (written < 0 || written != (ssize_t)size)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
@@ -91,13 +92,14 @@ static int crypt_wipe_special(int fd, int bsize, char *buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int wipe_block(int devfd, crypt_wipe_pattern pattern, char *sf,
|
static int wipe_block(int devfd, crypt_wipe_pattern pattern, char *sf,
|
||||||
size_t device_block_size, size_t wipe_block_size,
|
size_t device_block_size, size_t alignment,
|
||||||
uint64_t offset, bool *need_block_init)
|
size_t wipe_block_size, uint64_t offset, bool *need_block_init)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (pattern == CRYPT_WIPE_SPECIAL)
|
if (pattern == CRYPT_WIPE_SPECIAL)
|
||||||
return crypt_wipe_special(devfd, device_block_size, sf, offset, wipe_block_size);
|
return crypt_wipe_special(devfd, device_block_size, alignment,
|
||||||
|
sf, offset, wipe_block_size);
|
||||||
|
|
||||||
if (*need_block_init) {
|
if (*need_block_init) {
|
||||||
if (pattern == CRYPT_WIPE_ZERO) {
|
if (pattern == CRYPT_WIPE_ZERO) {
|
||||||
@@ -118,7 +120,8 @@ static int wipe_block(int devfd, crypt_wipe_pattern pattern, char *sf,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (write_blockwise(devfd, device_block_size, sf, wipe_block_size) == (ssize_t)wipe_block_size)
|
if (write_blockwise(devfd, device_block_size, alignment, sf,
|
||||||
|
wipe_block_size) == (ssize_t)wipe_block_size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
@@ -134,13 +137,15 @@ int crypt_wipe_device(struct crypt_device *cd,
|
|||||||
void *usrptr)
|
void *usrptr)
|
||||||
{
|
{
|
||||||
int r, devfd = -1, bsize;
|
int r, devfd = -1, bsize;
|
||||||
|
size_t alignment;
|
||||||
char *sf = NULL;
|
char *sf = NULL;
|
||||||
uint64_t dev_size;
|
uint64_t dev_size;
|
||||||
bool need_block_init = true;
|
bool need_block_init = true;
|
||||||
|
|
||||||
/* Note: LUKS1 calls it with wipe_block not aligned to multiple of bsize */
|
/* Note: LUKS1 calls it with wipe_block not aligned to multiple of bsize */
|
||||||
bsize = device_block_size(device);
|
bsize = device_block_size(device);
|
||||||
if ((bsize <= 0) || (wipe_block_size < (size_t)bsize))
|
alignment = device_alignment(device);
|
||||||
|
if ((bsize <= 0) || !alignment || (wipe_block_size < (size_t)bsize))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* Everything must be aligned to SECTOR_SIZE */
|
/* Everything must be aligned to SECTOR_SIZE */
|
||||||
@@ -163,7 +168,7 @@ int crypt_wipe_device(struct crypt_device *cd,
|
|||||||
dev_size = offset + length;
|
dev_size = offset + length;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = posix_memalign((void **)&sf, crypt_getpagesize(), wipe_block_size);
|
r = posix_memalign((void **)&sf, alignment, wipe_block_size);
|
||||||
if (r)
|
if (r)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@@ -189,7 +194,8 @@ int crypt_wipe_device(struct crypt_device *cd,
|
|||||||
|
|
||||||
//log_dbg("Wipe %012" PRIu64 "-%012" PRIu64 " bytes", offset, offset + wipe_block_size);
|
//log_dbg("Wipe %012" PRIu64 "-%012" PRIu64 " bytes", offset, offset + wipe_block_size);
|
||||||
|
|
||||||
r = wipe_block(devfd, pattern, sf, bsize, wipe_block_size, offset, &need_block_init);
|
r = wipe_block(devfd, pattern, sf, bsize, alignment,
|
||||||
|
wipe_block_size, offset, &need_block_init);
|
||||||
if (r) {
|
if (r) {
|
||||||
log_err(cd, "Device wipe error, offset %" PRIu64 ".\n", offset);
|
log_err(cd, "Device wipe error, offset %" PRIu64 ".\n", offset);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ int VERITY_read_sb(struct crypt_device *cd,
|
|||||||
struct crypt_params_verity *params)
|
struct crypt_params_verity *params)
|
||||||
{
|
{
|
||||||
struct device *device = crypt_metadata_device(cd);
|
struct device *device = crypt_metadata_device(cd);
|
||||||
int bsize = device_block_size(device);
|
|
||||||
struct verity_sb sb = {};
|
struct verity_sb sb = {};
|
||||||
ssize_t hdr_size = sizeof(struct verity_sb);
|
ssize_t hdr_size = sizeof(struct verity_sb);
|
||||||
int devfd = 0, sb_version;
|
int devfd = 0, sb_version;
|
||||||
@@ -84,7 +83,8 @@ int VERITY_read_sb(struct crypt_device *cd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lseek(devfd, sb_offset, SEEK_SET) < 0 ||
|
if (lseek(devfd, sb_offset, SEEK_SET) < 0 ||
|
||||||
read_blockwise(devfd, bsize, &sb, hdr_size) < hdr_size) {
|
read_blockwise(devfd, device_block_size(device), device_alignment(device),
|
||||||
|
&sb, hdr_size) < hdr_size) {
|
||||||
close(devfd);
|
close(devfd);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
@@ -156,7 +156,6 @@ int VERITY_write_sb(struct crypt_device *cd,
|
|||||||
struct crypt_params_verity *params)
|
struct crypt_params_verity *params)
|
||||||
{
|
{
|
||||||
struct device *device = crypt_metadata_device(cd);
|
struct device *device = crypt_metadata_device(cd);
|
||||||
int bsize = device_block_size(device);
|
|
||||||
struct verity_sb sb = {};
|
struct verity_sb sb = {};
|
||||||
ssize_t hdr_size = sizeof(struct verity_sb);
|
ssize_t hdr_size = sizeof(struct verity_sb);
|
||||||
char *algorithm;
|
char *algorithm;
|
||||||
@@ -197,7 +196,8 @@ int VERITY_write_sb(struct crypt_device *cd,
|
|||||||
memcpy(sb.salt, params->salt, params->salt_size);
|
memcpy(sb.salt, params->salt, params->salt_size);
|
||||||
memcpy(sb.uuid, uuid, sizeof(sb.uuid));
|
memcpy(sb.uuid, uuid, sizeof(sb.uuid));
|
||||||
|
|
||||||
r = write_lseek_blockwise(devfd, bsize, (char*)&sb, hdr_size, sb_offset) < hdr_size ? -EIO : 0;
|
r = write_lseek_blockwise(devfd, device_block_size(device), device_alignment(device),
|
||||||
|
(char*)&sb, hdr_size, sb_offset) < hdr_size ? -EIO : 0;
|
||||||
if (r)
|
if (r)
|
||||||
log_err(cd, _("Error during update of verity header on device %s.\n"),
|
log_err(cd, _("Error during update of verity header on device %s.\n"),
|
||||||
device_path(device));
|
device_path(device));
|
||||||
|
|||||||
Reference in New Issue
Block a user