Commit Graph
763 Commits
Author SHA1 Message Date
Maxim Suhanov 0ed2458cc4 fs/ntfs: Fix an OOB read when reading data from the resident $DATA attribute
When reading a file containing resident data, i.e., the file data is stored in
the $DATA attribute within the NTFS file record, not in external clusters,
there are no checks that this resident data actually fits the corresponding
file record segment.

When parsing a specially-crafted file system image, the current NTFS code will
read the file data from an arbitrary, attacker-chosen memory offset and of
arbitrary, attacker-chosen length.

This allows an attacker to display arbitrary chunks of memory, which could
contain sensitive information like password hashes or even plain-text,
obfuscated passwords from BS EFI variables.

This fix implements a check to ensure that resident data is read from the
corresponding file record segment only.

Fixes: CVE-2023-4693

Reported-by: Maxim Suhanov <dfirblog@gmail.com>
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-10-03 15:38:48 +02:00
Maxim Suhanov 43651027d2 fs/ntfs: Fix an OOB write when parsing the $ATTRIBUTE_LIST attribute for the $MFT file
When parsing an extremely fragmented $MFT file, i.e., the file described
using the $ATTRIBUTE_LIST attribute, current NTFS code will reuse a buffer
containing bytes read from the underlying drive to store sector numbers,
which are consumed later to read data from these sectors into another buffer.

These sectors numbers, two 32-bit integers, are always stored at predefined
offsets, 0x10 and 0x14, relative to first byte of the selected entry within
the $ATTRIBUTE_LIST attribute. Usually, this won't cause any problem.

However, when parsing a specially-crafted file system image, this may cause
the NTFS code to write these integers beyond the buffer boundary, likely
causing the GRUB memory allocator to misbehave or fail. These integers contain
values which are controlled by on-disk structures of the NTFS file system.

Such modification and resulting misbehavior may touch a memory range not
assigned to the GRUB and owned by firmware or another EFI application/driver.

This fix introduces checks to ensure that these sector numbers are never
written beyond the boundary.

Fixes: CVE-2023-4692

Reported-by: Maxim Suhanov <dfirblog@gmail.com>
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-10-03 15:38:48 +02:00
Vladimir Serbinenko 7ce5b49110 ZFS: Check bonustype in addition to dnode type
Some dnodes are shared with properties zap. This is used
e.g. for quotas. Then dnode type is 0xc4 and GRUB stumbles on
this. Check bonus type and if it's ok then ignore dnode type mismatch

Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-09-18 02:44:35 +02:00
Vladimir Serbinenko 444089eec6 ZFS: Don't iterate over null objsets
Reading them is harmless but useless as they are empty by definition

Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-09-18 02:44:02 +02:00
Vladimir Serbinenko 96446ce14e ZFS: Fix invalid memcmp
We ended up comparing over unset values as we had dnode_phys on one side
and dnode on another

Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-09-18 02:43:32 +02:00
Vladimir Serbinenko 42a831d746 ZFS: support inode type embed into its ID
This is a speedup used in some ZFS version. This trips GRUB and makes it
unable to access directories. Just skip it for now and revisit
if we ever need this speedup.

Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-09-18 02:42:21 +02:00
Glenn Washburn fcbea18c58 fs/archelp: If path given to grub_archelp_dir() is not a directory return error
Specifically, return GRUB_ERR_BAD_FILE_TYPE because this is what is
expected by the ls command when it is given a path to a non-directory.
This fixes a bug where calling ls with a list of non-directory paths
outputs a blank line for each such argument.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-08-14 18:07:24 +02:00
Lidong Chen a24ea9241c fs/udf: Fix out of bounds access
Implemented a boundary check before advancing the allocation
descriptors pointer.

Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-06-13 14:48:38 +02:00
Darren Kenny ef7850c757 fs/xfs: Fix issues found while fuzzing the XFS filesystem
While performing fuzz testing with XFS filesystem images with ASAN
enabled, several issues were found where the memory accesses are made
beyond the data that is allocated into the struct grub_xfs_data
structure's data field.

