Skip site navigation (1)Skip section navigation (2)
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>