In the Linux kernel, the following vulnerability has been resolved:
ext4: fix idisksize exceeding isize problem in paritally written case
It is possible for idisksize can exceed isize, triggering a warning.
genericperformwrite copied = iovitercopyfromuseratomic(len) // copied < len ext4dawriteend | ext4updateidisksize | newisize = pos + copied; | WRITEONCE(EXT4I(inode)->idisksize, newsize) // update idisksize | genericwriteend | copied = blockwriteend(copied, len) // copied = 0 | if (unlikely(copied < len)) | if (!PageUptodate(page)) | copied = 0; | if (pos + copied > inode->isize) // return false if (unlikely(copied == 0)) goto again; if (unlikely(ioviterfaultinreadable(i, bytes))) { status = -EFAULT; break; }
We get idisksize greater than isize here, which could trigger WARNING check 'isizeread(inode) < EXT4I(inode)->idisksize' while doing dio:
ext4diowriteiter iomapdiorw _iomapdiorw // return err, length is not aligned to 512 ext4handleinodeextension WARNONONCE(isizeread(inode) < EXT4I(inode)->i_disksize) // Oops
WARNING: CPU: 2 PID: 2609 at fs/ext4/file.c:319 CPU: 2 PID: 2609 Comm: aa Not tainted 6.3.0-rc2 RIP: 0010:ext4filewriteiter+0xbc7 Call Trace: vfswrite+0x3b1 ksyswrite+0x77 dosyscall_64+0x39
Fix it by updating 'copied' value before updating idisksize just like ext4writeinlinedata_end() does.
A reproducer can be found in the buganizer link below.