Skip to content

exfat driver may fail to write files with a size > 4GB when used in a 32bit kernel #32

Open
@jerryatpb

Description

@jerryatpb

The exfat driver fails to write files with a size > 4GB when these conditions are met:

  • The kernel is built for a 32bit system
  • The kernel config switch CONFIG_LBDAF is not set (i.e. no files > 2TB are supported)

We stumbled upon this when integrating the driver into our 32bit embedded Linux ecosystem.

The reason for this is an integer overflow when converting number of blocks into a file position, as for instance here:
https://github.com/namjaejeon/linux-exfat-oot/blob/5.14.1/inode.c#L338
Line:
pos = EXFAT_BLK_TO_B((iblock + 1), sb);
which translates to:
pos = (iblock + 1) << sb->s_blocksize_bits;

iblock is of type sector_t. Normally this is a 64bit integer, but on a 32bit system without CONFIG_LBDAF being set, it is just 32bit.
pos, on the other hand is a full 64bit integer

Unfortunately, the compiler performs the calculation in 32bit range without issuing a warning. As a result, an overflow will occur as soon as the file size reaches 4GB

A simple fix would be:
pos = EXFAT_BLK_TO_B((loff_t)(iblock + 1), sb);
This makes sure that the left side is cast to 64bit before shifting it.

Attention:
We've located a few more such lines where potentially 32bit-overflow-prone left-shifts are done, namely:
https://github.com/namjaejeon/linux-exfat-oot/blob/5.14.1/dir.c#L171
https://github.com/namjaejeon/linux-exfat-oot/blob/5.14.1/dir.c#L187
https://github.com/namjaejeon/linux-exfat-oot/blob/5.14.1/inode.c#L249
https://github.com/namjaejeon/linux-exfat-oot/blob/5.14.1/inode.c#L338
https://github.com/namjaejeon/linux-exfat-oot/blob/5.14.1/inode.c#L357
https://github.com/namjaejeon/linux-exfat-oot/blob/5.14.1/namei.c#L402
https://github.com/namjaejeon/linux-exfat-oot/blob/5.14.1/namei.c#L1292
https://github.com/namjaejeon/linux-exfat-oot/blob/5.14.1/super.c#L592
In general, all lines where types sector_t or blkcnt_t are used with a left-shift operator should be considered.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions