mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-12 03:10:08 +01:00
Fix access to unaligned hidden TrueCrypt header.
On native 4k-sector device the old hidden header is not aligned with hw sector size and derect-io access with SEEK_END fails. Let's extend blockwise functions to support a negative offset and use the same logic as normal unaligned writes. Fixes problem mentioned in https://gitlab.com/cryptsetup/cryptsetup/merge_requests/18
This commit is contained in:
@@ -627,27 +627,26 @@ 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 (lseek(devfd, TCRYPT_HDR_SYSTEM_OFFSET, SEEK_SET) >= 0 &&
|
if (read_lseek_blockwise(devfd, bs, hdr, hdr_size,
|
||||||
read_blockwise(devfd, bs, hdr, hdr_size) == 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 (lseek(devfd, TCRYPT_HDR_HIDDEN_OFFSET_BCK, SEEK_END) >= 0 &&
|
if (read_lseek_blockwise(devfd, bs, hdr, hdr_size,
|
||||||
read_blockwise(devfd, bs, hdr, hdr_size) == 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 (lseek(devfd, TCRYPT_HDR_HIDDEN_OFFSET, SEEK_SET) >= 0 &&
|
if (read_lseek_blockwise(devfd, bs, hdr, hdr_size,
|
||||||
read_blockwise(devfd, bs, hdr, hdr_size) == hdr_size)
|
TCRYPT_HDR_HIDDEN_OFFSET) == hdr_size)
|
||||||
r = TCRYPT_init_hdr(cd, hdr, params);
|
r = TCRYPT_init_hdr(cd, hdr, params);
|
||||||
if (r &&
|
if (r && read_lseek_blockwise(devfd, bs, hdr, hdr_size,
|
||||||
lseek(devfd, TCRYPT_HDR_HIDDEN_OFFSET_OLD, SEEK_END) >= 0 &&
|
TCRYPT_HDR_HIDDEN_OFFSET_OLD) == hdr_size)
|
||||||
read_blockwise(devfd, bs, hdr, hdr_size) == 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 (lseek(devfd, TCRYPT_HDR_OFFSET_BCK, SEEK_END) >= 0 &&
|
if (read_lseek_blockwise(devfd, bs, hdr, hdr_size,
|
||||||
read_blockwise(devfd, bs, hdr, hdr_size) == 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, hdr, hdr_size) == hdr_size)
|
||||||
r = TCRYPT_init_hdr(cd, hdr, params);
|
r = TCRYPT_init_hdr(cd, hdr, params);
|
||||||
|
|||||||
12
lib/utils.c
12
lib/utils.c
@@ -235,6 +235,12 @@ ssize_t write_lseek_blockwise(int fd, int bsize, void *buf, size_t count, off_t
|
|||||||
if (fd == -1 || !buf || bsize <= 0)
|
if (fd == -1 || !buf || bsize <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (offset < 0)
|
||||||
|
offset = lseek(fd, offset, SEEK_END);
|
||||||
|
|
||||||
|
if (offset < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
frontHang = offset % bsize;
|
frontHang = offset % bsize;
|
||||||
|
|
||||||
if (lseek(fd, offset - frontHang, SEEK_SET) < 0)
|
if (lseek(fd, offset - frontHang, SEEK_SET) < 0)
|
||||||
@@ -287,6 +293,12 @@ ssize_t read_lseek_blockwise(int fd, int bsize, void *buf, size_t count, off_t o
|
|||||||
if (fd == -1 || !buf || bsize <= 0)
|
if (fd == -1 || !buf || bsize <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (offset < 0)
|
||||||
|
offset = lseek(fd, offset, SEEK_END);
|
||||||
|
|
||||||
|
if (offset < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
frontHang = offset % bsize;
|
frontHang = offset % bsize;
|
||||||
|
|
||||||
if (lseek(fd, offset - frontHang, SEEK_SET) < 0)
|
if (lseek(fd, offset - frontHang, SEEK_SET) < 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user