diff --git a/lib/internal.h b/lib/internal.h index 821c115c..71d57096 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -78,6 +78,7 @@ void device_topology_alignment(struct device *device, int 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); enum devcheck { DEV_OK = 0, DEV_EXCL = 1, DEV_SHARED = 2 }; int device_block_adjust(struct crypt_device *cd, diff --git a/lib/luks1/keymanage.c b/lib/luks1/keymanage.c index 164ba4a9..d82c4717 100644 --- a/lib/luks1/keymanage.c +++ b/lib/luks1/keymanage.c @@ -170,7 +170,7 @@ int LUKS_hdr_backup( log_dbg("Storing backup of header (%u bytes) and keyslot area (%u bytes).", sizeof(*hdr), buffer_size - LUKS_ALIGN_KEYSLOTS); - devfd = open(device_path(device), O_RDONLY | O_DIRECT | O_SYNC); + devfd = device_open(device, O_RDONLY); if(devfd == -1) { log_err(ctx, _("Device %s is not a valid LUKS device.\n"), device_path(device)); r = -EINVAL; @@ -284,7 +284,7 @@ int LUKS_hdr_restore( log_dbg("Storing backup of header (%u bytes) and keyslot area (%u bytes) to device %s.", sizeof(*hdr), buffer_size - LUKS_ALIGN_KEYSLOTS, device_path(device)); - devfd = open(device_path(device), O_RDWR | O_DIRECT | O_SYNC); + devfd = device_open(device, O_RDWR); if (devfd == -1) { if (errno == EACCES) log_err(ctx, _("Cannot write to device %s, permission denied.\n"), @@ -517,7 +517,7 @@ int LUKS_read_phdr(struct luks_phdr *hdr, log_dbg("Reading LUKS header of size %d from device %s", hdr_size, device_path(device)); - devfd = open(device_path(device), O_RDONLY | O_DIRECT | O_SYNC); + devfd = device_open(device, O_RDONLY); if (devfd == -1) { log_err(ctx, _("Cannot open device %s.\n"), device_path(device)); return -EINVAL; @@ -553,7 +553,7 @@ int LUKS_write_phdr(struct luks_phdr *hdr, if (r) return r; - devfd = open(device_path(device), O_RDWR | O_DIRECT | O_SYNC); + devfd = device_open(device, O_RDWR); if(-1 == devfd) { if (errno == EACCES) log_err(ctx, _("Cannot write to device %s, permission denied.\n"), diff --git a/lib/tcrypt/tcrypt.c b/lib/tcrypt/tcrypt.c index 8fe461e9..11b712f2 100644 --- a/lib/tcrypt/tcrypt.c +++ b/lib/tcrypt/tcrypt.c @@ -562,7 +562,7 @@ int TCRYPT_read_phdr(struct crypt_device *cd, if (bs < 0) return bs; - devfd = open(device_path(device), O_RDONLY | O_DIRECT); + devfd = device_open(device, O_RDONLY); if (devfd == -1) { log_err(cd, _("Cannot open device %s.\n"), device_path(device)); return -EINVAL; diff --git a/lib/utils_device.c b/lib/utils_device.c index 44282a6e..9b53f1da 100644 --- a/lib/utils_device.c +++ b/lib/utils_device.c @@ -47,7 +47,7 @@ static int device_ready(const char *device) struct stat st; log_dbg("Trying to open and read device %s.", device); - devfd = open(device, O_RDONLY | O_DIRECT | O_SYNC); + devfd = open(device, O_RDONLY); if (devfd < 0) { log_err(NULL, _("Device %s doesn't exist or access denied.\n"), device); return -EINVAL; @@ -61,6 +61,20 @@ static int device_ready(const char *device) return r; } +int device_open(struct device *device, int flags) +{ + int devfd; + + devfd = open(device_path(device), flags | O_DIRECT | O_SYNC); + if (devfd < 0 && errno == EINVAL) { + log_dbg("Trying to open device %s without direct-io.", + device_path(device)); + devfd = open(device_path(device), flags | O_SYNC); + } + + return devfd; +} + int device_alloc(struct device **device, const char *path) { struct device *dev; diff --git a/lib/utils_wipe.c b/lib/utils_wipe.c index 858964c6..b9385b5c 100644 --- a/lib/utils_wipe.c +++ b/lib/utils_wipe.c @@ -157,14 +157,14 @@ int crypt_wipe(struct device *device, if (!buffer) return -ENOMEM; - flags = O_RDWR | O_DIRECT | O_SYNC; + flags = O_RDWR; /* use O_EXCL only for block devices */ if (exclusive && S_ISBLK(st.st_mode)) flags |= O_EXCL; /* coverity[toctou] */ - devfd = open(device_path(device), flags); + devfd = device_open(device, flags); if (devfd == -1) { free(buffer); return errno ? -errno : -EINVAL; diff --git a/lib/verity/verity.c b/lib/verity/verity.c index 3cfc7e36..e3285a21 100644 --- a/lib/verity/verity.c +++ b/lib/verity/verity.c @@ -57,17 +57,18 @@ int VERITY_read_sb(struct crypt_device *cd, char **uuid_string, struct crypt_params_verity *params) { - const char *device = device_path(crypt_metadata_device(cd)); - int bsize = device_block_size(crypt_metadata_device(cd)); + struct device *device = crypt_metadata_device(cd); + int bsize = device_block_size(device); struct verity_sb sb = {}; ssize_t hdr_size = sizeof(struct verity_sb); int devfd = 0, sb_version; log_dbg("Reading VERITY header of size %u on device %s, offset %" PRIu64 ".", - sizeof(struct verity_sb), device, sb_offset); + sizeof(struct verity_sb), device_path(device), sb_offset); if (params->flags & CRYPT_VERITY_NO_HEADER) { - log_err(cd, _("Verity device doesn't use on-disk header.\n"), device); + log_err(cd, _("Verity device doesn't use on-disk header.\n"), + device_path(device)); return -EINVAL; } @@ -76,9 +77,9 @@ int VERITY_read_sb(struct crypt_device *cd, return -EINVAL; } - devfd = open(device ,O_RDONLY | O_DIRECT); + devfd = device_open(device, O_RDONLY); if(devfd == -1) { - log_err(cd, _("Cannot open device %s.\n"), device); + log_err(cd, _("Cannot open device %s.\n"), device_path(device)); return -EINVAL; } @@ -90,7 +91,8 @@ int VERITY_read_sb(struct crypt_device *cd, close(devfd); if (memcmp(sb.signature, VERITY_SIGNATURE, sizeof(sb.signature))) { - log_err(cd, _("Device %s is not a valid VERITY device.\n"), device); + log_err(cd, _("Device %s is not a valid VERITY device.\n"), + device_path(device)); return -EINVAL; } @@ -150,29 +152,31 @@ int VERITY_write_sb(struct crypt_device *cd, const char *uuid_string, struct crypt_params_verity *params) { - const char *device = device_path(crypt_metadata_device(cd)); - int bsize = device_block_size(crypt_metadata_device(cd)); + struct device *device = crypt_metadata_device(cd); + int bsize = device_block_size(device); struct verity_sb sb = {}; ssize_t hdr_size = sizeof(struct verity_sb); uuid_t uuid; int r, devfd = 0; log_dbg("Updating VERITY header of size %u on device %s, offset %" PRIu64 ".", - sizeof(struct verity_sb), device, sb_offset); + sizeof(struct verity_sb), device_path(device), sb_offset); if (!uuid_string || uuid_parse(uuid_string, uuid) == -1) { - log_err(cd, _("Wrong VERITY UUID format provided.\n"), device); + log_err(cd, _("Wrong VERITY UUID format provided.\n"), + device_path(device)); return -EINVAL; } if (params->flags & CRYPT_VERITY_NO_HEADER) { - log_err(cd, _("Verity device doesn't use on-disk header.\n"), device); + log_err(cd, _("Verity device doesn't use on-disk header.\n"), + device_path(device)); return -EINVAL; } - devfd = open(device, O_RDWR | O_DIRECT); + devfd = device_open(device, O_RDWR); if(devfd == -1) { - log_err(cd, _("Cannot open device %s.\n"), device); + log_err(cd, _("Cannot open device %s.\n"), device_path(device)); return -EINVAL; } @@ -189,7 +193,8 @@ int VERITY_write_sb(struct crypt_device *cd, r = write_lseek_blockwise(devfd, bsize, (char*)&sb, hdr_size, sb_offset) < hdr_size ? -EIO : 0; if (r) - log_err(cd, _("Error during update of verity header on device %s.\n"), device); + log_err(cd, _("Error during update of verity header on device %s.\n"), + device_path(device)); close(devfd); return r;