The existing structure didn't store the size of the memory allocated into
the buffer in the data field and had no way to check it. To resolve these
issues, the data size is stored to enable checks into the data buffer.

With these checks in place, the fuzzing corpus no longer cause any crashes.

Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
Signed-off-by: Marta Lewandowska <mlewando@redhat.com>
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-06-13 14:26:47 +02:00
Lidong Chen 61b13c187c fs/hfsplus: Set grub_errno to prevent NULL pointer access
When an invalid node size is detected in grub_hfsplus_mount(), data
pointer is freed. Thus, file->data is not set. The code should also
set the grub_errno when that happens to indicate an error and to avoid
accessing the uninitialized file->data in grub_file_close().

Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-05-17 18:19:02 +02:00
Lidong Chen eb8b0aabb8 fs/hfsplus: Prevent out of bound access in catalog file
A corrupted hfsplus can have a catalog key that is out of range. This
can lead to out of bound access when advancing the pointer to access
catalog file info. The valid range of a catalog key is specified in
HFS Plus Technical Note TN1150 [1].

[1] https://developer.apple.com/library/archive/technotes/tn/tn1150.html

Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-05-17 18:19:02 +02:00
Lidong Chen 3f6b129bdc fs/hfsplus: Validate btree node size
The invalid btree node size can cause crashes when parsing the btree.
The fix is to ensure the btree node size is within the valid range
defined in the HFS Plus technical note, TN1150 [1].

[1] https://developer.apple.com/library/archive/technotes/tn/tn1150.html

Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-05-17 18:19:02 +02:00
Thomas Schmitt d6f12ffaf8 fs/iso9660: Delay CE hop until end of current SUSP area
The SUSP specs demand that the reading of the next SUSP area which is
depicted by a CE entry shall be delayed until reading of the current
SUSP area is completed. Up to now GRUB immediately ends reading of the
current area and loads the new one. So, buffer the parameters of a found
CE entry and perform checks and reading of new data only after the
reader loop has ended.

Signed-off-by: Thomas Schmitt <scdbackup@gmx.net>
Tested-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-04-13 14:45:47 +02:00
Thomas Schmitt 2a96eab759 fs/iso9660: Prevent skipping CE or ST at start of continuation area
If processing of a SUSP CE entry leads to a continuation area which
begins by entry CE or ST, then these entries were skipped without
interpretation. In case of CE this would lead to premature end of
processing the SUSP entries of the file. In case of ST this could
cause following non-SUSP bytes to be interpreted as SUSP entries.

Signed-off-by: Thomas Schmitt <scdbackup@gmx.net>
Tested-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Thomas Schmitt <scdbackup@gmx.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-02-02 19:44:56 +01:00
Lidong Chen 77f657dc9e fs/iso9660: Incorrect check for entry boundary
An SL entry consists of the entry info and the component area.
The entry info should take up 5 bytes instead of sizeof(*entry).
The area after the first 5 bytes is the component area. It is
incorrect to use the sizeof(*entry) to check the entry boundary.

Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Thomas Schmitt <scdbackup@gmx.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-02-02 19:44:56 +01:00
Lidong Chen c44b1428c4 fs/iso9660: Avoid reading past the entry boundary
Added a check for the SP entry data boundary before reading it.

Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Thomas Schmitt <scdbackup@gmx.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-02-02 19:44:56 +01:00
Lidong Chen 8f41d35fce fs/iso9660: Prevent read past the end of system use area
In the code, the for loop advanced the entry pointer to the next entry before
checking if the next entry is within the system use area boundary. Another
issue in the code was that there is no check for the size of system use area.
For a corrupted system, the size of system use area can be less than the size
of minimum SUSP entry size (4 bytes). These can cause buffer overrun. The fixes
added the checks to ensure the read is valid and within the boundary.

Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Thomas Schmitt <scdbackup@gmx.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-02-02 19:44:56 +01:00
Lidong Chen 4e0bab34ec fs/iso9660: Add check to prevent infinite loop
There is no check for the end of block when reading
directory extents. It resulted in read_node() always
read from the same offset in the while loop, thus
caused infinite loop. The fix added a check for the
end of the block and ensure the read is within directory
boundary.

Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Thomas Schmitt <scdbackup@gmx.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-02-02 19:43:50 +01:00
Daniel Axtens 4de39a2af6 fs/f2fs: Fix off-by-one error in nat journal entries check
Oops. You're allowed to have up to n = NAT_JOURNAL_ENTRIES entries
_inclusive_, because the loop below uses i < n, not i <= n. D'oh.

