diff --git a/lib/internal.h b/lib/internal.h index c7d64bac..ca577acf 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -72,7 +72,7 @@ void device_topology_alignment(struct device *device, unsigned long *required_alignment, /* bytes */ unsigned long *alignment_offset, /* bytes */ unsigned long default_alignment); -int device_block_size(struct device *device); +size_t device_block_size(struct device *device); int device_read_ahead(struct device *device, uint32_t *read_ahead); int device_size(struct device *device, uint64_t *size); int device_open(struct device *device, int flags); @@ -88,7 +88,7 @@ int device_block_adjust(struct crypt_device *cd, uint64_t device_offset, uint64_t *size, uint32_t *flags); -size_t size_round_up(size_t size, unsigned int block); +size_t size_round_up(size_t size, size_t block); /* Receive backend devices from context helpers */ struct device *crypt_metadata_device(struct crypt_device *cd); @@ -105,12 +105,12 @@ uint64_t crypt_dev_partition_offset(const char *dev_path); 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 write_blockwise(int fd, int bsize, size_t alignment, void *orig_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, size_t alignment, 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); +ssize_t write_blockwise(int fd, size_t bsize, size_t alignment, void *orig_buf, size_t count); +ssize_t read_blockwise(int fd, size_t bsize, size_t alignment, void *buf, size_t count); +ssize_t write_lseek_blockwise(int fd, size_t bsize, size_t alignment, void *buf, size_t count, off_t offset); +ssize_t read_lseek_blockwise(int fd, size_t bsize, size_t alignment, void *buf, size_t count, off_t offset); -unsigned crypt_getpagesize(void); +size_t crypt_getpagesize(void); int init_crypto(struct crypt_device *ctx); void logger(struct crypt_device *cd, int class, const char *file, int line, const char *format, ...) __attribute__ ((format (printf, 5, 6))); diff --git a/lib/luks1/keyencryption.c b/lib/luks1/keyencryption.c index 4f5dff3d..587eae14 100644 --- a/lib/luks1/keyencryption.c +++ b/lib/luks1/keyencryption.c @@ -46,7 +46,7 @@ static int LUKS_endec_template(char *src, size_t srcLength, const char *cipher, const char *cipher_mode, struct volume_key *vk, unsigned int sector, - ssize_t (*func)(int, int, size_t, void *, size_t), + ssize_t (*func)(int, size_t, size_t, void *, size_t), int mode, struct crypt_device *ctx) { @@ -64,14 +64,14 @@ static int LUKS_endec_template(char *src, size_t srcLength, .iv_offset = 0, } }; - int r, bsize, devfd = -1; - size_t alignment; + int r, devfd = -1; + size_t bsize, alignment; log_dbg("Using dmcrypt to access keyslot area."); bsize = device_block_size(dmd.data_device); alignment = device_alignment(dmd.data_device); - if (bsize <= 0 || !alignment) + if (!bsize || !alignment) return -EINVAL; dmd.size = size_round_up(srcLength, bsize) / SECTOR_SIZE; @@ -138,8 +138,7 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength, struct device *device = crypt_metadata_device(ctx); struct crypt_storage *s; - int devfd = -1, bsize, r = 0; - size_t alignment; + int devfd = -1, r = 0; /* Only whole sector writes supported */ if (srcLength % SECTOR_SIZE) @@ -174,17 +173,13 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength, r = -EIO; /* Write buffer to device */ - bsize = device_block_size(device); - alignment = device_alignment(device); - if (bsize <= 0 || !alignment) - goto out; - devfd = device_open(device, O_RDWR); if (devfd < 0) goto out; if (lseek(devfd, sector * SECTOR_SIZE, SEEK_SET) == -1 || - write_blockwise(devfd, bsize, alignment, src, srcLength) == -1) + write_blockwise(devfd, device_block_size(device), + device_alignment(device), src, srcLength) == -1) goto out; r = 0; @@ -206,8 +201,7 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength, { struct device *device = crypt_metadata_device(ctx); struct crypt_storage *s; - int devfd = -1, bsize, r = 0; - size_t alignment; + int devfd = -1, r = 0; /* Only whole sector reads supported */ if (dstLength % SECTOR_SIZE) @@ -235,17 +229,13 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength, r = -EIO; /* Read buffer from device */ - bsize = device_block_size(device); - alignment = device_alignment(device); - if (bsize <= 0 || !alignment) - goto bad; - devfd = device_open(device, O_RDONLY); if (devfd < 0) goto bad; if (lseek(devfd, sector * SECTOR_SIZE, SEEK_SET) == -1 || - read_blockwise(devfd, bsize, alignment, dst, dstLength) == -1) + read_blockwise(devfd, device_block_size(device), + device_alignment(device), dst, dstLength) == -1) goto bad; close(devfd); diff --git a/lib/luks1/keymanage.c b/lib/luks1/keymanage.c index b0deb778..cbb65438 100644 --- a/lib/luks1/keymanage.c +++ b/lib/luks1/keymanage.c @@ -153,8 +153,8 @@ int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx) struct device *device = crypt_metadata_device(ctx); struct luks_phdr hdr; int r = 0, devfd = -1; - ssize_t hdr_size; - ssize_t buffer_size; + size_t hdr_size; + size_t buffer_size; char *buffer = NULL; r = LUKS_read_phdr(&hdr, 1, 0, ctx); @@ -183,7 +183,7 @@ int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx) } if (read_blockwise(devfd, device_block_size(device), device_alignment(device), - buffer, hdr_size) < hdr_size) { + buffer, hdr_size) < (ssize_t)hdr_size) { r = -EIO; goto out; } @@ -202,7 +202,7 @@ int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx) r = -EINVAL; goto out; } - if (write_buffer(devfd, buffer, buffer_size) < buffer_size) { + if (write_buffer(devfd, buffer, buffer_size) < (ssize_t)buffer_size) { log_err(ctx, _("Cannot write header backup file %s.\n"), backup_file); r = -EIO; goto out; diff --git a/lib/tcrypt/tcrypt.c b/lib/tcrypt/tcrypt.c index 56b7cbeb..b181989c 100644 --- a/lib/tcrypt/tcrypt.c +++ b/lib/tcrypt/tcrypt.c @@ -600,19 +600,13 @@ int TCRYPT_read_phdr(struct crypt_device *cd, struct device *base_device, *device = crypt_metadata_device(cd); ssize_t hdr_size = sizeof(struct tcrypt_phdr); char *base_device_path; - int devfd = 0, r, bs; - size_t alignment; + int devfd = 0, r; assert(sizeof(struct tcrypt_phdr) == 512); log_dbg("Reading TCRYPT header of size %zu bytes from device %s.", hdr_size, device_path(device)); - bs = device_block_size(device); - alignment = device_alignment(device); - if (bs < 0) - return bs; - if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER && crypt_dev_is_partition(device_path(device))) { base_device_path = crypt_get_base_device(device_path(device)); @@ -637,28 +631,34 @@ int TCRYPT_read_phdr(struct crypt_device *cd, r = -EIO; if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER) { - if (read_lseek_blockwise(devfd, bs, alignment, hdr, hdr_size, + if (read_lseek_blockwise(devfd, device_block_size(device), + device_alignment(device), hdr, hdr_size, TCRYPT_HDR_SYSTEM_OFFSET) == hdr_size) { r = TCRYPT_init_hdr(cd, hdr, params); } } else if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER) { if (params->flags & CRYPT_TCRYPT_BACKUP_HEADER) { - if (read_lseek_blockwise(devfd, bs, alignment, hdr, hdr_size, + if (read_lseek_blockwise(devfd, device_block_size(device), + device_alignment(device), hdr, hdr_size, TCRYPT_HDR_HIDDEN_OFFSET_BCK) == hdr_size) r = TCRYPT_init_hdr(cd, hdr, params); } else { - if (read_lseek_blockwise(devfd, bs, alignment, hdr, hdr_size, + if (read_lseek_blockwise(devfd, device_block_size(device), + device_alignment(device), hdr, hdr_size, TCRYPT_HDR_HIDDEN_OFFSET) == hdr_size) r = TCRYPT_init_hdr(cd, hdr, params); - if (r && read_lseek_blockwise(devfd, bs, alignment, hdr, hdr_size, + if (r && read_lseek_blockwise(devfd, device_block_size(device), + device_alignment(device), hdr, hdr_size, TCRYPT_HDR_HIDDEN_OFFSET_OLD) == hdr_size) r = TCRYPT_init_hdr(cd, hdr, params); } } else if (params->flags & CRYPT_TCRYPT_BACKUP_HEADER) { - if (read_lseek_blockwise(devfd, bs, alignment, hdr, hdr_size, + if (read_lseek_blockwise(devfd, device_block_size(device), + device_alignment(device), hdr, hdr_size, TCRYPT_HDR_OFFSET_BCK) == hdr_size) r = TCRYPT_init_hdr(cd, hdr, params); - } else if (read_blockwise(devfd, bs, alignment, hdr, hdr_size) == hdr_size) + } else if (read_blockwise(devfd, device_block_size(device), + device_alignment(device), hdr, hdr_size) == hdr_size) r = TCRYPT_init_hdr(cd, hdr, params); close(devfd); diff --git a/lib/utils.c b/lib/utils.c index e4b69c8e..4bc962fc 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -30,10 +30,10 @@ #include "internal.h" -unsigned crypt_getpagesize(void) +size_t crypt_getpagesize(void) { long r = sysconf(_SC_PAGESIZE); - return r < 0 ? DEFAULT_MEM_ALIGNMENT : r; + return r <= 0 ? DEFAULT_MEM_ALIGNMENT : (size_t)r; } ssize_t read_buffer(int fd, void *buf, size_t count) @@ -82,14 +82,15 @@ ssize_t write_buffer(int fd, const void *buf, size_t count) return (ssize_t)write_size; } -ssize_t write_blockwise(int fd, int bsize, size_t alignment, void *orig_buf, size_t count) +ssize_t write_blockwise(int fd, size_t bsize, size_t alignment, + void *orig_buf, size_t count) { void *hangover_buf = NULL, *buf = NULL; int r; size_t hangover, solid; ssize_t ret = -1; - if (fd == -1 || !orig_buf || bsize <= 0 || !alignment) + if (fd == -1 || !orig_buf || !bsize || !alignment) return -1; hangover = count % bsize; @@ -116,10 +117,10 @@ ssize_t write_blockwise(int fd, int bsize, size_t alignment, void *orig_buf, siz if (r < 0 || r < (ssize_t)hangover) goto out; - if (r < bsize) + if (r < (ssize_t)bsize) bsize = r; - if (lseek(fd, -bsize, SEEK_CUR) < 0) + if (lseek(fd, -(off_t)bsize, SEEK_CUR) < 0) goto out; memcpy(hangover_buf, (char*)buf + solid, hangover); @@ -136,14 +137,15 @@ out: return ret; } -ssize_t read_blockwise(int fd, int bsize, size_t alignment, void *orig_buf, size_t count) +ssize_t read_blockwise(int fd, size_t bsize, size_t alignment, + void *orig_buf, size_t count) { void *hangover_buf = NULL, *buf = NULL; int r; size_t hangover, solid; ssize_t ret = -1; - if (fd == -1 || !orig_buf || bsize <= 0 || !alignment) + if (fd == -1 || !orig_buf || !bsize || !alignment) return -1; hangover = count % bsize; @@ -184,14 +186,15 @@ out: * is implicitly included in the read/write offset, which can not be set to non-aligned * boundaries. Hence, we combine llseek with write. */ -ssize_t write_lseek_blockwise(int fd, int bsize, size_t alignment, void *buf, size_t count, off_t offset) +ssize_t write_lseek_blockwise(int fd, size_t bsize, size_t alignment, + void *buf, size_t count, off_t offset) { void *frontPadBuf = NULL; - int r, frontHang; - size_t innerCount = 0; + int r; + size_t frontHang, innerCount = 0; ssize_t ret = -1; - if (fd == -1 || !buf || bsize <= 0) + if (fd == -1 || !buf || !bsize || !alignment) return -1; if (offset < 0) @@ -210,7 +213,7 @@ ssize_t write_lseek_blockwise(int fd, int bsize, size_t alignment, void *buf, si return -1; r = read_buffer(fd, frontPadBuf, bsize); - if (r < 0 || r != bsize) + if (r < 0 || r != (ssize_t)bsize) goto out; innerCount = bsize - frontHang; @@ -223,7 +226,7 @@ ssize_t write_lseek_blockwise(int fd, int bsize, size_t alignment, void *buf, si goto out; r = write_buffer(fd, frontPadBuf, bsize); - if (r < 0 || r != bsize) + if (r < 0 || r != (ssize_t)bsize) goto out; buf = (char*)buf + innerCount; @@ -238,11 +241,12 @@ out: return ret; } -ssize_t read_lseek_blockwise(int fd, int bsize, size_t alignment, void *buf, size_t count, off_t offset) +ssize_t read_lseek_blockwise(int fd, size_t bsize, size_t alignment, + void *buf, size_t count, off_t offset) { void *frontPadBuf = NULL; - int r, frontHang; - size_t innerCount = 0; + int r; + size_t frontHang, innerCount = 0; ssize_t ret = -1; if (fd == -1 || !buf || bsize <= 0) @@ -264,7 +268,7 @@ ssize_t read_lseek_blockwise(int fd, int bsize, size_t alignment, void *buf, siz return -1; r = read_buffer(fd, frontPadBuf, bsize); - if (r < 0 || r != bsize) + if (r < 0 || r != (ssize_t)bsize) goto out; innerCount = bsize - frontHang; diff --git a/lib/utils_device.c b/lib/utils_device.c index 6994dc72..06e375f3 100644 --- a/lib/utils_device.c +++ b/lib/utils_device.c @@ -46,31 +46,28 @@ struct device { /* cached values */ size_t alignment; + size_t block_size; }; -static int device_block_size_fd(int fd, size_t *min_size) +static size_t device_block_size_fd(int fd, size_t *min_size) { struct stat st; - int bsize = 0, r = -EINVAL; + size_t bsize; if (fstat(fd, &st) < 0) - return -EINVAL; + return 0; - if (S_ISREG(st.st_mode)) { - r = (int)crypt_getpagesize(); - bsize = r; - } - else if (ioctl(fd, BLKSSZGET, &bsize) >= 0) - r = bsize; - else - r = -EINVAL; + if (S_ISREG(st.st_mode)) + bsize = crypt_getpagesize(); + else if (ioctl(fd, BLKSSZGET, &bsize) < 0) + return 0; - if (r < 0 || !min_size) - return r; + if (!min_size) + return bsize; if (S_ISREG(st.st_mode)) { /* file can be empty as well */ - if (st.st_size > bsize) + if (st.st_size > (ssize_t)bsize) *min_size = bsize; else *min_size = st.st_size; @@ -97,13 +94,13 @@ static size_t device_alignment_fd(int devfd) static int device_read_test(int devfd) { char buffer[512]; - int blocksize, r = -EIO; - size_t minsize = 0, alignment; + int r = -EIO; + size_t minsize = 0, blocksize, alignment; blocksize = device_block_size_fd(devfd, &minsize); alignment = device_alignment_fd(devfd); - if (blocksize <= 0 || !alignment) + if (!blocksize || !alignment) return -EINVAL; if (minsize == 0) @@ -165,6 +162,7 @@ static int device_ready(struct device *device, int check_directio) r = S_ISREG(st.st_mode) ? -ENOTBLK : -EINVAL; device->alignment = device_alignment_fd(devfd); + device->block_size= device_block_size_fd(devfd, NULL); close(devfd); return r; @@ -317,27 +315,30 @@ out: (void)close(fd); } -int device_block_size(struct device *device) +size_t device_block_size(struct device *device) { - int fd, r = -EINVAL; + int fd; if (!device) return 0; + if (device->block_size) + return device->block_size; + if (device->file_path) - return (int)crypt_getpagesize(); + device->block_size = crypt_getpagesize(); + else { + fd = open(device->path, O_RDONLY); + if (fd >= 0) { + device->block_size = device_block_size_fd(fd, NULL); + close(fd); + } + } - fd = open(device->path, O_RDONLY); - if(fd < 0) - return -EINVAL; - - r = device_block_size_fd(fd, NULL); - - if (r <= 0) + if (!device->block_size) log_dbg("Cannot get block size for device %s.", device_path(device)); - close(fd); - return r; + return device->block_size; } int device_read_ahead(struct device *device, uint32_t *read_ahead) @@ -546,7 +547,7 @@ int device_block_adjust(struct crypt_device *cd, return 0; } -size_t size_round_up(size_t size, unsigned int block) +size_t size_round_up(size_t size, size_t block) { size_t s = (size + (block - 1)) / block; return s * block; diff --git a/lib/utils_wipe.c b/lib/utils_wipe.c index a60d7a1d..8e16a477 100644 --- a/lib/utils_wipe.c +++ b/lib/utils_wipe.c @@ -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, size_t alignment, char *buffer, +static int crypt_wipe_special(int fd, size_t bsize, size_t alignment, char *buffer, uint64_t offset, size_t size) { int r; @@ -136,8 +136,8 @@ int crypt_wipe_device(struct crypt_device *cd, int (*progress)(uint64_t size, uint64_t offset, void *usrptr), void *usrptr) { - int r, devfd = -1, bsize; - size_t alignment; + int r, devfd = -1; + size_t bsize, alignment; char *sf = NULL; uint64_t dev_size; bool need_block_init = true; @@ -145,7 +145,7 @@ int crypt_wipe_device(struct crypt_device *cd, /* Note: LUKS1 calls it with wipe_block not aligned to multiple of bsize */ bsize = device_block_size(device); alignment = device_alignment(device); - if ((bsize <= 0) || !alignment || (wipe_block_size < (size_t)bsize)) + if (!bsize || !alignment || (wipe_block_size < bsize)) return -EINVAL; /* Everything must be aligned to SECTOR_SIZE */ diff --git a/lib/verity/verity_hash.c b/lib/verity/verity_hash.c index e34b8961..c20693a3 100644 --- a/lib/verity/verity_hash.c +++ b/lib/verity/verity_hash.c @@ -421,7 +421,7 @@ int VERITY_create(struct crypt_device *cd, char *root_hash, size_t root_hash_size) { - unsigned pgsize = crypt_getpagesize(); + unsigned pgsize = (unsigned)crypt_getpagesize(); if (verity_hdr->salt_size > 256) return -EINVAL;