In the Linux kernel, the following vulnerability has been resolved:
nvmet-fc: avoid scheduling association deletion twice
When forcefully shutting down a port via the configfs interface, nvmetportsubsysdroplink() first calls nvmetportdelctrls() and then nvmetdisableport(). Both functions will eventually schedule all remaining associations for deletion.
The current implementation checks whether an association is about to be removed, but only after the work item has already been scheduled. As a result, it is possible for the first scheduled work item to free all resources, and then for the same work item to be scheduled again for deletion.
Because the association list is an RCU list, it is not possible to take a lock and remove the list entry directly, so it cannot be looked up again. Instead, a flag (terminating) must be used to determine whether the association is already in the process of being deleted.
In the Linux kernel, the following vulnerability has been resolved:
veth: reduce XDP nodirect return section to fix race
As explain in commit fa349e396e48 ("veth: Fix race with AFXDP exposing old or uninitialized descriptors") for veth there is a chance after napicompletedone() that another CPU can manage start another NAPI instance running vethpool(). For NAPI this is correctly handled as the napischeduleprep() check will prevent multiple instances from getting scheduled, but for the remaining code in vethpool() this can run concurrent with the newly started NAPI instance.
The problem/race is that xdpclearreturnframenodirect() isn't designed to be nested.
Prior to commit 401cb7dae813 ("net: Reference bpfredirectinfo via taskstruct on PREEMPTRT.") the temporary BPF net context bpfredirectinfo was stored per CPU, where this wasn't an issue. Since this commit the BPF context is stored in 'current' taskstruct. When running veth in threaded-NAPI mode, then the kthread becomes the storage area. Now a race exists between two concurrent vethpool() function calls one exiting NAPI and one running new NAPI, both using the same BPF net context.
Race is when another CPU gets within the xdpsetreturnframenodirect() section before exiting vethpool() calls the clear-function xdpclearreturnframenodirect().
In the Linux kernel, the following vulnerability has been resolved:
btrfs: fix double free of qgroup record after failure to add delayed ref head
In the previous code it was possible to incur into a double kfree() scenario when calling adddelayedrefhead(). This could happen if the record was reported to already exist in the btrfsqgrouptraceextentnolock() call, but then there was an error later on adddelayedrefhead(). In this case, since adddelayedrefhead() returned an error, the caller went to free the record. Since adddelayedrefhead() couldn't set this kfree'd pointer to NULL, then kfree() would have acted on a non-NULL 'record' object which was pointing to memory already freed by the callee.
The problem comes from the fact that the responsibility to kfree the object is on both the caller and the callee at the same time. Hence, the fix for this is to shift the ownership of the 'qrecord' object out of the adddelayedrefhead(). That is, we will never attempt to kfree() the given object inside of this function, and will expect the caller to act on the 'qrecord' object on its own. The only exception where the 'qrecord' object cannot be kfree'd is if it was inserted into the tracing logic, for which we already have the 'qrecordinsertedret' boolean to account for this. Hence, the caller has to kfree the object only if adddelayedrefhead() reports not to have inserted it on the tracing logic.
As a side-effect of the above, we must guarantee that 'qrecordinsertedret' is properly initialized at the start of the function, not at the end, and then set when an actual insert happens. This way we avoid 'qrecordinsertedret' having an invalid value on an early exit.
The documentation from the adddelayedrefhead() has also been updated to reflect on the exact ownership of the 'qrecord' object.
In the Linux kernel, the following vulnerability has been resolved:
ixgbe: Fix panic during XDPTX with > 64 CPUs
Commit 4fe815850bdc ("ixgbe: let the xdpdrv work with more than 64 cpus") adds support to allow XDP programs to run on systems with more than 64 CPUs by locking the XDP TX rings and indexing them using cpu % 64 (IXGBEMAXXDPQS).
Upon trying this out patch on a system with more than 64 cores, the kernel paniced with an array-index-out-of-bounds at the return in ixgbedeterminexdpring in ixgbe.h, which means ixgbedeterminexdpqidx was just returning the cpu instead of cpu % IXGBEMAXXDPQS. An example splat:
========================================================================== UBSAN: array-index-out-of-bounds in /var/lib/dkms/ixgbe/5.18.6+focal-1/build/src/ixgbe.h:1147:26 index 65 is out of range for type 'ixgbering [64]' ========================================================================== BUG: kernel NULL pointer dereference, address: 0000000000000058 #PF: supervisor read access in kernel mode #PF: errorcode(0x0000) - not-present page PGD 0 P4D 0 Oops: 0000 [#1] SMP NOPTI CPU: 65 PID: 408 Comm: ksoftirqd/65 Tainted: G IOE 5.15.0-48-generic #54~20.04.1-Ubuntu Hardware name: Dell Inc. PowerEdge R640/0W23H8, BIOS 2.5.4 01/13/2020 RIP: 0010:ixgbexmitxdpring+0x1b/0x1c0 [ixgbe] Code: 3b 52 d4 cf e9 42 f2 ff ff 66 0f 1f 44 00 00 0f 1f 44 00 00 55 b9 00 00 00 00 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 08 <44> 0f b7 47 58 0f b7 47 5a 0f b7 57 54 44 0f b7 76 08 66 41 39 c0 RSP: 0018:ffffbc3fcd88fcb0 EFLAGS: 00010282 RAX: ffff92a253260980 RBX: ffffbc3fe68b00a0 RCX: 0000000000000000 RDX: ffff928b5f659000 RSI: ffff928b5f659000 RDI: 0000000000000000 RBP: ffffbc3fcd88fce0 R08: ffff92b9dfc20580 R09: 0000000000000001 R10: 3d3d3d3d3d3d3d3d R11: 3d3d3d3d3d3d3d3d R12: 0000000000000000 R13: ffff928b2f0fa8c0 R14: ffff928b9be20050 R15: 000000000000003c FS: 0000000000000000(0000) GS:ffff92b9dfc00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000058 CR3: 000000011dd6a002 CR4: 00000000007706e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: <TASK> ixgbepoll+0x103e/0x1280 [ixgbe] ? schedclockcpu+0x12/0xe0 napipoll+0x30/0x160 netrxaction+0x11c/0x270 dosoftirq+0xda/0x2ee runksoftirqd+0x2f/0x50 smpbootthreadfn+0xb7/0x150 ? sortrange+0x30/0x30 kthread+0x127/0x150 ? setkthreadstruct+0x50/0x50 retfromfork+0x1f/0x30 </TASK>
I think this is how it happens:
Upon loading the first XDP program on a system with more than 64 CPUs, ixgbexdplockingkey is incremented in ixgbexdpsetup. However, immediately after this, the rings are reconfigured by ixgbesetuptc. ixgbesetuptc calls ixgbeclearinterruptscheme which calls ixgbefreeqvectors which calls ixgbefreeqvector in a loop. ixgbefreeqvector decrements ixgbexdplockingkey once per call if it is non-zero. Commenting out the decrement in ixgbefreeqvector stopped my system from panicing.
I suspect to make the original patch work, I would need to load an XDP program and then replace it in order to get ixgbexdplockingkey back above 0 since ixgbesetuptc is only called when transitioning between XDP and non-XDP ring configurations, while ixgbexdplockingkey is incremented every time ixgbexdpsetup is called.
Also, ixgbesetuptc can be called via ethtool --set-channels, so this becomes another path to decrement ixgbexdplockingkey to 0 on systems with more than 64 CPUs.
Since ixgbexdplockingkey only protects the XDPTX path and is tied to the number of CPUs present, there is no reason to disable it upon unloading an XDP program. To avoid confusion, I have moved enabling ixgbexdplockingkey into ixgbeswinit, which is part of the probe path.
In the Linux kernel, the following vulnerability has been resolved:
nvmet-tcp: add bounds checks in nvmettcpbuildpduiovec
nvmettcpbuildpduiovec() could walk past cmd->req.sg when a PDU length or offset exceeds sgcnt and then use bogus sg->length/offset values, leading to copytoiter() GPF/KASAN. Guard sgidx, remaining entries, and sg->length/offset before building the bvec.
In the Linux kernel, the following vulnerability has been resolved:
libceph: prevent potential out-of-bounds writes in handleauthsessionkey()
The len field originates from untrusted network packets. Boundary checks have been added to prevent potential out-of-bounds writes when decrypting the connection secret or processing service tickets.
[ idryomov: changelog ]
e1000: fix OOB in e1000tbishouldaccept()
In the Linux kernel, the following vulnerability has been resolved:
drm/gpusvm: fix hmmpfntomaporder() usage
Handle the case where the hmm range partially covers a huge page (like 2M), otherwise we can potentially end up doing something nasty like mapping memory which is outside the range, and maybe not even mapped by the mm. Fix is based on the xe userptr code, which in a future patch will directly use gpusvm, so needs alignment here.
v2: - Add kernel-doc (Matt B) - s/fls/ilog2/ (Thomas)
In the Linux kernel, the following vulnerability has been resolved:
nvme-fc: use lock accessing portstate and rport state
nvmefcunregisterremote removes the remote port on a lport object at any point in time when there is no active association. This races with with the reconnect logic, because nvmefccreateassociation is not taking a lock to check the portstate and atomically increase the active count on the rport.
In the Linux kernel, the following vulnerability has been resolved:
net/smc: use smclgrlist.lock to protect smclgrlist.list iterate in smcrportadd
While doing smcrportadd, there maybe linkgroup add into or delete from smclgrlist.list at the same time, which may result kernel crash. So, use smclgrlist.lock to protect smclgrlist.list iterate in smcrportadd.
The crash calltrace show below: BUG: kernel NULL pointer dereference, address: 0000000000000000 PGD 0 P4D 0 Oops: 0000 [#1] SMP NOPTI CPU: 0 PID: 559726 Comm: kworker/0:92 Kdump: loaded Tainted: G Hardware name: Alibaba Cloud Alibaba Cloud ECS, BIOS 449e491 04/01/2014 Workqueue: events smcibporteventwork [smc] RIP: 0010:smcrportadd+0xa6/0xf0 [smc] RSP: 0000:ffffa5a2c8f67de0 EFLAGS: 00010297 RAX: 0000000000000001 RBX: ffff9935e0650000 RCX: 0000000000000000 RDX: 0000000000000010 RSI: ffff9935e0654290 RDI: ffff9935c8560000 RBP: 0000000000000000 R08: 0000000000000000 R09: ffff9934c0401918 R10: 0000000000000000 R11: ffffffffb4a5c278 R12: ffff99364029aae4 R13: ffff99364029aa00 R14: 00000000ffffffed R15: ffff99364029ab08 FS: 0000000000000000(0000) GS:ffff994380600000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 0000000f06a10003 CR4: 0000000002770ef0 PKRU: 55555554 Call Trace: smcibporteventwork+0x18f/0x380 [smc] processonework+0x19b/0x340 workerthread+0x30/0x370 ? processonework+0x340/0x340 kthread+0x114/0x130 ? kthreadcancelwork+0x50/0x50 retfromfork+0x1f/0x30
In the Linux kernel, the following vulnerability has been resolved:
smb: client: split cachedfid bitfields to avoid shared-byte RMW races
isopen, haslease and onlist are stored in the same bitfield byte in struct cachedfid but are updated in different code paths that may run concurrently. Bitfield assignments generate byte read–modify–write operations (e.g. orb $mask, addr on x8664), so updating one flag can restore stale values of the others.
A possible interleaving is: CPU1: load old byte (haslease=1, onlist=1) CPU2: clear both flags (store 0) CPU1: RMW store (old | ISOPEN) -> reintroduces cleared bits
To avoid this class of races, convert these flags to separate bool fields.
In the Linux kernel, the following vulnerability has been resolved:
nfsd: clean up potential nfsdfile refcount leaks in COPY codepath
There are two different flavors of the nfsd4copy struct. One is embedded in the compound and is used directly in synchronous copies. The other is dynamically allocated, refcounted and tracked in the client struture. For the embedded one, the cleanup just involves releasing any nfsdfiles held on its behalf. For the async one, the cleanup is a bit more involved, and we need to dequeue it from lists, unhash it, etc.
There is at least one potential refcount leak in this code now. If the kthreadcreate call fails, then both the src and dst nfsdfiles in the original nfsd4copy object are leaked.
The cleanup in this codepath is also sort of weird. In the async copy case, we'll have up to four nfsdfile references (src and dst for both flavors of copy structure). They are both put at the end of nfsd4doasynccopy, even though the ones held on behalf of the embedded one outlive that structure.
Change it so that we always clean up the nfsdfile refs held by the embedded copy structure before nfsd4copy returns. Rework cleanupasynccopy to handle both inter and intra copies. Eliminate nfsd4cleanupintrassc since it now becomes a no-op.
In the Linux kernel, the following vulnerability has been resolved:
crypto: lib/mpi - avoid null pointer deref in mpicmpui()
During NVMeTCP Authentication a controller can trigger a kernel oops by specifying the 8192 bit Diffie Hellman group and passing a correctly sized, but zeroed Diffie Hellamn value. mpicmpui() was detecting this if the second parameter was 0, but 1 is passed from dhispubkeyvalid(). This causes the null pointer u->d to be dereferenced towards the end of mpicmpui()
In the Linux kernel, the following vulnerability has been resolved:
libceph: replace BUGON with bounds check for map->maxosd
OSD indexes come from untrusted network packets. Boundary checks are added to validate these against map->maxosd.
[ idryomov: drop BUGON in cephgetprimaryaffinity(), minor cosmetic edits ]
In the Linux kernel, the following vulnerability has been resolved:
gue: Fix skb memleak with inner IP protocol 0.
syzbot reported skb memleak below. [0]
The repro generated a GUE packet with its inner protocol 0.
gueudprecv() returns -guehdr->protoctype for "resubmit" in ipprotocoldeliverrcu(), but this only works with non-zero protocol number.
Let's drop such packets.
Note that 0 is a valid number (IPv6 Hop-by-Hop Option).
I think it is not practical to encap HOPOPT in GUE, so once someone starts to complain, we could pass down a resubmit flag pointer to distinguish two zeros from the upper layer:
no error resubmit HOPOPT
[0] BUG: memory leak unreferenced object 0xffff888109695a00 (size 240): comm "syz.0.17", pid 6088, jiffies 4294943096 hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 40 c2 10 81 88 ff ff 00 00 00 00 00 00 00 00 .@.............. backtrace (crc a84b336f): kmemleakallocrecursive include/linux/kmemleak.h:44 [inline] slabpostallochook mm/slub.c:4958 [inline] slaballocnode mm/slub.c:5263 [inline] kmemcacheallocnoprof+0x3b4/0x590 mm/slub.c:5270 buildskb+0x23/0x60 net/core/skbuff.c:474 buildskb+0x20/0x190 net/core/skbuff.c:490 tunbuildskb drivers/net/tun.c:1541 [inline] tunbuildskb+0x4a1/0xa40 drivers/net/tun.c:1636 tungetuser+0xc12/0x2030 drivers/net/tun.c:1770 tunchrwriteiter+0x71/0x120 drivers/net/tun.c:1999 newsyncwrite fs/readwrite.c:593 [inline] vfswrite+0x45d/0x710 fs/readwrite.c:686 ksyswrite+0xa7/0x170 fs/readwrite.c:738 dosyscallx64 arch/x86/entry/syscall64.c:63 [inline] dosyscall64+0xa4/0xf80 arch/x86/entry/syscall64.c:94 entrySYSCALL64afterhwframe+0x77/0x7f
In the Linux kernel, the following vulnerability has been resolved:
RDMA/siw: Fix potential NULL pointer dereference in header processing
If siwgethdr() returns -EINVAL before setrxfpducontext(), qp->rxfpdu can be NULL. The error path in siwtcprxdata() dereferences qp->rxfpdu->moreddpsegs without checking, which may lead to a NULL pointer deref. Only check moreddpsegs when rxfpdu is present.
KASAN splat: [ 101.384271] KASAN: null-ptr-deref in range [0x00000000000000c0-0x00000000000000c7] [ 101.385869] RIP: 0010:siwtcprxdata+0x13ad/0x1e50
drm/vmwgfx: Validate command header size against SVGACMDMAXDATASIZE
In the Linux kernel, the following vulnerability has been resolved:
netfilter: nftables: fix underflow in chain reference counter
Set element addition error path decrements reference counter on chains twice: once on element release and again via nftdatarelease().
Then, d6b478666ffa ("netfilter: nftables: fix underflow in object reference counter") incorrectly fixed this by removing the stateful object reference count decrement.
Restore the stateful object decrement as in b91d90368837 ("netfilter: nftables: fix leaking object reference count") and let nftdatarelease() decrement the chain reference counter, so this is done only once.
In the Linux kernel, the following vulnerability has been resolved:
ice: fix devlink reload call trace
Commit 4da71a77fc3b ("ice: read internal temperature sensor") introduced internal temperature sensor reading via HWMON. icehwmoninit() was added to iceinitfeature() and icehwmonexit() was added to iceremove(). As a result if devlink reload is used to reinit the device and then the driver is removed, a call trace can occur.
BUG: unable to handle page fault for address: ffffffffc0fd4b5d Call Trace: string+0x48/0xe0 vsnprintf+0x1f9/0x650 sprintf+0x62/0x80 nameshow+0x1f/0x30 devattrshow+0x19/0x60
The call trace repeats approximately every 10 minutes when system monitoring tools (e.g., sadc) attempt to read the orphaned hwmon sysfs attributes that reference freed module memory.
The sequence is: 1. Driver load, icehwmoninit() gets called from iceinitfeature() 2. Devlink reload down, flow does not call iceremove() 3. Devlink reload up, icehwmoninit() gets called from iceinitfeature() resulting in a second instance 4. Driver unload, icehwmonexit() called from iceremove() leaving the first hwmon instance orphaned with dangling pointer
Fix this by moving icehwmonexit() from iceremove() to icedeinitfeatures() to ensure proper cleanup symmetry with icehwmoninit().
In the Linux kernel, the following vulnerability has been resolved:
bpf, testrun: Subtract size of xdpframe from allowed metadata size
The xdpframe structure takes up part of the XDP frame headroom, limiting the size of the metadata. However, in bpftestrun, we don't take this into account, which makes it possible for userspace to supply a metadata size that is too large (taking up the entire headroom).
If userspace supplies such a large metadata size in live packet mode, the xdpupdateframefrombuff() call in xdptestruninitpage() call will fail, after which packet transmission proceeds with an uninitialised frame structure, leading to the usual Bad Stuff.
The commit in the Fixes tag fixed a related bug where the second check in xdpupdateframefrombuff() could fail, but did not add any additional constraints on the metadata size. Complete the fix by adding an additional check on the metadata size. Reorder the checks slightly to make the logic clearer and add a comment.
In the Linux kernel, the following vulnerability has been resolved:
dccp: Fix out of bounds access in DCCP error handler
There was a previous attempt to fix an out-of-bounds access in the DCCP error handlers, but that fix assumed that the error handlers only want to access the first 8 bytes of the DCCP header. Actually, they also look at the DCCP sequence number, which is stored beyond 8 bytes, so an explicit pskbmaypull() is required.
In the Linux kernel, the following vulnerability has been resolved:
hungtask: fix warnings caused by unaligned lock pointers
The blocker tracking mechanism assumes that lock pointers are at least 4-byte aligned to use their lower bits for type encoding.
However, as reported by Eero Tamminen, some architectures like m68k only guarantee 2-byte alignment of 32-bit values. This breaks the assumption and causes two related WARNONONCE checks to trigger.
To fix this, the runtime checks are adjusted to silently ignore any lock that is not 4-byte aligned, effectively disabling the feature in such cases and avoiding the related warnings.
Thanks to Geert Uytterhoeven for bisecting!
In the Linux kernel, the following vulnerability has been resolved:
net: tls: avoid hanging tasks on the txlock
syzbot sent a hung task report and Eric explains that adversarial receiver may keep RWIN at 0 for a long time, so we are not guaranteed to make forward progress. Thread which took txlock and went to sleep may not release txlock for hours. Use interruptible sleep where possible and reschedule the work if it can't take the lock.
Testing: existing selftest passes
In the Linux kernel, the following vulnerability has been resolved:
bnxten: Fix XDPTX path
For XDPTX action in bnxtrxxdp(), clearing of the event flags is not correct. bnxtpollwork() -> bnxtrxpkt() -> bnxtrxxdp() may be looping within NAPI and some event flags may be set in earlier iterations. In particular, if BNXTTXEVENT is set earlier indicating some XDPTX packets are ready and pending, it will be cleared if it is XDPTX action again. Normally, we will set BNXTTXEVENT again when we successfully call bnxtxmitxdp(). But if the TX ring has no more room, the flag will not be set. This will cause the TX producer to be ahead but the driver will not hit the TX doorbell.
For multi-buf XDPTX, there is no need to clear the event flags and set BNXTAGGEVENT. The BNXTAGGEVENT flag should have been set earlier in bnxtrxpkt().
The visible symptom of this is that the RX ring associated with the TX XDP ring will eventually become empty and all packets will be dropped. Because this condition will cause the driver to not refill the RX ring seeing that the TX ring has forever pending XDPTX packets.
The fix is to only clear BNXTRXEVENT when we have successfully called bnxtxmitxdp().
In the Linux kernel, the following vulnerability has been resolved:
libceph: prevent potential out-of-bounds reads in handleauthdone()
Perform an explicit bounds check on payloadlen to avoid a possible out-of-bounds access in the callout.
[ idryomov: changelog ]
In the Linux kernel, the following vulnerability has been resolved:
libceph: replace overzealous BUGON in osdmapapplyincremental()
If the osdmap is (maliciously) corrupted such that the incremental osdmap epoch is different from what is expected, there is no need to BUG. Instead, just declare the incremental osdmap to be invalid.
In the Linux kernel, the following vulnerability has been resolved:
nvmet: fix race in nvmetbiodone() leading to NULL pointer dereference
There is a race condition in nvmetbiodone() that can cause a NULL pointer dereference in blkcgroupbiostart():
1. nvmetbiodone() is called when a bio completes 2. nvmetreqcomplete() is called, which invokes req->ops->queueresponse(req) 3. The queueresponse callback can re-queue and re-submit the same request 4. The re-submission reuses the same inlinebio from nvmetreq 5. Meanwhile, nvmetreqbioput() (called after nvmetreqcomplete) invokes biouninit() for inlinebio, which sets bio->biblkg to NULL 6. The re-submitted bio enters submitbionoacctnocheck() 7. blkcgroupbiostart() dereferences bio->biblkg, causing a crash:
BUG: kernel NULL pointer dereference, address: 0000000000000028 #PF: supervisor read access in kernel mode RIP: 0010:blkcgroupbiostart+0x10/0xd0 Call Trace: submitbionoacctnocheck+0x44/0x250 nvmetbdevexecuterw+0x254/0x370 [nvmet] processonework+0x193/0x3c0 workerthread+0x281/0x3a0
Fix this by reordering nvmetbiodone() to call nvmetreqbioput() BEFORE nvmetreqcomplete(). This ensures the bio is cleaned up before the request can be re-submitted, preventing the race condition.
In the Linux kernel, the following vulnerability has been resolved:
nvmet-tcp: fixup hang in nvmettcplistendataready()
When the socket is closed while in TCPLISTEN a callback is run to flush all outstanding packets, which in turns calls nvmettcplistendataready() with the skcallbacklock held. So we need to check if we are in TCPLISTEN before attempting to get the skcallbacklock() to avoid a deadlock.
In the Linux kernel, the following vulnerability has been resolved:
jfs: fix invalid free of JFSIP(ipimap)->iimap in diUnmount
syzbot found an invalid-free in diUnmount:
BUG: KASAN: double-free in slabfree mm/slub.c:3661 [inline] BUG: KASAN: double-free in kmemcachefree+0x71/0x110 mm/slub.c:3674 Free of addr ffff88806f410000 by task syz-executor131/3632
CPU: 0 PID: 3632 Comm: syz-executor131 Not tainted 6.1.0-rc7-syzkaller-00012-gca57f02295f1 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 Call Trace: <TASK> dumpstack lib/dumpstack.c:88 [inline] dumpstacklvl+0x1b1/0x28e lib/dumpstack.c:106 printaddressdescription+0x74/0x340 mm/kasan/report.c:284 printreport+0x107/0x1f0 mm/kasan/report.c:395 kasanreportinvalidfree+0xac/0xd0 mm/kasan/report.c:460 kasanslabfree+0xfb/0x120 kasanslabfree include/linux/kasan.h:177 [inline] slabfreehook mm/slub.c:1724 [inline] slabfreefreelisthook+0x12e/0x1a0 mm/slub.c:1750 slabfree mm/slub.c:3661 [inline] kmemcachefree+0x71/0x110 mm/slub.c:3674 diUnmount+0xef/0x100 fs/jfs/jfsimap.c:195 jfsumount+0x108/0x370 fs/jfs/jfsumount.c:63 jfsputsuper+0x86/0x190 fs/jfs/super.c:194 genericshutdownsuper+0x130/0x310 fs/super.c:492 killblocksuper+0x79/0xd0 fs/super.c:1428 deactivatelockedsuper+0xa7/0xf0 fs/super.c:332 cleanupmnt+0x494/0x520 fs/namespace.c:1186 taskworkrun+0x243/0x300 kernel/taskwork.c:179 exittaskwork include/linux/taskwork.h:38 [inline] doexit+0x664/0x2070 kernel/exit.c:820 dogroupexit+0x1fd/0x2b0 kernel/exit.c:950 dosysexitgroup kernel/exit.c:961 [inline] sesysexitgroup kernel/exit.c:959 [inline] x64sysexitgroup+0x3b/0x40 kernel/exit.c:959 dosyscallx64 arch/x86/entry/common.c:50 [inline] dosyscall64+0x3d/0xb0 arch/x86/entry/common.c:80 entrySYSCALL64afterhwframe+0x63/0xcd [...]
JFSIP(ipimap)->iimap is not setting to NULL after free in diUnmount. If jfsremount() free JFSIP(ipimap)->iimap but then failed at diMount(). JFSIP(ipimap)->iimap will be freed once again. Fix this problem by setting JFSIP(ipimap)->iimap to NULL after free.
In the Linux kernel, the following vulnerability has been resolved:
hfs: fix missing hfsbnodeget() in hfsbnodecreate
Syzbot found a kernel BUG in hfsbnodeput():
kernel BUG at fs/hfs/bnode.c:466! invalid opcode: 0000 [#1] PREEMPT SMP KASAN CPU: 0 PID: 3634 Comm: kworker/u4:5 Not tainted 6.1.0-rc7-syzkaller-00190-g97ee9d1c1696 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 Workqueue: writeback wbworkfn (flush-7:0) RIP: 0010:hfsbnodeput+0x46f/0x480 fs/hfs/bnode.c:466 Code: 8a 80 ff e9 73 fe ff ff 89 d9 80 e1 07 80 c1 03 38 c1 0f 8c a0 fe ff ff 48 89 df e8 db 8a 80 ff e9 93 fe ff ff e8 a1 68 2c ff <0f> 0b e8 9a 68 2c ff 0f 0b 0f 1f 84 00 00 00 00 00 55 41 57 41 56 RSP: 0018:ffffc90003b4f258 EFLAGS: 00010293 RAX: ffffffff825e318f RBX: 0000000000000000 RCX: ffff8880739dd7c0 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: ffffc90003b4f430 R08: ffffffff825e2d9b R09: ffffed10045157d1 R10: ffffed10045157d1 R11: 1ffff110045157d0 R12: ffff8880228abe80 R13: ffff88807016c000 R14: dffffc0000000000 R15: ffff8880228abe00 FS: 0000000000000000(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fa6ebe88718 CR3: 000000001e93d000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> hfswriteinode+0x1bc/0xb40 writeinode fs/fs-writeback.c:1440 [inline] writebacksingleinode+0x4d6/0x670 fs/fs-writeback.c:1652 writebacksbinodes+0xb3b/0x18f0 fs/fs-writeback.c:1878 writebackinodeswb+0x125/0x420 fs/fs-writeback.c:1949 wbwriteback+0x440/0x7b0 fs/fs-writeback.c:2054 wbcheckstartall fs/fs-writeback.c:2176 [inline] wbdowriteback fs/fs-writeback.c:2202 [inline] wbworkfn+0x827/0xef0 fs/fs-writeback.c:2235 processonework+0x877/0xdb0 kernel/workqueue.c:2289 workerthread+0xb14/0x1330 kernel/workqueue.c:2436 kthread+0x266/0x300 kernel/kthread.c:376 retfromfork+0x1f/0x30 arch/x86/entry/entry64.S:306 </TASK>
The BUGON() is triggered at here:
/ Dispose of resources used by a node / void hfsbnodeput(struct hfsbnode node) { if (node) { <skipped> BUGON(!atomicread(&node->refcnt)); <- we have issue here!!!! <skipped> } }
By tracing the refcnt, I found the node is created by hfsbmapalloc() with refcnt 1. Then the node is used by hfsbtreewrite(). There is a missing of hfsbnodeget() after find the node. The issue happened in following path:
<alloc> hfsbmapalloc hfsbnodefind hfsbnodecreate <- allocate a new node with refcnt 1. hfsbnodeput <- decrease the refcnt
<write> hfsbtreewrite hfsbnodefind hfsbnodecreate hfsbnodefindhash <- find the node without refcnt increased. hfsbnodeput <- trigger the BUGON() since refcnt is 0.