From 1ca0b382f5e4fc72b31b23950315d637bf83c250 Mon Sep 17 00:00:00 2001 From: Benjamin Robin Date: Sat, 8 May 2021 10:05:12 +0200 Subject: [PATCH 1/2] dis_initialize: Open block device RO if asked with --readonly --- src/dislocker.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/dislocker.c b/src/dislocker.c index 41e216f6..48f91d0d 100644 --- a/src/dislocker.c +++ b/src/dislocker.c @@ -127,33 +127,36 @@ int dis_initialize(dis_context_t dis_ctx) /* Open the volume as a (big) normal file */ - dis_printf(L_DEBUG, "Trying to open '%s'...\n", dis_ctx->cfg.volume_path); - dis_ctx->fve_fd = dis_open(dis_ctx->cfg.volume_path, O_RDWR|O_LARGEFILE); - if(dis_ctx->fve_fd < 0) + + if(dis_is_read_only(dis_ctx) != 0) { - /* Trying to open it in read-only if O_RDWR doesn't work */ - dis_ctx->fve_fd = dis_open( - dis_ctx->cfg.volume_path, - O_RDONLY|O_LARGEFILE - ); + dis_printf(L_DEBUG, "Trying to open RO '%s'...\n", dis_ctx->cfg.volume_path); + dis_ctx->fve_fd = dis_open(dis_ctx->cfg.volume_path, O_RDONLY|O_LARGEFILE); + } + else + { + dis_printf(L_DEBUG, "Trying to open RW '%s'...\n", dis_ctx->cfg.volume_path); + dis_ctx->fve_fd = dis_open(dis_ctx->cfg.volume_path, O_RDWR|O_LARGEFILE); if(dis_ctx->fve_fd < 0) { + /* Trying to open it in read-only if O_RDWR doesn't work */ + dis_ctx->cfg.flags |= DIS_FLAG_READ_ONLY; dis_printf( - L_CRITICAL, - "Failed to open %s: %s\n", - dis_ctx->cfg.volume_path, strerror(errno) + L_WARNING, + "Failed to open %s for writing. Falling back to read-only.\n", + dis_ctx->cfg.volume_path ); - dis_destroy(dis_ctx); - return DIS_RET_ERROR_FILE_OPEN; + + dis_ctx->fve_fd = dis_open(dis_ctx->cfg.volume_path, O_RDONLY|O_LARGEFILE); } + } - dis_ctx->cfg.flags |= DIS_FLAG_READ_ONLY; - dis_printf( - L_WARNING, - "Failed to open %s for writing. Falling back to read-only.\n", - dis_ctx->cfg.volume_path - ); + if(dis_ctx->fve_fd < 0) + { + dis_printf(L_CRITICAL, "Failed to open %s: %s\n", dis_ctx->cfg.volume_path, strerror(errno)); + dis_destroy(dis_ctx); + return DIS_RET_ERROR_FILE_OPEN; } dis_printf(L_DEBUG, "Opened (fd #%d).\n", dis_ctx->fve_fd); From 845cf7a76e3848fed49a26de1642626c260166dc Mon Sep 17 00:00:00 2001 From: Benjamin Robin Date: Sat, 8 May 2021 10:21:13 +0200 Subject: [PATCH 2/2] prepare_crypt: Get encrypted_volume_size from disk device size Do not trust size provided from metadata --- src/inouts/prepare.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/inouts/prepare.c b/src/inouts/prepare.c index 6d8a0be6..f134ac26 100644 --- a/src/inouts/prepare.c +++ b/src/inouts/prepare.c @@ -23,6 +23,9 @@ #include #include +#include +#include +#include #include "dislocker/inouts/prepare.h" #include "dislocker/inouts/sectors.h" @@ -98,6 +101,7 @@ int init_keys(bitlocker_dataset_t* dataset, datum_key_t* fvek_datum, int prepare_crypt(dis_context_t dis_ctx) { dis_iodata_t* io_data; + uint64_t part_volume_size = UINT64_MAX; if(!dis_ctx) return DIS_RET_ERROR_DISLOCKER_INVAL; @@ -113,6 +117,15 @@ int prepare_crypt(dis_context_t dis_ctx) io_data->encrypted_volume_size = dis_metadata_volume_size_from_vbr(dis_ctx->metadata); io_data->encrypted_volume_size += io_data->sector_size; //The volume size of Vista should include the DBR backup } + + // Do not trust the encrypted volume size in metadata. After shrinking the volume, metadata + // is not updated at least by Windows 10 1909 + if (ioctl(dis_ctx->fve_fd, BLKGETSIZE64, &part_volume_size) >= 0) + { + if (part_volume_size < io_data->encrypted_volume_size) + io_data->encrypted_volume_size = part_volume_size; + } + io_data->backup_sectors_addr = dis_metadata_ntfs_sectors_address(io_data->metadata); io_data->nb_backup_sectors = dis_metadata_backup_sectors_count(io_data->metadata);