In the Linux kernel, the following vulnerability has been resolved:
ocfs2: reject oversized group bitmap descriptors
ocfs2validategdparent() only bounds bgbits against the parent allocator's chain geometry. A malicious descriptor can still claim a bgsize/bgbits pair that exceeds the bitmap bytes that physically fit in the group descriptor block, so later bitmap scans and bit updates can run past bgbitmap.
Add a physical-cap check based on ocfs2groupbitmapsize() for the parent allocator type and reject descriptors whose bgsize or bgbits exceed that capacity. Keep the existing chain geometry check so both the on-disk bitmap layout and the allocator metadata must agree before the descriptor is used.
Validation reproduced this kernel report: KASAN use-after-free in findnextbit+0x7f/0xc0 Read of size 8 Call trace: dumpstacklvl+0x66/0xa0 (?:?) printreport+0xd0/0x630 (?:?) findnextbit+0x7f/0xc0 (?:?) srsoaliasreturnthunk+0x5/0xfbef5 (?:?) virtaddrvalid+0x188/0x2f0 (?:?) kasanreport+0xe4/0x120 (?:?) ocfs2findmaxcontigfreebits+0x35/0x70 (fs/ocfs2/suballoc.c:1375) ocfs2blockgroupsetbits+0x472/0x4b0 (fs/ocfs2/suballoc.c:1457) ocfs2clustergroupsearch+0x16b/0x440 (fs/ocfs2/suballoc.c:86) ocfs2bgdiscontigfixresult+0x1ef/0x230 (fs/ocfs2/suballoc.c:1786) ocfs2searchchain+0x8f8/0x10a0 (fs/ocfs2/suballoc.c:1886) getpagefromfreelist+0x70e/0x2370 (?:?) lockrelease+0xc6/0x290 (?:?) dorawspinunlock+0x9a/0x100 (?:?) kasanunpoison+0x27/0x60 (?:?) bfs+0x147/0x240 (?:?) getpagefromfreelist+0x83d/0x2370 (?:?) ocfs2claimsuballocbits+0x38c/0xe70 (fs/ocfs2/suballoc.c:96) scheddomainsnumamasksclear+0x70/0xd0 (?:?) checkirqusage+0xe8/0xb70 (?:?) ocfs2claimclusters+0x18d/0x4c0 (fs/ocfs2/suballoc.c:2497) checkpath+0x24/0x50 (?:?) rcuiswatching+0x20/0x50 (?:?) checkprevadd+0xfd/0xd00 (?:?) ocfs2addclustersinbtree+0x17d/0x810 (fs/ocfs2/suballoc.c:?) foliobatchaddandmove+0x1f5/0x3d0 (?:?) ocfs2addinodedata+0xd9/0x120 (fs/ocfs2/suballoc.c:?) filemapaddfolio+0x105/0x1f0 (?:?) ocfs2writebeginnolock+0x29f7/0x2f80 (fs/ocfs2/suballoc.c:3043) ocfs2readinodeblock+0xb5/0x110 (fs/ocfs2/suballoc.c:?) downwrite+0xf5/0x180 (?:?) ocfs2writebegin+0x180/0x240 (fs/ocfs2/suballoc.c:?) markinodedirty+0x758/0x9a0 (?:?) inodetobdi+0x41/0x90 (?:?) balancedirtypagesratelimitedflags+0xf8/0x1d0 (?:?) genericperformwrite+0x252/0x440 (?:?) mntputwriteaccessfile+0x16/0x70 (?:?) fileupdatetimeflags+0xe4/0x200 (?:?) ocfs2filewriteiter+0x80a/0x1320 (fs/ocfs2/suballoc.c:?) lockacquire+0x184/0x2f0 (?:?) ksyswrite+0xd2/0x170 (?:?) apparmorfilepermission+0xf5/0x310 (?:?) readzero+0x8d/0x140 (?:?) lockisheldtype+0x8f/0x100 (?:?)
In the Linux kernel, the following vulnerability has been resolved:
ocfs2: fix use-after-free in ocfs2fault() when VMFAULTRETRY
filemapfault() may drop the mmaplock before returning VMFAULTRETRY, as documented in mm/filemap.c:
"If our return value has VMFAULTRETRY set, it's because the mmaplock may be dropped before doing I/O or by lockfoliomaybedropmmap()."
When this happens, a concurrent munmap() can call removevma() and free the vmareastruct via RCU. The saved 'vma' pointer in ocfs2fault() then becomes a dangling pointer, and the subsequent traceocfs2fault() call dereferences it -- a use-after-free.
Fix this by saving ipblkno as a plain integer before calling filemapfault(), and removing vma from the trace event. Since ipblkno is copied by value before the lock can be dropped, it remains valid regardless of what happens to the vma or inode afterward.
In the Linux kernel, the following vulnerability has been resolved:
ocfs2: validate inline data isize during inode read
When reading an inode from disk, ocfs2validateinodeblock() performs various sanity checks but does not validate the size of inline data. If the filesystem is corrupted, an inode's isize can exceed the actual inline data capacity (idcount).
This causes ocfs2dirforeachblkid() to iterate beyond the inline data buffer, triggering a use-after-free when accessing directory entries from freed memory.
In the syzbot report: - isize was 1099511627576 bytes (~1TB) - Actual inline data capacity (idcount) is typically <256 bytes - A garbage reclen (54648) caused ctx->pos to jump out of bounds - This triggered a UAF in ocfs2checkdirentry()
Fix by adding a validation check in ocfs2validateinodeblock() to ensure inodes with inline data have isize <= idcount. This catches the corruption early during inode read and prevents all downstream code from operating on invalid data.
In the Linux kernel, the following vulnerability has been resolved:
ocfs2: fix out-of-bounds write in ocfs2writeendinline
KASAN reports a use-after-free write of 4086 bytes in ocfs2writeendinline, called from ocfs2writeendnolock during a copyfilerange splice fallback on a corrupted ocfs2 filesystem mounted on a loop device. The actual bug is an out-of-bounds write past the inode block buffer, not a true use-after-free. The write overflows into an adjacent freed page, which KASAN reports as UAF.
The root cause is that ocfs2trytowriteinlinedata trusts the on-disk idcount field to determine whether a write fits in inline data. On a corrupted filesystem, idcount can exceed the physical maximum inline data capacity, causing writes to overflow the inode block buffer.
Call trace (crash path):
vfscopyfilerange (fs/readwrite.c:1634) dosplicedirect splicedirecttoactor iterfilesplicewrite ocfs2filewriteiter genericperformwrite ocfs2writeend ocfs2writeendnolock (fs/ocfs2/aops.c:1949) ocfs2writeendinline (fs/ocfs2/aops.c:1915) memcpyfromfolio <-- KASAN: write OOB
So add idcount upper bound check in ocfs2validateinodeblock() to alongside the existing isize check to fix it.
In the Linux kernel, the following vulnerability has been resolved:
ocfs2: fix possible deadlock between unlink and dioendiowrite
ocfs2unlink takes orphan dir inodelock first and then ipallocsem, while in ocfs2dioendiowrite, it acquires these locks in reverse order. This creates an ABBA lock ordering violation on lock classes ocfs2sysfilelockkey[ORPHANDIRSYSTEMINODE] and ocfs2fileipallocsemkey.
Lock Chain #0 (orphan dir inodelock -> ipallocsem): ocfs2unlink ocfs2prepareorphandir ocfs2lookuplockorphandir inodelock(orphandirinode) <- lock A ocfs2prepareorphandir ocfs2preparedirforinsert ocfs2extenddir ocfs2expandinlinedir downwrite(&oi->ipallocsem) <- Lock B
Lock Chain #1 (ipallocsem -> orphan dir inodelock): ocfs2dioendiowrite downwrite(&oi->ipallocsem) <- Lock B ocfs2delinodefromorphan() inodelock(orphandirinode) <- Lock A
Deadlock Scenario: CPU0 (unlink) CPU1 (dioendiowrite) ------ ------ inodelock(orphandirinode) downwrite(ipallocsem) downwrite(ipallocsem) inodelock(orphandirinode)
Since ipallocsem is to protect allocation changes, which is unrelated with operations in ocfs2delinodefromorphan. So move ocfs2delinodefromorphan out of ipallocsem to fix the deadlock.
In the Linux kernel, the following vulnerability has been resolved:
ocfs2: handle invalid dinode in ocfs2groupextend
[BUG] kernel BUG at fs/ocfs2/resize.c:308! Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI RIP: 0010:ocfs2groupextend+0x10aa/0x1ae0 fs/ocfs2/resize.c:308 Code: 8b8520ff ffff83f8 860f8580 030000e8 5cc3c1fe Call Trace: ... ocfs2ioctl+0x175/0x6e0 fs/ocfs2/ioctl.c:869 vfsioctl fs/ioctl.c:51 [inline] dosysioctl fs/ioctl.c:597 [inline] sesysioctl fs/ioctl.c:583 [inline] x64sysioctl+0x197/0x1e0 fs/ioctl.c:583 x64syscall+0x1144/0x26a0 arch/x86/include/generated/asm/syscalls64.h:17 dosyscallx64 arch/x86/entry/syscall64.c:63 [inline] dosyscall64+0x93/0xf80 arch/x86/entry/syscall64.c:94 entrySYSCALL64afterhwframe+0x76/0x7e ...
[CAUSE] ocfs2groupextend() assumes that the global bitmap inode block returned from ocfs2inodelock() has already been validated and BUGONs when the signature is not a dinode. That assumption is too strong for crafted filesystems because the JBD2-managed buffer path can bypass structural validation and return an invalid dinode to the resize ioctl.
[FIX] Validate the dinode explicitly in ocfs2groupextend(). If the global bitmap buffer does not contain a valid dinode, report filesystem corruption with ocfs2error() and fail the resize operation instead of crashing the kernel.
In the Linux kernel, the following vulnerability has been resolved:
ocfs2: validate group add input before caching
[BUG] OCFS2IOCGROUPADD can trigger a BUGON in ocfs2setnewbufferuptodate():
kernel BUG at fs/ocfs2/uptodate.c:509! Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI RIP: 0010:ocfs2setnewbufferuptodate+0x194/0x1e0 fs/ocfs2/uptodate.c:509 Code: ffffe88f 42b9fe4c 89e64889 dfe8b4df Call Trace: ocfs2groupadd+0x3f1/0x1510 fs/ocfs2/resize.c:507 ocfs2ioctl+0x309/0x6e0 fs/ocfs2/ioctl.c:887 vfsioctl fs/ioctl.c:51 [inline] dosysioctl fs/ioctl.c:597 [inline] sesysioctl fs/ioctl.c:583 [inline] x64sysioctl+0x197/0x1e0 fs/ioctl.c:583 x64syscall+0x1144/0x26a0 arch/x86/include/generated/asm/syscalls64.h:17 dosyscallx64 arch/x86/entry/syscall64.c:63 [inline] dosyscall64+0x93/0xf80 arch/x86/entry/syscall64.c:94 entrySYSCALL64afterhwframe+0x76/0x7e RIP: 0033:0x7bbfb55a966d
[CAUSE] ocfs2groupadd() calls ocfs2setnewbufferuptodate() on a user-controlled group block before ocfs2verifygroupandinput() validates that block number. That helper is only valid for newly allocated metadata and asserts that the block is not already present in the chosen metadata cache. The code also uses INODECACHE(inode) even though the group descriptor belongs to mainbminode and later journal accesses use that cache context instead.
[FIX] Validate the on-disk group descriptor before caching it, then add it to the metadata cache tracked by INODECACHE(mainbminode). Keep the validation failure path separate from the later cleanup path so we only remove the buffer from that cache after it has actually been inserted. This keeps the group buffer lifetime consistent across validation, journaling, and cleanup.