An out of bounds write exists in FreeType versions 2.13.0 and below (newer versions of FreeType are not vulnerable) when attempting to parse font subglyph structures related to TrueType GX and variable font files. The vulnerable code assigns a signed short value to an unsigned long and then adds a static value causing it to wrap around and allocate too small of a heap buffer. The code then writes up to 6 signed long integers out of bounds relative to this buffer. This may result in arbitrary code execution. This vulnerability may have been exploited in the wild.
A potential denial of service vulnerability is present in versions of Apache CXF before 3.5.10, 3.6.5 and 4.0.6. In some edge cases, the CachedOutputStream instances may not be closed and, if backed by temporary files, may fill up the file system (it applies to servers and clients).
In the Linux kernel, the following vulnerability has been resolved:
ALSA: usb-audio: Fix out of bounds reads when finding clock sources
The current USB-audio driver code doesn't check bLength of each descriptor at traversing for clock descriptors. That is, when a device provides a bogus descriptor with a shorter bLength, the driver might hit out-of-bounds reads.
For addressing it, this patch adds sanity checks to the validator functions for the clock descriptor traversal. When the descriptor length is shorter than expected, it's skipped in the loop.
For the clock source and clock multiplier descriptors, we can just check bLength against the sizeof() of each descriptor type. OTOH, the clock selector descriptor of UAC2 and UAC3 has an array of bNrInPins elements and two more fields at its tail, hence those have to be checked in addition to the sizeof() check.
In the Linux kernel, the following vulnerability has been resolved:
mptcp: cope racing subflow creation in mptcprcvspaceadjust
Additional active subflows - i.e. created by the in kernel path manager - are included into the subflow list before starting the 3whs.
A racing recvmsg() spooling data received on an already established subflow would unconditionally call tcpcleanuprbuf() on all the current subflows, potentially hitting a divide by zero error on the newly created ones.
Explicitly check that the subflow is in a suitable state before invoking tcpcleanuprbuf().
i40e: fix race condition by adding filter's intermediate sync state
In the Linux kernel, the following vulnerability has been resolved:
lib/generic-radix-tree.c: Fix rare race in genradixptralloc()
If we need to increase the tree depth, allocate a new node, and then race with another thread that increased the tree depth before us, we'll still have a preallocated node that might be used later.
If we then use that node for a new non-root node, it'll still have a pointer to the old root instead of being zeroed - fix this by zeroing it in the cmpxchg failure path.
In the Linux kernel, the following vulnerability has been resolved:
memcg: protect concurrent access to memcgroupidr
Commit 73f576c04b94 ("mm: memcontrol: fix cgroup creation failure after many small jobs") decoupled the memcg IDs from the CSS ID space to fix the cgroup creation failures. It introduced IDR to maintain the memcg ID space. The IDR depends on external synchronization mechanisms for modifications. For the memcgroupidr, the idralloc() and idrreplace() happen within css callback and thus are protected through cgroupmutex from concurrent modifications. However idrremove() for memcgroupidr was not protected against concurrency and can be run concurrently for different memcgs when they hit their refcnt to zero. Fix that.
We have been seeing listlru based kernel crashes at a low frequency in our fleet for a long time. These crashes were in different part of listlru code including listlruadd(), listlrudel() and reparenting code. Upon further inspection, it looked like for a given object (dentry and inode), the superblock's listlru didn't have listlruone for the memcg of that object. The initial suspicions were either the object is not allocated through kmemcachealloclru() or somehow memcglistlrualloc() failed to allocate listlruone() for a memcg but returned success. No evidence were found for these cases.
Looking more deeply, we started seeing situations where valid memcg's id is not present in memcgroupidr and in some cases multiple valid memcgs have same id and memcgroupidr is pointing to one of them. So, the most reasonable explanation is that these situations can happen due to race between multiple idrremove() calls or race between idralloc()/idrreplace() and idrremove(). These races are causing multiple memcgs to acquire the same ID and then offlining of one of them would cleanup listlrus on the system for all of them. Later access from other memcgs to the listlru cause crashes due to missing listlruone.
In the Linux kernel, the following vulnerability has been resolved:
mlxsw: spectrumaclerp: Fix object nesting warning
ACLs in Spectrum-2 and newer ASICs can reside in the algorithmic TCAM (A-TCAM) or in the ordinary circuit TCAM (C-TCAM). The former can contain more ACLs (i.e., tc filters), but the number of masks in each region (i.e., tc chain) is limited.
In order to mitigate the effects of the above limitation, the device allows filters to share a single mask if their masks only differ in up to 8 consecutive bits. For example, dstip/25 can be represented using dstip/24 with a delta of 1 bit. The C-TCAM does not have a limit on the number of masks being used (and therefore does not support mask aggregation), but can contain a limited number of filters.
The driver uses the "objagg" library to perform the mask aggregation by passing it objects that consist of the filter's mask and whether the filter is to be inserted into the A-TCAM or the C-TCAM since filters in different TCAMs cannot share a mask.
The set of created objects is dependent on the insertion order of the filters and is not necessarily optimal. Therefore, the driver will periodically ask the library to compute a more optimal set ("hints") by looking at all the existing objects.
When the library asks the driver whether two objects can be aggregated the driver only compares the provided masks and ignores the A-TCAM / C-TCAM indication. This is the right thing to do since the goal is to move as many filters as possible to the A-TCAM. The driver also forbids two identical masks from being aggregated since this can only happen if one was intentionally put in the C-TCAM to avoid a conflict in the A-TCAM.
The above can result in the following set of hints:
H1: {mask X, A-TCAM} -> H2: {mask Y, A-TCAM} // X is Y + delta H3: {mask Y, C-TCAM} -> H4: {mask Z, A-TCAM} // Y is Z + delta
After getting the hints from the library the driver will start migrating filters from one region to another while consulting the computed hints and instructing the device to perform a lookup in both regions during the transition.
Assuming a filter with mask X is being migrated into the A-TCAM in the new region, the hints lookup will return H1. Since H2 is the parent of H1, the library will try to find the object associated with it and create it if necessary in which case another hints lookup (recursive) will be performed. This hints lookup for {mask Y, A-TCAM} will either return H2 or H3 since the driver passes the library an object comparison function that ignores the A-TCAM / C-TCAM indication.
This can eventually lead to nested objects which are not supported by the library [1].
Fix by removing the object comparison function from both the driver and the library as the driver was the only user. That way the lookup will only return exact matches.
I do not have a reliable reproducer that can reproduce the issue in a timely manner, but before the fix the issue would reproduce in several minutes and with the fix it does not reproduce in over an hour.
Note that the current usefulness of the hints is limited because they include the C-TCAM indication and represent aggregation that cannot actually happen. This will be addressed in net-next.
[1] WARNING: CPU: 0 PID: 153 at lib/objagg.c:170 objaggobjparentassign+0xb5/0xd0 Modules linked in: CPU: 0 PID: 153 Comm: kworker/0:18 Not tainted 6.9.0-rc6-custom-g70fbc2c1c38b #42 Hardware name: Mellanox Technologies Ltd. MSN3700C/VMOD0008, BIOS 5.11 10/10/2018 Workqueue: mlxswcore mlxswspacltcamvregionrehashwork RIP: 0010:objaggobjparentassign+0xb5/0xd0 [...] Call Trace: objaggobjget+0x2bb/0x580 objaggobjget+0xe/0x80 mlxswspaclerpmaskget+0xb5/0xf0 mlxswspaclatcamentryadd+0xe8/0x3c0 mlxswspacltcamentrycreate+0x5e/0xa0 mlxswspacltcamvchunkmigrateone+0x16b/0x270 mlxswspacltcamvregionrehashwork+0xbe/0x510 processonework+0x151/0x370
dev/parport: fix the array out-of-bounds risk
In the Linux kernel, the following vulnerability has been resolved:
kobjectuevent: Fix OOB access within zapmodaliasenv()
zapmodaliasenv() wrongly calculates size of memory block to move, so will cause OOB memory access issue if variable MODALIAS is not the last one within its @env parameter, fixed by correcting size to memmove.
drm/amdgpu: Using uninitialized value size when calling amdgpuvcecsreloc
In the Linux kernel, the following vulnerability has been resolved:
nvmet: fix a possible leak when destroy a ctrl during qp establishment
In nvmetsqdestroy we capture sq->ctrl early and if it is non-NULL we know that a ctrl was allocated (in the admin connect request handler) and we need to release pending AERs, clear ctrl->sqs and sq->ctrl (for nvme-loop primarily), and drop the final reference on the ctrl.
However, a small window is possible where nvmetsqdestroy starts (as a result of the client giving up and disconnecting) concurrently with the nvme admin connect cmd (which may be in an early stage). But before killandconfirm of sq->ref (i.e. the admin connect managed to get an sq live reference). In this case, sq->ctrl was allocated however after it was captured in a local variable in nvmetsqdestroy. This prevented the final reference drop on the ctrl.
Solve this by re-capturing the sq->ctrl after all inflight request has completed, where for sure sq->ctrl reference is final, and move forward based on that.
This issue was observed in an environment with many hosts connecting multiple ctrls simoutanuosly, creating a delay in allocating a ctrl leading up to this race window.
In the Linux kernel, the following vulnerability has been resolved:
wifi: mt76: replace skbput with skbputzero
Avoid potentially reusing uninitialized data
drm/i915/gt: Fix potential UAF by revoke of fence registers
In the Linux kernel, the following vulnerability has been resolved:
ibmvnic: Add tx check to prevent skb leak
Below is a summary of how the driver stores a reference to an skb during transmit: txbuff[freemap[consumerindex]]->skb = newskb; freemap[consumerindex] = IBMVNICINVALIDMAP; consumerindex ++; Where variable data looks like this: freemap == [4, IBMVNICINVALIDMAP, IBMVNICINVALIDMAP, 0, 3] consumerindex^ txbuff == [skb=null, skb=, skb=, skb=null, skb=null]
The driver has checks to ensure that freemap[consumerindex] pointed to a valid index but there was no check to ensure that this index pointed to an unused/null skb address. So, if, by some chance, our freemap and txbuff lists become out of sync then we were previously risking an skb memory leak. This could then cause tcp congestion control to stop sending packets, eventually leading to ETIMEDOUT.
Therefore, add a conditional to ensure that the skb address is null. If not then warn the user (because this is still a bug that should be patched) and free the old pointer to prevent memleak/tcp problems.
In the Linux kernel, the following vulnerability has been resolved:
powerpc/eeh: avoid possible crash when edev->pdev changes
If a PCI device is removed during eehpereportedev(), edev->pdev will change and can cause a crash, hold the PCI rescan/remove lock while taking a copy of edev->pdev->bus.
In the Linux kernel, the following vulnerability has been resolved:
drm/radeon: check bova->bo is non-NULL before using it
The call to radeonvmclearfreed might clear bova->bo, so we have to check it before dereferencing it.
In the Linux kernel, the following vulnerability has been resolved:
firmware: csdsp: Use strnlen() on name fields in V1 wmfw files
Use strnlen() instead of strlen() on the algorithm and coefficient name string arrays in V1 wmfw files.
In V1 wmfw files the name is a NUL-terminated string in a fixed-size array. csdsp should protect against overrunning the array if the NUL terminator is missing.
In the Linux kernel, the following vulnerability has been resolved:
netfilter: nftables: prefer nftchainvalidate
nftchainvalidate already performs loop detection because a cycle will result in a call stack overflow (ctx->level >= NFTJUMPSTACKSIZE).
It also follows maps via ->validate callback in nftlookup, so there appears no reason to iterate the maps again.
nftablescheckloops() and all its helper functions can be removed. This improves ruleset load time significantly, from 23s down to 12s.
This also fixes a crash bug. Old loop detection code can result in unbounded recursion:
BUG: TASK stack guard page was hit at .... Oops: stack guard page: 0000 [#1] PREEMPT SMP KASAN CPU: 4 PID: 1539 Comm: nft Not tainted 6.10.0-rc5+ #1 [..]
with a suitable ruleset during validation of register stores.
I can't see any actual reason to attempt to check for this from nftvalidateregisterstore(), at this point the transaction is still in progress, so we don't have a full picture of the rule graph.
For nf-next it might make sense to either remove it or make this depend on table->validatestate in case we could catch an error earlier (for improved error reporting to userspace).
In the Linux kernel, the following vulnerability has been resolved:
firmware: csdsp: Fix overflow checking of wmfw header
Fix the checking that firmware file buffer is large enough for the wmfw header, to prevent overrunning the buffer.
The original code tested that the firmware data buffer contained enough bytes for the sums of the size of the structs
wmfwheader + wmfwadsp1sizes + wmfwfooter
But wmfwadsp1sizes is only used on ADSP1 firmware. For ADSP2 and Halo Core the equivalent struct is wmfwadsp2sizes, which is 4 bytes longer. So the length check didn't guarantee that there are enough bytes in the firmware buffer for a header with wmfwadsp2sizes.
This patch splits the length check into three separate parts. Each of the wmfwheader, wmfwadsp?sizes and wmfwfooter are checked separately before they are used.
firmware: csdsp: Prevent buffer overrun when processing V2 alg headers
In the Linux kernel, the following vulnerability has been resolved:
xfs: add bounds checking to xlogrecoverprocessdata
There is a lack of verification of the space occupied by fixed members of xlogopheader in the xlogrecoverprocessdata.
We can create a crafted image to trigger an out of bounds read by following these steps: 1) Mount an image of xfs, and do some file operations to leave records 2) Before umounting, copy the image for subsequent steps to simulate abnormal exit. Because umount will ensure that tailblk and headblk are the same, which will result in the inability to enter xlogrecoverprocessdata 3) Write a tool to parse and modify the copied image in step 2 4) Make the end of the xlogopheader entries only 1 byte away from xlogrecheader->hsize 5) xlogrecheader->hnumlogops++ 6) Modify xlogrecheader->hcrc
Fix: Add a check to make sure there is sufficient space to access fixed members of xlogopheader.
In the Linux kernel, the following vulnerability has been resolved:
xfs: don't walk off the end of a directory data block
This adds sanity checks for xfsdir2dataunused and xfsdir2dataentry to make sure don't stray beyond valid memory region. Before patching, the loop simply checks that the start offset of the dup and dep is within the range. So in a crafted image, if last entry is xfsdir2dataunused, we can change dup->length to dup->length-1 and leave 1 byte of space. In the next traversal, this space will be considered as dup or dep. We may encounter an out of bound read when accessing the fixed members.
In the patch, we make sure that the remaining bytes large enough to hold an unused entry before accessing xfsdir2dataunused and xfsdir2dataunused is XFSDIR2DATAALIGN byte aligned. We also make sure that the remaining bytes large enough to hold a dirent with a single-byte name before accessing xfsdir2dataentry.
In the Linux kernel, the following vulnerability has been resolved:
udp: Set SOCKRCUFREE earlier in udplibgetport().
syzkaller triggered the warning [0] in udpv4earlydemux().
In udpv[46]earlydemux() and sklookup(), we do not touch the refcount of the looked-up sk and use sockpfree() as skb->destructor, so we check SOCKRCUFREE to ensure that the sk is safe to access during the RCU grace period.
Currently, SOCKRCUFREE is flagged for a bound socket after being put into the hash table. Moreover, the SOCKRCUFREE check is done too early in udpv[46]earlydemux() and sklookup(), so there could be a small race window:
CPU1 CPU2 ---- ---- udpv4earlydemux() udplibgetport() | |- hlistaddheadrcu() |- sk = udp4libdemuxlookup() | |- DEBUGNETWARNONONCE(skisrefcounted(sk)); - socksetflag(sk, SOCKRCUFREE)
We had the same bug in TCP and fixed it in commit 871019b22d1b ("net: set SOCKRCUFREE before inserting socket into hashtable").
Let's apply the same fix for UDP.
[0]: WARNING: CPU: 0 PID: 11198 at net/ipv4/udp.c:2599 udpv4earlydemux+0x481/0xb70 net/ipv4/udp.c:2599 Modules linked in: CPU: 0 PID: 11198 Comm: syz-executor.1 Not tainted 6.9.0-g93bda33046e7 #13 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 RIP: 0010:udpv4earlydemux+0x481/0xb70 net/ipv4/udp.c:2599 Code: c5 7a 15 fe bb 01 00 00 00 44 89 e9 31 ff d3 e3 81 e3 bf ef ff ff 89 de e8 2c 74 15 fe 85 db 0f 85 02 06 00 00 e8 9f 7a 15 fe <0f> 0b e8 98 7a 15 fe 49 8d 7e 60 e8 4f 39 2f fe 49 c7 46 60 20 52 RSP: 0018:ffffc9000ce3fa58 EFLAGS: 00010293 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff8318c92c RDX: ffff888036ccde00 RSI: ffffffff8318c2f1 RDI: 0000000000000001 RBP: ffff88805a2dd6e0 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000000 R11: 0001ffffffffffff R12: ffff88805a2dd680 R13: 0000000000000007 R14: ffff88800923f900 R15: ffff88805456004e FS: 00007fc449127640(0000) GS:ffff88807dc00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fc449126e38 CR3: 000000003de4b002 CR4: 0000000000770ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000600 PKRU: 55555554 Call Trace: <TASK> iprcvfinishcore.constprop.0+0xbdd/0xd20 net/ipv4/ipinput.c:349 iprcvfinish+0xda/0x150 net/ipv4/ipinput.c:447 NFHOOK include/linux/netfilter.h:314 [inline] NFHOOK include/linux/netfilter.h:308 [inline] iprcv+0x16c/0x180 net/ipv4/ipinput.c:569 netifreceiveskbonecore+0xb3/0xe0 net/core/dev.c:5624 netifreceiveskb+0x21/0xd0 net/core/dev.c:5738 netifreceiveskbinternal net/core/dev.c:5824 [inline] netifreceiveskb+0x271/0x300 net/core/dev.c:5884 tunrxbatched drivers/net/tun.c:1549 [inline] tungetuser+0x24db/0x2c50 drivers/net/tun.c:2002 tunchrwriteiter+0x107/0x1a0 drivers/net/tun.c:2048 newsyncwrite fs/readwrite.c:497 [inline] vfswrite+0x76f/0x8d0 fs/readwrite.c:590 ksyswrite+0xbf/0x190 fs/readwrite.c:643 dosyswrite fs/readwrite.c:655 [inline] sesyswrite fs/readwrite.c:652 [inline] x64syswrite+0x41/0x50 fs/readwrite.c:652 x64syscall+0xe66/0x1990 arch/x86/include/generated/asm/syscalls64.h:2 dosyscallx64 arch/x86/entry/common.c:52 [inline] dosyscall64+0x4b/0x110 arch/x86/entry/common.c:83 entrySYSCALL64afterhwframe+0x4b/0x53 RIP: 0033:0x7fc44a68bc1f Code: 89 54 24 18 48 89 74 24 10 89 7c 24 08 e8 e9 cf f5 ff 48 8b 54 24 18 48 8b 74 24 10 41 89 c0 8b 7c 24 08 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 31 44 89 c7 48 89 44 24 08 e8 3c d0 f5 ff 48 RSP: 002b:00007fc449126c90 EFLAGS: 00000293 ORIGRAX: 0000000000000001 RAX: ffffffffffffffda RBX: 00000000004bc050 RCX: 00007fc44a68bc1f R ---truncated---
In the Linux kernel, the following vulnerability has been resolved:
filelock: Remove locks reliably when fcntl/close race is detected
The Linux kernel CVE team has assigned CVE-2024-41012 to this issue.
Upstream advisory: https://lore.kernel.org/linux-cve-announce/2024072314-CVE-2024-41012-a1cf@gregkh/T
A denial-of-service (DoS) attack was found in the mlx5 driver in the Linux kernel. A KVM guest VM using virtio-net can crash the host by sending a short packet (i.e. size < ETHHLEN). The packet may traverse through vhost-net, macvtap and vlan without any validation/drop. When this packet is presented to mlx5 driver on the host side, the kernel panic happens since mlx5core assumes the frame size is always >= ETHHLEN.
This vulnerability affects both drivers/net/tun.c and drivers/net/tap.c. CVE-2024-41091 has been assigned to the TUN side of the issue.
Reference: https://www.openwall.com/lists/oss-security/2024/07/24/4
A denial-of-service (DoS) attack was found in the mlx5 driver in the Linux kernel. A KVM guest VM using virtio-net can crash the host by sending a short packet (i.e. size < ETHHLEN). The packet may traverse through vhost-net, macvtap and vlan without any validation/drop. When this packet is presented to mlx5 driver on the host side, the kernel panic happens, since mlx5core assumes the frame size is always >= ETHHLEN.
This vulnerability affects both drivers/net/tun.c and drivers/net/tap.c. CVE-2024-41090 has been assigned to the TAP side of the issue.
Reference: https://www.openwall.com/lists/oss-security/2024/07/24/4
In the Linux kernel, the following vulnerability has been resolved:
bpf: Fix overrunning reservations in ringbuf
The BPF ring buffer internally is implemented as a power-of-2 sized circular buffer, with two logical and ever-increasing counters: consumerpos is the consumer counter to show which logical position the consumer consumed the data, and producerpos which is the producer counter denoting the amount of data reserved by all producers.
Each time a record is reserved, the producer that "owns" the record will successfully advance producer counter. In user space each time a record is read, the consumer of the data advanced the consumer counter once it finished processing. Both counters are stored in separate pages so that from user space, the producer counter is read-only and the consumer counter is read-write.
One aspect that simplifies and thus speeds up the implementation of both producers and consumers is how the data area is mapped twice contiguously back-to-back in the virtual memory, allowing to not take any special measures for samples that have to wrap around at the end of the circular buffer data area, because the next page after the last data page would be first data page again, and thus the sample will still appear completely contiguous in virtual memory.
Each record has a struct bpfringbufhdr { u32 len; u32 pgoff; } header for book-keeping the length and offset, and is inaccessible to the BPF program. Helpers like bpfringbufreserve() return (void )hdr + BPFRINGBUFHDRSZ for the BPF program to use. Bing-Jhong and Muhammad reported that it is however possible to make a second allocated memory chunk overlapping with the first chunk and as a result, the BPF program is now able to edit first chunk's header.
For example, consider the creation of a BPFMAPTYPERINGBUF map with size of 0x4000. Next, the consumerpos is modified to 0x3000 /before/ a call to bpfringbufreserve() is made. This will allocate a chunk A, which is in [0x0,0x3008], and the BPF program is able to edit [0x8,0x3008]. Now, lets allocate a chunk B with size 0x3000. This will succeed because consumerpos was edited ahead of time to pass the newprodpos - conspos > rb->mask check. Chunk B will be in range [0x3008,0x6010], and the BPF program is able to edit [0x3010,0x6010]. Due to the ring buffer memory layout mentioned earlier, the ranges [0x0,0x4000] and [0x4000,0x8000] point to the same data pages. This means that chunk B at [0x4000,0x4008] is chunk A's header. bpfringbufsubmit() / bpfringbufdiscard() use the header's pgoff to then locate the bpfringbuf itself via bpfringbufrestorefromrec(). Once chunk B modified chunk A's header, then bpfringbufcommit() refers to the wrong page and could cause a crash.
Fix it by calculating the oldest pendingpos and check whether the range from the oldest outstanding record to the newest would span beyond the ring buffer size. If that is the case, then reject the request. We've tested with the ring buffer benchmark in BPF selftests (./benchs/runbenchringbufs.sh) before/after the fix and while it seems a bit slower on some benchmarks, it is still not significantly enough to matter.
In the Linux kernel, the following vulnerability has been resolved:
HID: hid-thrustmaster: fix OOB read in thrustmasterinterrupts
Syzbot reported an slab-out-of-bounds Read in thrustmasterprobe() bug. The root case is in missing validation check of actual number of endpoints.
Code should not blindly access usbhostinterface::endpoint array, since it may contain less endpoints than code expects.
Fix it by adding missing validaion check and print an error if number of endpoints do not match expected number
In the Linux kernel, the following vulnerability has been resolved:
net/sunrpc: fix reference count leaks in rpcsysfsxprtstatechange
The refcount leak issues take place in an error handling path. When the 3rd argument buf doesn't match with "offline", "online" or "remove", the function simply returns -EINVAL and forgets to decrease the reference count of a rpcxprt object and a rpcxprtswitch object increased by rpcsysfsxprtkobjgetxprt() and rpcsysfsxprtkobjgetxprtswitch(), causing reference count leaks of both unused objects.
Fix this issue by jumping to the error handling path labelled with output when buf matches none of "offline", "online" or "remove".