Fixes: 4bd9877f62 (fs/f2fs: Do not read past the end of nat journal entries)

Reported-by: программист нект <programmer11180@programist.ru>
Tested-by: программист нект <programmer11180@programist.ru>
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-01-19 17:39:05 +01:00
t.feng 2e32d23574 fs/xfs: Fix memory leaks in XFS module
Signed-off-by: t.feng <fengtao40@huawei.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-12-07 23:38:26 +01:00
t.feng 98ae234000 fs/squash4: Fix memory leaks in grub_squash_iterate_dir()
Fixes: 20dd511c8 (Handle "." and ".." on squashfs)

Signed-off-by: t.feng <fengtao40@huawei.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-12-07 23:38:26 +01:00
t.feng 7338cbe91a fs/iso9660: Fix memory leaks in grub_iso9660_susp_iterate()
Fixes: 99373ce47 (* grub-core/fs/iso9660.c: Remove nested functions)

Signed-off-by: t.feng <fengtao40@huawei.com>
Reviewed-by: Thomas Schmitt <scdbackup@gmx.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-12-07 23:38:26 +01:00
t.feng a1e05167c8 fs/hfsplus: Fix memory leak in grub_hfsplus_btree_search()
Fixes: 58ea11d5b (fs/hfsplus: Don't fetch a key beyond the end of the node)

Signed-off-by: t.feng <fengtao40@huawei.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-12-07 23:38:26 +01:00
t.feng 6cdd08b362 fs/bfs: Fix memory leak in read_bfs_file()
The l1_entries and l2_entries were not freed at the end of file read.

Fixes: 5825b3794 (BFS implementation based on the specification)

Signed-off-by: t.feng <fengtao40@huawei.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-12-07 23:38:26 +01:00
t.feng a2f7914c3c fs/ntfs: Fix memory leaks in grub_ntfs_read_symlink()
Fixes: 5773fb641 (Support NTFS reparse points)

Signed-off-by: t.feng <fengtao40@huawei.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-12-07 23:38:26 +01:00
t.feng f3fab3ea60 fs/minix: Fix memory leaks in grub_minix_lookup_symlink()
Fixes: a07e6ad01 (* grub-core/fs/minix.c: Remove variable length arrays)

Signed-off-by: t.feng <fengtao40@huawei.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-12-07 23:38:26 +01:00
t.feng 3b49391bc5 fs/btrfs: Fix memory leak in find_path()
Fixes: 82591fa6e (Make / in btrfs refer to real root)

Signed-off-by: t.feng <fengtao40@huawei.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-12-07 23:38:25 +01:00
t.feng 022365aeaa fs/affs: Fix memory leaks in grub_affs_create_node()
The hashtable is not freed if GRUB_AFFS_FILETYPE_HARDLINK and
grub_disk_read() failed. If grub_affs_create_node() returns non-zero
the hashtable should be freed too.

By the way, the hashtable argument is unused in grub_affs_create_node().
So, we can remove the argument and free it in grub_affs_iterate_dir().
It allocates the memory and it should be responsible for releasing it.

This is why commit ebf32bc4e9 (fs/affs: Fix resource leaks) missed
this memory leak.

Fixes: ebf32bc4e9 (fs/affs: Fix resource leaks)

Signed-off-by: t.feng <fengtao40@huawei.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-12-07 23:38:25 +01:00
Jagannathan Raman c08edc545c fs/udf: Validate length of AED in grub_udf_read_block()
Validate the length of Allocation Extent Descriptor in grub_udf_read_block(),
based on the details in UDF spec. v2.01 section 2.3.11.

Fixes: CID 314037

Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-12-07 23:38:25 +01:00
Jagannathan Raman 306be1f813 fs/zfs/zfs: Update dangling dn_new pointer in dnode_get_path()
The dnode_get_path() traverses dnode structures to locate the dnode leaf
of a given path. When the leaf is a symlink to another path, it restarts
the traversal either from root or from a different path. In such cases,
dn_new must be re-initialized

Passes "make check".

Fixes: CID 86750

Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-10-27 16:50:06 +02:00
Theodore Ts'o 2e9fa73a04 fs/ext2: Ignore the large_dir incompat feature
Recently, ext4 added the large_dir feature, which adds support for
a 3 level htree directory support.

The GRUB supports existing file systems with htree directories by
ignoring their existence, and since the index nodes for the hash tree
look like deleted directory entries (by design), the GRUB can simply do
a brute force O(n) linear search of directories. The same is true for
3 level deep htrees indicated by large_dir feature flag.

Hence, it is safe for the GRUB to ignore the large_dir incompat feature.

Fixes: https://savannah.gnu.org/bugs/?61606

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-10-04 16:00:51 +02:00
Jagannathan Raman a032782c86 fs/zfs/zfs: Pass pointer to dnode_end_t instead of value to fill_fs_info()
Coverity reports that dnode_end_t argument of fill_fs_info() is too
large to pass-by-value. Therefore, replace the argument with a pointer.

Fixes: CID 73631

Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-08-19 23:55:50 +02:00
Robbie Harwood e43f3d93b2 fs/fat: Don't error when mtime is 0
In the wild, we occasionally see valid ESPs where some file modification
times are 0. For instance:

    ├── [Dec 31  1979]  EFI
    │   ├── [Dec 31  1979]  BOOT
    │   │   ├── [Dec 31  1979]  BOOTX64.EFI
    │   │   └── [Dec 31  1979]  fbx64.efi
    │   └── [Jun 27 02:41]  fedora
    │       ├── [Dec 31  1979]  BOOTX64.CSV
    │       ├── [Dec 31  1979]  fonts
    │       ├── [Mar 14 03:35]  fw
    │       │   ├── [Mar 14 03:35]  fwupd-359c1169-abd6-4a0d-8bce-e4d4713335c1.cap
    │       │   ├── [Mar 14 03:34]  fwupd-9d255c4b-2d88-4861-860d-7ee52ade9463.cap
    │       │   └── [Mar 14 03:34]  fwupd-b36438d8-9128-49d2-b280-487be02d948b.cap
    │       ├── [Dec 31  1979]  fwupdx64.efi
    │       ├── [May 10 10:47]  grub.cfg
    │       ├── [Jun  3 12:38]  grub.cfg.new.new
    │       ├── [May 10 10:41]  grub.cfg.old
    │       ├── [Jun 27 02:41]  grubenv
    │       ├── [Dec 31  1979]  grubx64.efi
    │       ├── [Dec 31  1979]  mmx64.efi
    │       ├── [Dec 31  1979]  shim.efi
    │       ├── [Dec 31  1979]  shimx64.efi
    │       └── [Dec 31  1979]  shimx64-fedora.efi
    └── [Dec 31  1979]  FSCK0000.REC

    5 directories, 17 files

This causes grub-probe failure, which in turn causes grub-mkconfig
failure. They are valid filesystems that appear intact, and the Linux
FAT stack is able to mount and manipulate them without complaint.

The check for mtime of 0 has been present since
20def1a3c3 (fat: support file
modification times).

Signed-off-by: Robbie Harwood <rharwood@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-07-27 19:20:53 +02:00
Glenn Washburn f5a92e6040 disk: Allow read hook callback to take read buffer to potentially modify it
It will be desirable in the future to allow having the read hook modify the
data passed back from a read function call on a disk or file. This adds that
infrastructure and has no impact on code flow for existing uses of the read
hook. Also changed is that now when the read hook callback is called it can
also indicate what error code should be sent back to the read caller.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-07-04 14:43:25 +02:00
Darren Kenny 2f4430cc0a fs/btrfs: Fix more fuzz issues related to chunks
The corpus was generating issues in grub_btrfs_read_logical() when
attempting to iterate over stripe entries in the superblock's
bootmapping.

In most cases the reason for the failure was that the number of stripes
in chunk->nstripes exceeded the possible space statically allocated in
superblock bootmapping space. Each stripe entry in the bootmapping block
consists of a grub_btrfs_key followed by a grub_btrfs_chunk_stripe.

Another issue that came up was that while calculating the chunk size,
in an earlier piece of code in that function, depending on the data
provided in the btrfs file system, it would end up calculating a size
that was too small to contain even 1 grub_btrfs_chunk_item, which is
obviously invalid too.

Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-06-07 16:39:34 +02:00
Darren Kenny 13dce204cf fs/btrfs: Fix more ASAN and SEGV issues found with fuzzing
The fuzzer is generating btrfs file systems that have chunks with
invalid combinations of stripes and substripes for the given RAID
configurations.

After examining the Linux kernel fs/btrfs/tree-checker.c code, it
appears that sub-stripes should only be applied to RAID10, and in that
case there should only ever be 2 of them.

Similarly, RAID single should only have 1 stripe, and RAID1/1C3/1C4
should have 2. 3 or 4 stripes respectively, which is what redundancy
corresponds.

Some of the chunks ended up with a size of 0, which grub_malloc() still
returned memory for and in turn generated ASAN errors later when
accessed.

While it would be possible to specifically limit the number of stripes,
a more correct test was on the combination of the chunk item, and the
number of stripes by the size of the chunk stripe structure in
comparison to the size of the chunk itself.

Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-06-07 16:39:34 +02:00
Darren Kenny 11e1cffb7e fs/btrfs: Fix several fuzz issues with invalid dir item sizing
According to the btrfs code in Linux, the structure of a directory item
leaf should be of the form:

  |struct btrfs_dir_item|name|data|

in GRUB the name len and data len are in the grub_btrfs_dir_item
structure's n and m fields respectively.

The combined size of the structure, name and data should be less than
the allocated memory, a difference to the Linux kernel's struct
btrfs_dir_item is that the grub_btrfs_dir_item has an extra field for
where the name is stored, so we adjust for that too.

Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-06-07 16:39:34 +02:00
Sudhakar Kuppusamy e40b83335b fs/f2fs: Do not copy file names that are too long
A corrupt f2fs file system might specify a name length which is greater
than the maximum name length supported by the GRUB f2fs driver.

We will allocate enough memory to store the overly long name, but there
are only F2FS_NAME_LEN bytes in the source, so we would read past the end
of the source.

While checking directory entries, do not copy a file name with an invalid
length.

Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-06-07 16:39:33 +02:00
Sudhakar Kuppusamy deae293f39 fs/f2fs: Do not read past the end of nat bitmap
A corrupt f2fs filesystem could have a block offset or a bitmap
offset that would cause us to read beyond the bounds of the nat
bitmap.

Introduce the nat_bitmap_size member in grub_f2fs_data which holds
the size of nat bitmap.

Set the size when loading the nat bitmap in nat_bitmap_ptr(), and
catch when an invalid offset would create a pointer past the end of
the allocated space.

Check against the bitmap size in grub_f2fs_test_bit() test bit to avoid
reading past the end of the nat bitmap.

Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-06-07 16:39:33 +02:00
Sudhakar Kuppusamy 4bd9877f62 fs/f2fs: Do not read past the end of nat journal entries
A corrupt f2fs file system could specify a nat journal entry count
that is beyond the maximum NAT_JOURNAL_ENTRIES.

Check if the specified nat journal entry count before accessing the
array, and throw an error if it is too large.

Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-06-07 16:39:33 +02:00
Jagannathan Raman 91b38780ac fs/zfs/zfs: zfs_mount() - avoid pointer downcasting
Coverity reports that while loopis in the following functions uses
tainted data as boundary:
  zfs_mount() -> check_mos_features() -> dnode_get() -> zfs_log2()
  zfs_mount() -> grub_memmove()

The defect type is "Untrusted loop bound" caused as a result of
"tainted_data_downcast". Coverity does not like the pointer downcast
here and we need to address it.

We believe Coverity flags pointer downcast for the following two
reasons:
1. External data: The pointer downcast could indicate that the source is
  external data, which we need to further sanitize - such as verifying its
  limits. In this case, the data is read from an external source, which is
  a disk. But, zio_read(), which reads the data from the disk, sanitizes it
  using a checksum. checksum is the best facility that ZFS offers to verify
  external data, and we don't believe a better way exists. Therefore, no
  further action is possible for this.

2. Corruption due to alignment: downcasting a pointer from a strict type
  to less strict type could result in data corruption. For example, the
  following cast would corrupt because uint32_t is 4-byte aligned, and
  won't be able to point to 0x1003 which is not 4-byte aligned.
    uint8_t *ptr = 0x1003;
    uint32_t *word = ptr; (incorrect, alignment issues)

  This patch converts the "osp" pointer in zfs_mount() from a "void" type
  to "objset_phys_t" type to address this issue.

We are not sure if there are any other reasons why Coverity flags the
downcast. However, the fix for alignment issue masks/suppresses any
other issues from showing up.

Fixes: CID 314023

Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-06-07 16:39:31 +02:00
Jagannathan Raman a5cc223e38 fs/zfs/zfs: make_mdn() - avoid pointer downcasting
Coverity reports that the while loop in the following function uses
tainted data as boundary:
  fill_fs_info() -> dnode_get() -> zfs_log2()

The tainted originated from:
  fill_fs_info() -> make_mdn()

The defect type is "Untrusted loop bound" caused as a result of
"tainted_data_downcast". Coverity does not like the pointer downcast
here and we need to address it.

We believe Coverity flags pointer downcast for the following two
reasons:
1. External data: The pointer downcast could indicate that the source is
  external data, which we need to further sanitize - such as verifying its
  limits. In this case, the data is read from an external source, which is
  a disk. But, zio_read(), which reads the data from the disk, sanitizes it
  using a checksum. checksum is the best facility that ZFS offers to verify
  external data, and we don't believe a better way exists. Therefore, no
  further action is possible for this.

2. Corruption due to alignment: downcasting a pointer from a strict type
  to less strict type could result in data corruption. For example, the
  following cast would corrupt because uint32_t is 4-byte aligned, and
  won't be able to point to 0x1003 which is not 4-byte aligned.
    uint8_t *ptr = 0x1003;
    uint32_t *word = ptr; (incorrect, alignment issues)

This patch converts the "osp" pointer in make_mdn() from a "void" type
to "objset_phys_t" type to address the issue.

We are not sure if there are any other reasons why Coverity flags the
downcast. However, the fix for alignment issue masks/suppresses any
other issues from showing up.

Fixes: CID 314020

Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-06-07 16:39:31 +02:00
Michael Chang acffb81485 build: Fix -Werror=array-bounds array subscript 0 is outside array bounds
The GRUB is failing to build with GCC-12 in many places like this:

  In function 'init_cbfsdisk',
      inlined from 'grub_mod_init' at ../../grub-core/fs/cbfs.c:391:3:
  ../../grub-core/fs/cbfs.c:345:7: error: array subscript 0 is outside array bounds of 'grub_uint32_t[0]' {aka 'unsigned int[]'} [-Werror=array-bounds]
    345 |   ptr = *(grub_uint32_t *) 0xfffffffc;
        |   ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This is caused by GCC regression in 11/12 [1]. In a nut shell, the
warning is about detected invalid accesses at non-zero offsets to NULL
pointers. Since hardwired constant address is treated as NULL plus an
offset in the same underlying code, the warning is therefore triggered.

Instead of inserting #pragma all over the places where literal pointers
are accessed to avoid diagnosing array-bounds, we can try to borrow the
idea from Linux kernel that the absolute_pointer() macro [2][3] is used
to disconnect a pointer using literal address from it's original object,
hence GCC won't be able to make assumptions on the boundary while doing
pointer arithmetic. With that we can greatly reduce the code we have to
cover up by making initial literal pointer assignment to use the new
wrapper but not having to track everywhere literal pointers are
accessed. This also makes code looks cleaner.

Please note the grub_absolute_pointer() macro requires to be invoked in
a function as long as it is compound expression. Some global variables
with literal pointers has been changed to local ones in order to use
grub_absolute_pointer() to initialize it. The shuffling is basically done
in a selective and careful way that the variable's scope doesn't matter
being local or global, for example, the global variable must not get
modified at run time throughout. For the record, here's the list of
global variables got shuffled in this patch:

  grub-core/commands/i386/pc/drivemap.c:int13slot
  grub-core/term/i386/pc/console.c:bios_data_area
  grub-core/term/ns8250.c:serial_hw_io_addr

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578
[2] https://elixir.bootlin.com/linux/v5.16.14/source/include/linux/compiler.h#L180
[3] https://elixir.bootlin.com/linux/v5.16.14/source/include/linux/compiler-gcc.h#L31

Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-04-20 18:27:52 +02:00
Elyes Haouas 5b077d05b3 fs: Remove trailing whitespaces
Signed-off-by: Elyes Haouas <ehaouas@noos.fr>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-03-14 15:45:30 +01:00
Alec Brown ebf32bc4e9 fs/affs: Fix resource leaks
In commit 178ac51073 (affs: Fix memory leaks), fixes were made to
grub_affs_iterate_dir() to prevent memory leaks from occurring after it
returns without freeing node. However, there were still some instances
where node was causing a memory leak when the function returns after
calling grub_affs_create_node(). In this function, new memory is
allocated to node but doesn't get freed until the hook() function is
called near the end. Before hook() is called, node should be freed in
grub_affs_create_node() before returning out of it.

Fixes: 178ac51073 (affs: Fix memory leaks)
Fixes: CID 73759

Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-02-08 16:06:50 +01:00
Michael Chang b0f06a81c6 fs/btrfs: Use full btrfs bootloader area
Up to now GRUB can only embed to the first 64 KiB before primary
superblock of btrfs, effectively limiting the GRUB core size. That
could consequently pose restrictions to feature enablement like
advanced zstd compression.

This patch attempts to utilize full unused area reserved by btrfs for
the bootloader outlined in the document [1]:

  The first 1MiB on each device is unused with the exception of primary
  superblock that is on the offset 64KiB and spans 4KiB.

Apart from that, adjacent sectors to superblock and first block group
are not used for embedding in case of overflow and logged access to
adjacent sectors could be useful for tracing it up.

This patch has been tested to provide out of the box support for btrfs
zstd compression with which GRUB has been installed to the partition.

[1] https://btrfs.wiki.kernel.org/index.php/Manpage/btrfs(5)#BOOTLOADER_SUPPORT

Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-12-23 02:55:30 +01:00
Qu Wenruo 7f4e017a14 fs/btrfs: Make extent item iteration to handle gaps
The GRUB btrfs implementation can't handle two very basic btrfs
file layouts:

1. Mixed inline/regualr extents
   # mkfs.btrfs -f test.img
   # mount test.img /mnt/btrfs
   # xfs_io -f -c "pwrite 0 1k" -c "sync" -c "falloc 0 4k" \
	       -c "pwrite 4k 4k" /mnt/btrfs/file
   # umount /mnt/btrfs
   # ./grub-fstest ./grub-fstest --debug=btrfs ~/test.img hex "/file"

   Such mixed inline/regular extents case is not recommended layout,
   but all existing tools and kernel can handle it without problem.

2. NO_HOLES feature
   # mkfs.btrfs -f test.img -O no_holes
   # mount test.img /mnt/btrfs
   # xfs_io -f -c "pwrite 0 4k" -c "pwrite 8k 4k" /mnt/btrfs/file
   # umount /mnt/btrfs
   # ./grub-fstest ./grub-fstest --debug=btrfs ~/test.img hex "/file"

   NO_HOLES feature is going to be the default mkfs feature in the incoming
   v5.15 release, and kernel has support for it since v4.0.

The way GRUB btrfs code iterates through file extents relies on no gap
between extents.

If any gap is hit, then GRUB btrfs will error out, without any proper
reason to help debug the bug.

This is a bad assumption, since a long long time ago btrfs has a new
feature called NO_HOLES to allow btrfs to skip the padding hole extent
to reduce metadata usage.

The NO_HOLES feature is already stable since kernel v4.0 and is going to
be the default mkfs feature in the incoming v5.15 btrfs-progs release.

When there is a extent gap, instead of error out, just try next item.

This is still not ideal, as kernel/progs/U-boot all do the iteration
item by item, not relying on the file offset continuity.

But it will be way more time consuming to correct the whole behavior than
starting from scratch to build a proper designed btrfs module for GRUB.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-12-23 00:44:33 +01:00
Darren Kenny bb9ff31641 fs/zfs/zfs: Fix possible insecure use of chunk size in zap_leaf_array_get()
In zap_leaf_array_get() the chunk size passed in is considered tainted
by Coverity, and is being used before it is tested for validity. To fix
this the assignment of "la" is moved until after the test of the value
of "chunk".

Fixes: CID 314014

Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-11-02 16:48:59 +01:00
Krzysztof Nowicki 1e5ed5f5f5 fs/ext2: Fix handling of missing sparse extent leafs
When a file on ext4 is stored as sparse the data belonging to
zero-filled blocks is not written to storage and the extent map is
missing entries for these blocks. Such case can happen both for depth
0 extents (leafs) as well as higher-level tables.

Consider a scenario of a file which has a zero-filled beginning (e.g.
ISO image). In such case real data starts at block 8. If such a file is
stored using 2-level extent structure the extent list in the inode will
be depth 1 and will have an entry to a depth 0 (leaf) extent header for
blocks 8-n.

Unfortunately existing GRUB2 ext2 driver is only able to handle missing
entries in leaf extent tables, for which the grub_ext2_read_block()
function returns 0. In case the whole leaf extent list is missing for
a block the function fails with "invalid extent" error.

The fix for this problem relies on the grub_ext4_find_leaf() helper
function to distinguish two error cases: missing extent and error
walking through the extent tree. The existing error message is raised
only for the latter case, while for the missing leaf extent zero is
returned from grub_ext2_read_block() indicating a sparse block.

Signed-off-by: Krzysztof Nowicki <krzysztof.nowicki@nokia.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-10-04 14:38:25 +02:00
Glenn Washburn da5f6dffba fs/udf: Fix regression which is preventing symlink access
This code was broken by commit 3f05d693 (malloc: Use overflow checking
primitives where we do complex allocations), which added overflow
checking in many areas. The problem here is that the changes update the
local variable sz, which was already in use and which was not updated
before the change. So the code using sz was getting a different value of
than it would have previously for the same UDF image. This causes the
logic getting the destination of the symlink to not realize that its
gotten the full destination, but keeps trying to read past the end of
the destination. The bytes after the end are generally NULL padding
bytes, but that's not a valid component type (ECMA-167 14.16.1.1). So
grub_udf_read_symlink() branches to error logic, returning NULL, instead
of the symlink destination path.

The result of this bug is that the UDF filesystem tests were failing in
the symlink test with the grub-fstest error message:

  grub-fstest: error: cannot open `(loop0)/sym': invalid symlink.

This change stores the result of doubling sz in another local variable s,
so as not to modify sz. Also remove unnecessary grub_add(), which increased
the output by 1, presumably to account for a NULL byte. This isn't needed
because an output buffer of size twice sz is already guaranteed to be more
than enough to contain the path components converted to UTF-8. The value of
sz contains at least 4 bytes for the path component header (ECMA-167 14.16.1),
which means that 2 * 4 bytes are allocated but will not be used for UTF-8
characters, so the NULL byte is accounted for.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-09-20 13:52:55 +02:00