Date: Sun, 03 Jan 2016 04:35:00 +0000 From: bugzilla-noreply@freebsd.org To: freebsd-bugs@FreeBSD.org Subject: [Bug 205816] [ext2fs] [patch] EXT4 sparse blocks unsupported, contain garbage when read Message-ID: <bug-205816-8@https.bugs.freebsd.org/bugzilla/>
next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D205816 Bug ID: 205816 Summary: [ext2fs] [patch] EXT4 sparse blocks unsupported, contain garbage when read Product: Base System Version: 11.0-CURRENT Hardware: Any OS: Any Status: New Keywords: patch Severity: Affects Many People Priority: --- Component: kern Assignee: freebsd-bugs@FreeBSD.org Reporter: damjan.jov@gmail.com CC: freebsd-fs@FreeBSD.org Created attachment 164979 --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=3D164979&action= =3Dedit preliminary patch to implement support for EXT4 sparse files The ext2fs module does not support sparse files on EXT4 filesystems, yet doesn't fail. When attempting to read the sparse blocks from a sparse file, instead of zeroes, they contain garbage data read from the wrong disk block= s. Here's an example sparse file in debugfs: debugfs: dump_extents /home/user/Documents/file.iso Level Entries Logical Physical Length Flags 0/ 1 1/ 1 0 - 1122599 1082775 1122600 1/ 1 1/ 53 0 - 5 1372160 - 1372165 6 1/ 1 2/ 53 8 - 11 1372168 - 1372171 4 1/ 1 3/ 53 16 - 19 1372176 - 1372179 4 1/ 1 4/ 53 24 - 27 1372184 - 1372187 4 1/ 1 5/ 53 32 - 33 1372192 - 1372193 2 ... Note how block ranges 0-5, 8-11, 16-19 are allocated, but the in between bl= ocks are sparse. The problem starts in the ext4_ext_binsearch() function in ext2_extents.c w= hich expects the block ranges in the extents to be continuous, and doesn't check whether the lbn parameter even lies inside the found extent's block range. = It blindly sets: path->ep_ext =3D l - 1; which will set the pointer to invalid memory (a part of struct ext2_extent_header) when lbn=3D0 and the first block of a file is sparse. A= lso in the above example, lbn=3D6 will use the 0-5 extent, reading block 0 instead. My preliminary patch improves ext4_ext_binsearch() to check for out of range blocks, marks the path as being sparse, and stores the range of extents starting at the lbn that is sparse. Sparse extents are cached in ext4_ext_read() for future reuse. Actual reading of sparse blocks is implemented by copying from a static array of zeroes (is there a better way= of doing it?) and read() definitely works, but mmap() doesn't seem to (system instantly reboots when reading even 1 byte from mapped region, but this also happens for some dense files, so it's not (just?) my patch). If testing against other EXT4 implementations, note that ext4fuse also has = this bug. --=20 You are receiving this mail because: You are the assignee for the bug.=
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-205816-8>