[extfs] fix inodes not being initialized above 4 GB

* So, as it happens, when assigning the product of two 32-bit variables into a 64-bit one,
  compilers default to being *DUMB* and, against all reasonable expectations, do not perform
  that multiplication as a 64-bit operation (even when the code is compiled as x64). Wow,
  that's really great decision making by compiler designers if I ever saw some... Whoever
  decided that C developers would much rather want truncation and 32-bit overflows, instead
  of the expected *LOGICAL* behaviour of conducting arithmetic operations as 64-bit when the
  result will be assigned to a 64-bit variable, need to be condemned to a lifetime of trying
  to help elderly folks trying to conduct simple computing tasks as a punishment...
  Anyhoo, nt_write_blk()'s offset.QuadPart = block * channel->block_size + nt_data->offset
  was overflowing 32-bit as soon as block * channel->block_size went over the 4 GB mark,
  with the disastrous results one can expect. Considering that this is code we practically
  lifted verbatim from e2fsprogs, I guess e2fsprogs' NT I/O manager was never properly
  tested with anything larger than a 4 GB. Awesome!
* We fix the above by doing what unix_io.c does and setting the 32-bit read/write_blk()
  calls to be wrappers around their 64-bit counterpart (since, once you deal with a 64-bit
  block variable, the computation is conducted as 64-bit).
* Also remove a bunch of stuff we don't need from config.h
* Closes #1396
This commit is contained in:
Pete Batard 2020-02-12 16:26:22 +00:00
parent 9edd7492db
commit 67d324f82b
No known key found for this signature in database
GPG key ID: 38E0CF5E69EDD671
4 changed files with 21 additions and 19 deletions

View file

@ -76,7 +76,9 @@ static errcode_t nt_open(const char *name, int flags, io_channel *channel);
static errcode_t nt_close(io_channel channel);
static errcode_t nt_set_blksize(io_channel channel, int blksize);
static errcode_t nt_read_blk(io_channel channel, unsigned long block, int count, void *data);
static errcode_t nt_read_blk64(io_channel channel, unsigned long long block, int count, void* data);
static errcode_t nt_write_blk(io_channel channel, unsigned long block, int count, const void *data);
static errcode_t nt_write_blk64(io_channel channel, unsigned long long block, int count, const void* data);
static errcode_t nt_flush(io_channel channel);
static struct struct_io_manager struct_nt_manager = {
@ -86,7 +88,9 @@ static struct struct_io_manager struct_nt_manager = {
.close = nt_close,
.set_blksize = nt_set_blksize,
.read_blk = nt_read_blk,
.read_blk64 = nt_read_blk64,
.write_blk = nt_write_blk,
.write_blk64 = nt_write_blk64,
.flush = nt_flush
};
@ -620,7 +624,7 @@ static errcode_t nt_set_blksize(io_channel channel, int blksize)
return 0;
}
static errcode_t nt_read_blk(io_channel channel, unsigned long block, int count, void *buf)
static errcode_t nt_read_blk64(io_channel channel, unsigned long long block, int count, void *buf)
{
PVOID read_buffer;
ULONG read_size;
@ -671,7 +675,12 @@ static errcode_t nt_read_blk(io_channel channel, unsigned long block, int count,
return 0;
}
static errcode_t nt_write_blk(io_channel channel, unsigned long block, int count, const void *buf)
static errcode_t nt_read_blk(io_channel channel, unsigned long block, int count, void* buf)
{
return nt_read_blk64(channel, block, count, buf);
}
static errcode_t nt_write_blk64(io_channel channel, unsigned long long block, int count, const void *buf)
{
ULONG write_size;
LARGE_INTEGER offset;
@ -718,6 +727,11 @@ static errcode_t nt_write_blk(io_channel channel, unsigned long block, int count
return 0;
}
static errcode_t nt_write_blk(io_channel channel, unsigned long block, int count, const void* buf)
{
return nt_write_blk64(channel, block, count, buf);
}
static errcode_t nt_flush(io_channel channel)
{
PNT_PRIVATE_DATA nt_data = NULL;