Details
-
Bug
-
Resolution: Fixed
-
Minor
-
None
-
None
-
None
-
3
-
9223372036854775807
Description
In e2fsprogs (master=v1.46.2-9-g32fda1e5 and recent wc tags), there is a one line bug in the direct IO case of raw_read_blk().
bounce_read:
if (channel->align == 0)
channel->align = 1;
if ((channel->block_size > channel->align) &&
(channel->block_size % channel->align) == 0)
align_size = channel->block_size;
else
align_size = channel->align;
aligned_blk = location / align_size;
offset = location % align_size;
mutex_lock(data, BOUNCE_MTX);
if (ext2fs_llseek(data->dev, aligned_blk * align_size, SEEK_SET) < 0) {
retval = errno ? errno : EXT2_ET_LLSEEK_FAILED;
goto error_unlock;
}
while (size > 0) {
actual = read(data->dev, data->bounce, align_size);
if (actual != align_size) {
mutex_unlock(data, BOUNCE_MTX);
actual = really_read;
buf -= really_read;
size += really_read;
goto short_read;
}
actual = size; /* HERE HIER AQUI ICI QUI TUK */
if (actual > align_size)
actual = align_size;
actual -= offset;
memcpy(buf, data->bounce + offset, actual);
We should not be setting actual = size.
When this is called from ext2fs_open() to read the super block on devices with a 4KB logical block size and EXT2_FLAG_DIRECT_IO it mis-initializes the super block and ext2fs_open() fails with EXT2_ET_BAD_MAGIC.
This can be reproduced in a few ways.
- Get a recent version of losetup that supports the -b option to set the logical blocksize.
- Hack ext2fs_get_device_sectsize() to return 4K.
- Use a device with 4K blocks.
Note, that you need to use EXT2_FLAG_DIRECT_IO in any of these cases to reproduce the issue.
It looks like this was fixed by artem_blagodarenko's change
c0015961 libext2fs: fix unix_io's Direct I/O support
and then inadvertently reintroduced by
d557b965 libext2fs: fix potential races in unix_io
Attachments
Issue Links
- is related to
-
LU-15591 ext2fs_open2() missing goto
-
- Closed
-