Closed cernekee closed 6 years ago
op_read() can fail an assertion if the last block of a file is sparse and the file length does not divide evenly by the block size. Test case:
wget https://dl.google.com/dl/android/aosp/blueline-pd1a.180720.030-factory-d6fefe86.zip unzip blueline-pd1a.180720.030-factory-d6fefe86.zip unzip blueline-pd1a.180720.030/image-blueline-pd1a.180720.030.zip vendor.img simg2img vendor.img vendor.img.raw mkdir vendor ext4fuse vendor.img.raw vendor sha1sum vendor/firmware/confirmationui.b04
The log reports:
[debug][op_read:110] Read 12288/12421 bytes from 1 consecutive blocks [debug][extent_get_block_from_ees:23] Extent contains 1 entries [debug][extent_get_block_from_ees:24] Looking for LBlock 259 [debug][extent_get_block_from_ees:39] Extent [0] doesn't contain block [debug][op_read:106] sparse file, skipping 4096 bytes [debug][op_read:110] Read 16384/12421 bytes from 1 consecutive blocks [warn] [op_read:114] ASSERT FAIL: size == ret
The sha1sum command (and further operations on the filesystem) fail with ENOTCONN.
This filesystem uses 4kB blocks. Offsets 0x20220 - 0x103084 of the file are all zeroes; therefore only blocks 0-32 are present on disk:
debugfs: stat /firmware/confirmationui.b04 Inode: 568 Type: regular Mode: 0644 Flags: 0x80000 Generation: 0 Version: 0x00000000:00000000 User: 0 Group: 0 Project: 0 Size: 1060997 File ACL: 0 Links: 1 Blockcount: 264 Fragment: Address: 0 Number: 0 Size: 0 ctime: 0x495c7800:00000000 -- Thu Jan 1 00:00:00 2009 atime: 0x495c7800:00000000 -- Thu Jan 1 00:00:00 2009 mtime: 0x495c7800:00000000 -- Thu Jan 1 00:00:00 2009 crtime: 0x495c7800:00000000 -- Thu Jan 1 00:00:00 2009 Size of extra inode fields: 32 Extended attributes: security.selinux (26) = "u:object_r:vendor_file:s0\000" EXTENTS: (0-32):12468-12500 debugfs: blocks /firmware/confirmationui.b04 12468 12469 12470 12471 12472 12473 12474 12475 12476 12477 12478 12479 12480 12481 12482 12483 12484 12485 12486 12487 12488 12489 12490 12491 12492 12493 12494 12495 12496 12497 12498 12499 12500
hexdump -C confirmationui.b04 ends with:
hexdump -C confirmationui.b04
00020210 00 00 00 00 00 00 00 00 00 00 00 ff ff ff ff ff |................| 00020220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00103085
Change op_read() so that it takes the remaining transfer bytes into account instead of always returning |BLOCK_SIZE| zeroes when reading a sparse block.
I also added a new check to test case 0014 to catch this error.
op_read() can fail an assertion if the last block of a file is sparse and the file length does not divide evenly by the block size. Test case:
The log reports:
The sha1sum command (and further operations on the filesystem) fail with ENOTCONN.
This filesystem uses 4kB blocks. Offsets 0x20220 - 0x103084 of the file are all zeroes; therefore only blocks 0-32 are present on disk:
hexdump -C confirmationui.b04
ends with:Change op_read() so that it takes the remaining transfer bytes into account instead of always returning |BLOCK_SIZE| zeroes when reading a sparse block.
I also added a new check to test case 0014 to catch this error.