In the Linux kernel, the following vulnerability has been resolved:
drm/hyperv: validate resolutioncount and fix WIN8 fallback
A SYNTHVIDRESOLUTIONRESPONSE with resolutioncount > 64 walks past the supportedresolution[SYNTHVIDMAXRESOLUTIONCOUNT] array in the parse loop. Bound resolutioncount against the array size, folded into the existing zero-check.
When the WIN10 resolution probe fails, the caller in hypervconnectvsp() left hv->screenmax / preferred unpopulated, which sets modeconfig.maxwidth / maxheight to 0 and makes drminternalframebuffercreate() reject every userspace framebuffer with -EINVAL. The pre-WIN10 branch had the same gap for preferredwidth / preferredheight. Use a single post-probe fallback guarded by screenwidthmax == 0 so both paths converge on the WIN8 defaults.
In the Linux kernel, the following vulnerability has been resolved:
net/handshake: Take a long-lived file reference at submit
handshakenlacceptdoit() needs the file pointer backing req->hrsk->sksocket to survive the window between handshakereqnext() and the subsequent FDPREPARE() and getfile(). The submit-side sockhold() does not provide that. skrefcnt keeps struct sock alive, but struct socket is owned by sock->file: when the consumer fputs the last file reference, sockrelease() tears the socket down regardless of any sockhold.
Add an hrfile pointer to struct handshakereq and acquire an explicit reference on sock->file during handshakereqsubmit(). handshakecomplete() and handshakereqcancel() release the reference on the completion-bit-winning path.
The submit error path must also release the file reference, but after rhashtable insertion a concurrent handshakereqcancel() can discover the request and race the error path. Gate the error-path cleanup -- skdestruct restoration, fput, and request destruction -- with testandsetbit(HANDSHAKEFREQCOMPLETED), the same serialization handshakecomplete() and handshakereqcancel() already use. When cancel has already claimed ownership, the submit error path returns without touching the request; socket teardown handles final destruction.
The accept-side dereferences are not yet retargeted; that change comes in the next patch.
Bluetooth: fix UAF in btacceptdequeue()
In the Linux kernel, the following vulnerability has been resolved:
LoongArch: Report dying CPU to RCU in stopthiscpu()
This is a port of MIPS commit 9f3f3bdc6d9dac1 ("MIPS: smp: report dying CPU to RCU in stopthiscpu()"). smpsendstop() parks all secondary CPUs in stopthiscpu(). And the function marks the CPU offline for the scheduler via setcpuonline(false) but never informs RCU, so RCU keeps expecting a quiescent state from CPUs that are now spinning forever with interrupts disabled.
As long as nothing waits for an RCU grace period after smpsendstop() this is harmless, which is why it went unnoticed. However, since commit 91840be8f710370 ("irqwork: Fix use-after-free in irqworksingle() on PREEMPTRT"), irqworksync() calls synchronizercu() on architectures without an irqwork self-IPI, i.e. where archirqworkhasinterrupt() returns false. Any irqworksync() issued in the reboot/shutdown/halt path after smpsendstop() then blocks on a grace period that can never complete, hanging the reboot:
WARNING: CPU: 0 PID: 15 at kernel/irqwork.c:144 irqworkqueueon ... rcu: INFO: rcusched detected stalls on CPUs/tasks: rcu: Offline CPU 1 blocking current GP. rcu: Offline CPU 2 blocking current GP. rcu: Offline CPU 3 blocking current GP.
This issue needs some hacks to reproduce, and it was not noticed on LoongArch because archirqworkhasinterrupt() usually returns true.
Call rcutreereportcpudead() once interrupts are disabled, mirroring the generic CPU-hotplug offline path, so RCU stops waiting on the parked CPUs and grace periods can still complete. LoongArch shuts down all CPUs here without going through the CPU-hotplug mechanism, so this report is not otherwise issued.
In the Linux kernel, the following vulnerability has been resolved:
MIPS: smp: report dying CPU to RCU in stopthiscpu()
smpsendstop() parks all secondary CPUs in stopthiscpu(). The function marks the CPU offline for the scheduler via setcpuonline(false) but never informs RCU, so RCU keeps expecting a quiescent state from CPUs that are now spinning forever with interrupts disabled.
As long as nothing waits for an RCU grace period after smpsendstop() this is harmless, which is why it went unnoticed. Since commit 91840be8f710 ("irqwork: Fix use-after-free in irqworksingle() on PREEMPTRT") however, irqworksync() calls synchronizercu() on architectures without an irqwork self-IPI, i.e. where archirqworkhasinterrupt() returns false. That is the asm-generic default used by MIPS. Any irqworksync() issued in the reboot/shutdown path after smpsendstop() then blocks on a grace period that can never complete, hanging the reboot:
WARNING: CPU: 0 PID: 15 at kernel/irqwork.c:144 irqworkqueueon ... rcu: INFO: rcusched detected stalls on CPUs/tasks: rcu: Offline CPU 1 blocking current GP. rcu: Offline CPU 2 blocking current GP. rcu: Offline CPU 3 blocking current GP.
This issue was noticed on several Realtek MIPS switch SoCs (MIPS interAptiv) and came up during kernel bump downstream in OpenWrt from 6.18.33 to 6.18.34, after the backport of the patch to the 6.18 stable branch. The patch also has been backported all the way back to 6.1.
Call rcutreereportcpudead() once interrupts are disabled, mirroring the generic CPU-hotplug offline path, so RCU stops waiting on the parked CPUs and grace periods can still complete. MIPS shuts down all CPUs here without going through the CPU-hotplug mechanism, so this report is not otherwise issued. Reporting a dying CPU to RCU outside the regular hotplug offline path is not unprecedented: arm64 does the same in cpudieearly(). There it is an exception for a CPU that was coming online and is aborting bringup, rather than the default shutdown action as on MIPS.
In the Linux kernel, the following vulnerability has been resolved:
ASoC: codecs: simple-mux: Fix enum control bounds check
simplemuxcontrolput() rejects values greater than e->items, but enum control values are zero based. For the two-entry mux used by this driver, valid values are 0 and 1, so value 2 must be rejected as well.
Accepting e->items can store an invalid mux state, pass it to the GPIO setter, and pass it on to the DAPM mux update path where it is used as an index into the enum text array.
Use the same >= e->items check used by the ASoC enum helpers.
In the Linux kernel, the following vulnerability has been resolved:
usb: gadget: net2280: Fix double free in probe error path
usbinitializegadget() installs gadgetrelease() as the release callback for the embedded gadget device. The struct net2280 instance is therefore released through gadgetrelease() when the gadget device's last reference is dropped.
The probe error path calls net2280remove(), which tears down the partially initialized device and drops the gadget reference with usbputgadget(). Calling kfree(dev) afterwards can free the same object again.
Drop the explicit kfree() and let the gadget device release callback handle the final free. This issue was found by a static analysis tool I am developing.
gpio: rockchip: teardown bugs and resource leaks
In the Linux kernel, the following vulnerability has been resolved:
media: rc: igorplugusb: fix control request setup packet
Commit eac69475b01f ("media: rc: igorplugusb: heed coherency rules") changed the control request storage from an embedded struct to an allocated pointer so it can obey DMA coherency rules.
However, the driver still passes &ir->request to usbfillcontrolurb(). That points the URB setup packet at the pointer field itself rather than at the allocated struct usbctrlrequest.
USB core then interprets pointer bytes as the setup packet. This can produce an invalid bRequestType and trigger the control direction warning reported by syzbot:
usb 2-1: BOGUS control dir, pipe 80003580 doesn't match bRequestType 0
Pass ir->request itself as the setup packet.
In the Linux kernel, the following vulnerability has been resolved:
mm/damon/sysfs-schemes: delete tried region in regionsrmdirs()
DAMON sysfs maintains the DAMOS tried region directory objects via a linked list. When the user requests refresh of the directories, DAMON sysfs removes all the region directories first, and then generate updated regions directory on the empty space. The removal function (damonsysfsschemeregionsrmdirs()) only puts the kobj objects. Deletion of the container region object from the linked list is done inside the kobj release callback function.
If somehow the callback invocation is delayed, the list will contain regions list that gonna be freed. If the updated region directories creation is started in this situation, the list can be corrupted and use-after-free can happen.
Because the kobj objects are managed by only DAMON sysfs, the issue cannot happen in normal situation. But, such delays can be made on kernels that built with CONFIGDEBUGKOBJECTRELEASE. On the kernel, the issue can indeed be reproduced like below.
# damo start --damosaction stat # cd /sys/kernel/mm/damon/admin/kdamonds/0/ # for i in {1..10}; do echo updateschemestriedregions > state; done # dmesg | grep underflow [ 89.296152] refcountt: underflow; use-after-free.
Fix the issue by removing the region object from the list when decrementing the reference count.
Also update damossysfspopulateregiondir() to add the region object to the list only after the kobjectinitandadd() is success, so that fail of kobjectinitandadd() is not leaving the deallocated object on the list.
The issue was discovered [1] by Sashiko.
In the Linux kernel, the following vulnerability has been resolved:
gpio: shared: fix deadlock on shared proxy's parent removal
Commit 710abda58055 ("gpio: shared: call gpiochip::ofxlate() if set") used the mutex embedded in struct gpiosharedentry to protect the offset field which now can be modified after assignment. The critical section however is too wide and introduced a potential deadlock on the removal of the shared GPIO proxy's parent.
Make the critical section shorter - only protect the offset when it's being read.
While at it: mention the fact that the entry lock is now also used to protect against concurrent access to the offset field in the structure's documentation.
In the Linux kernel, the following vulnerability has been resolved:
Input: elani2c - validate firmware size before use
Ensure that the firmware file is large enough to contain the expected number of pages and the signature (which resides at the end of the firmware blob) before accessing them to prevent potential out-of-bounds reads.
In the Linux kernel, the following vulnerability has been resolved:
i2c: davinci: fix division by zero on missing clock-frequency
When the 'clock-frequency' property is missing from the device tree, the driver falls back to DAVINCII2CDEFAULTBUSFREQ. However, this macro was defined in kHz (100), whereas the device tree property is expected in Hz.
The probe function divided the fallback value by 1000, causing integer truncation that resulted in dev->busfreq = 0. This triggered a deterministic division-by-zero kernel panic when calculating clock dividers later in the probe sequence.
Fix this by redefining DAVINCII2CDEFAULTBUSFREQ in Hz (100000) to match the expected device tree property unit, allowing the existing division logic to work correctly for both cases.
In the Linux kernel, the following vulnerability has been resolved:
x86/ftrace: Relocate %rip-relative percpu refs in dynamic trampolines
With CONFIGCALLDEPTHTRACKING enabled on an x86 retbleed-affected platform (eg: Skylake), with retbleed=stuff, registering a dynamic ftrace trampoline crashes on the first call into the traced function:
BUG: unable to handle page fault for address: ffff88817ae18880 #PF: supervisor write access in kernel mode #PF: errorcode(0x0002) - not-present page PGD 4b53067 P4D 4b53067 PUD 0 Oops: Oops: 0002 [#1] SMP PTI CPU: 3 UID: 0 PID: 187 Comm: usleep Not tainted 7.0.10 #243 PREEMPT(full) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux 1.17.0-2-2 04/01/2014 Code: 24 78 00 00 00 00 48 89 ea 48 89 54 24 20 48 8b b4 24 b8 00 00 00 48 8b bc 24 b0 00 00 00 48 89 bc 24 80 00 00 00 48 83 ef 05 <65> 48 c1 3d 1f a8 b6 02 05 48 8b 15 f6 00 00 00 4c 89 3c 24 4c 89 Call Trace: <TASK> ? findheldlock ? excpagefault ? lockrelease ? x64sysclocknanosleep ? lockdephardirqsonprepare ? tracehardirqson x64sysclocknanosleep dosyscall64 ? excpagefault ? calldepthreturnthunk entrySYSCALL64afterhwframe ... Kernel panic - not syncing: Fatal exception
This small reproducer allows to easily trigger the crash:
# echo 'p x64sysclocknanosleep' > /sys/kernel/tracing/kprobeevents # echo 1 > /sys/kernel/tracing/events/kprobes/px64sysclocknanosleep0/enable # usleep 1
Monitoring the crash under GDB points to the exact instruction in charge of incrementing the call depth:
sarq $5, %gs:x86calldepth(%rip)
This instruction matches the one inserted by the ftraceregscaller from ftrace64.S. This emitted code was likely working fine until the introduction of
59bec00ace28 ("x86/percpu: Introduce %rip-relative addressing to PERCPUVAR()"):
it has made the call depth accounting addressing relative to $rip, instead of being based on an absolute address.
As this code exact location depends on where the trampoline lives in memory, the corresponding displacement needs to be adjusted at runtime to actually correctly find the per-cpu x86calldepth value, otherwise the targeted address is wrong, leading to the page fault seen above.
Fix the %rip-relative displacement of the copied CALLDEPTHACCOUNT instruction (from ftraceregscaller) by calling textpokeapplyrelocation(), as it is done for example by the x86 BPF JIT compiler through x86calldepthemitaccounting(). This corrects both CALLDEPTHACCOUNT slots, in ftracecaller and ftraceregscaller.
[ bp: Massage. ]
In the Linux kernel, the following vulnerability has been resolved:
tty: serial: pchuart: add check for dmaalloccoherent()
Add a check for dmaalloccoherent() failure to prevent a potential NULL pointer dereference in dmahandlerx(). Properly release DMA channels and the PCI device reference using a goto ladder if the allocation fails.
In the Linux kernel, the following vulnerability has been resolved:
usb: gadget: uvc: hold opts->lock across XU walks in uvcfunctionbind
uvcfunctionbind() walks &opts->extensionunits twice without holding opts->lock:
- directly, for the iExtension string-descriptor fixup loop; - indirectly, four times via uvccopydescriptors() (once per speed), where the helper iterates uvc->desc.extensionunits (which aliases &opts->extensionunits) to size and emit XU descriptors.
The configfs side (uvcgextensionmake / uvcgextensiondrop, in drivers/usb/gadget/function/uvcconfigfs.c) takes opts->lock around its listaddtail / listdel operations. A privileged userspace process that holds the configfs subtree open and writes the gadget UDC name to bind the function while concurrently rmdir()'ing an extensions subdir can race uvcgextensiondrop() against the bind-time list walks and dereference a freed struct uvcgextension.
Hold opts->lock from the start of the XU string-descriptor fixup through the last uvccopydescriptors() call, releasing on the descriptor-error path via a new errorunlock label that drops the lock before falling through to the existing error label. This matches the locking discipline of the configfs callbacks and removes the only remaining unsynchronised reader of the XU list during bind.
Reachability: only privileged processes that can mount configfs and write to gadget UDC files can trigger the race, so this is a correctness fix rather than a security boundary.
In the Linux kernel, the following vulnerability has been resolved:
net: team: fix NULL pointer dereference in teamxmit during mode change
teamchangemode() clears team->ops with memset() before restoring safe dummy handlers via teamadjustops(). A concurrent teamxmit() running under RCU on another CPU can read team->ops.transmit during this window and call a NULL function pointer, crashing the kernel.
The race requires a mode change (CAPNETADMIN) concurrent with transmit on the team device.
BUG: kernel NULL pointer dereference, address: 0000000000000000 Oops: 0010 [#1] SMP KASAN NOPTI RIP: 0010:0x0 Call Trace: teamxmit (drivers/net/team/teamcore.c:1853) devhardstartxmit (net/core/dev.c:3904) devqueuexmit (net/core/dev.c:4871) packetsendmsg (net/packet/afpacket.c:3109) syssendto (net/socket.c:2265)
The original code assumed that no ports means no traffic, so mode changes could freely memset()/memcpy() the ops. AFPACKET with forced carrier breaks that assumption.
Prevent the race instead of making it safe: replace memset()/memcpy() with per-field updates that never touch transmit or receive. Those two handlers are managed solely by teamadjustops(), which already installs dummies when txenportcount == 0 (always true during mode change since no ports are present). WRITEONCE/READONCE prevent store/load tearing on the handler pointers.
synchronizenet() before exitop() drains in-flight readers that may still reference old mode state from before port removal switched the handlers to dummies.
In the Linux kernel, the following vulnerability has been resolved:
security/keys: fix missed RCU read section on lookup
Nicholas Carlini reports that the keyring code calls assocarrayfind() in findkeytoupdate() without holding the RCU read lock, while the assocarraygc() code really is designed around removing the node from the tree and then freeing it after an RCU grace-period.
The regular key handling doesn't see this because holding the keyring semaphore hides any lifetime issues, but the persistent key handling uses a different model.
Instead of extending the keyring locking, just do the simple RCU locking that the assocarray was designed for.
In the Linux kernel, the following vulnerability has been resolved:
Input: usbtouchscreen - clamp NEXIO datalen/xlen to URB buffer size
nexioreaddata() pulls datalen and xlen from a packed be16 header in the device's interrupt packet and then walks packet->data[0..xlen) and packet->data[xlen..datalen) comparing each byte against a threshold.
Both fields are 16-bit on the wire (max 65535). The existing adjustments shave at most 0x100 / 0x80 off, so the loop bound can still reach roughly 0xfeff. The URB transfer buffer for NEXIO is reptsize (1024) bytes from usballoccoherent(), with the first 7 occupied by the packed header — so packet->data[] has 1017 valid bytes. readdata() callbacks are not given urb->actuallength, and nothing else bounds the walk.
A device that lies about its length can get a ~64 KiB out-of-bounds read past the coherent DMA allocation. The first index whose byte exceeds NEXIOTHRESHOLD lands in beginx / beginy and from there into the reported touch coordinates, so adjacent kernel memory contents leak to userspace as ABSX / ABSY events. Far enough out, the read can also hit an unmapped page and fault.
Fix this all by clamping datalen to the buffer's data[] capacity and xlen to datalen.
In the Linux kernel, the following vulnerability has been resolved:
ACPI: button: Fix ACPI GPE handler leak during removal
Commit a7e23ec17fee ("ACPI: button: Install notifier for system events as well") changed the ACPI notify handler type for ACPI buttons to ACPIALLNOTIFY, but it forgot to update acpibuttonremove() to reflect that change. This leads to leaking the notify handler past driver removal, which may cause a kernel crash to occur if ACPI notify on the given device is triggered after removing the driver, and causes a subsequent probe of the given device with the same driver to fail.
Address this by updating the acpiremovenotifyhandler() call in acpibuttonremove() as appropriate.
In multiple locations, there is a possible use after free due to a race condition. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is not needed for exploitation.
In the Linux kernel, the following vulnerability has been resolved:
nfc: llcp: Fix use-after-free race in nfcllcprecvcc()
A race condition exists in the NFC LLCP connection state machine where the connection acceptance packet (CC) can be processed concurrently with socket release. This can lead to a use-after-free of the socket object.
When nfcllcprecvcc() moves the socket from the connectingsockets list to the sockets list, it does so without holding the socket lock. If llcpsockrelease() is executing concurrently, it might have already unlinked the socket and dropped its references, which can result in nfcllcprecvcc() linking a freed socket into the live list.
Fix this by holding locksock() during the state transition and list movement in nfcllcprecvcc(). After acquiring the lock, check if the socket is still hashed to ensure it hasn't already been unlinked and marked for destruction by the release path. This aligns the locking pattern with recvhdlc() and recvdisc().
In the Linux kernel, the following vulnerability has been resolved:
xfrm: Check for underflow in xfrmstatemtu
Leo Lin reported OOB write issue in esp component:
xfrmstatemtu() returns u32 but performs its arithmetic in unsigned modulo-2^32 space using an attacker-influenced "headerlen + authsize + netadj" subtracted from a small "mtu" argument. A nobody user can install an IPv4 ESP tunnel SA with a large authentication key (XFRMAALGAUTHTRUNC, e.g. hmac(sha512), 64-byte key, 64-byte trunc), configure a small interface MTU (68 bytes), and set XFRMATFCPAD to a large value. When a single UDP datagram is then sent through the tunnel, xfrmstatemtu() underflows to a near-2^32 value, and espoutput() consumes it as a signed int via:
padto = min(x->tfcpad, xfrmstatemtu(x, mtucached)) esp.tfclen = padto - skb->len (assigned to int)
esp.tfclen ends up negative (e.g. -207). It is sign-extended to sizet when passed to memset() inside espoutputfilltrailer(), producing a ~16 EB write of zeroes at skbtailpointer(skb). KASAN logs it as "Write of size 18446744073709551537 at addr ffff888...".
Check for underflow and return 1. This causes the sendmsg attempt to fail with ENETUNREACH.
In the Linux kernel, the following vulnerability has been resolved:
In the Linux kernel, the following vulnerability has been resolved:
accel/rocket: fix UAF via dangling GEM handle in createbo
rocketioctlcreatebo() inserts a GEM handle into the file's IDR via drmgemhandlecreate() early on, then performs several operations that can fail (sgt allocation, drmmm insert, iommumap). If any fail after the handle is live, the error path calls drmgemshmemobjectfree() which kfree's the object without removing the handle from the IDR.
This leaves a dangling handle pointing to freed slab memory. Any subsequent ioctl using that handle (PREPBO, FINIBO, SUBMIT) calls drmgemobjectlookup() and dereferences freed memory (UAF).
Fix by moving drmgemhandlecreate() to after all fallible operations succeed, matching the pattern used by panfrost, lima, and etnaviv.
Also fix drmmminsertnodegeneric() whose return value was silently overwritten by iommumapsgtable() on the next line. Add the missing error check.
[tomeu: Move handle creation to the very end]
In the Linux kernel, the following vulnerability has been resolved:
netfilter: nftables: fix dst corruption in same register operation
For lshift and rshift, the shift operations are performed in a loop over 32-bit words. The loop calculates the shifted value and write it to dst, and then immediately reads from src to calculate the carry for the next iteration. Because src and dst could point to the same memory location, the carry is incorrectly calculated using the newly modified dst value instead of the original src value.
Adding a temporary local variable to cache the original value before writing to dst and using it for the carry calculation solves the problem. In addition, partial overlap is rejected from control plane for all kind of operations including byteorder. This was tested with the following bytecode:
table testtable ip flags 0 use 1 handle 1 ip testtable testchain use 3 type filter hook input prio 0 policy accept packets 0 bytes 0 flags 1 ip testtable testchain 2 [ immediate reg 1 0x44332211 0x88776655 ] [ bitwise reg 1 = ( reg 1 << 0x08000000 ) ] [ cmp eq reg 1 0x66443322 0x00887766 ] [ counter pkts 0 bytes 0 ] ip testtable testchain 4 3 [ immediate reg 1 0x44332211 0x88776655 ] [ bitwise reg 1 = ( reg 1 << 0x08000000 ) ] [ cmp eq reg 1 0x55443322 0x00887766 ] [ counter pkts 21794 bytes 1917798 ]
In the Linux kernel, the following vulnerability has been resolved:
net/smc: Do not re-initialize smc hashtables
INITHLISTHEAD(&smcvhashinfo.ht) are called after smcnlinit(), protoregister() and sockregister(). This can lead to smcvhashinfo.ht being reset even though hash entries already exist and are being used, possibly resulting in a corrupted list.
Remove unnecessary and dangerous re-initialisation of smcvhashinfo.ht in smcinit(); it is implicitly initialised to zero anyhow. Add HLISTHEADINIT to the definitions for clarity.
In the Linux kernel, the following vulnerability has been resolved:
scsi: core: Run queues for all non-SDEVDEL devices from scsirunhostqueues
While a SCSI host is in a recovery state, scsimqrequeuecmd() will not set the requeue list for a requeued command to be kicked in the future. The expectation is a call to scsirunhostqueues() will kick all SCSI devices once the recovery state is cleared.
However, scsirunhostqueues() uses shostforeachdevice() which uses scsideviceget() and so will ignore devices in a partially removed state like SDEVCANCEL. But these devices may also have requeued requests, leaving their requests stuck from not being kicked and causing the removal process of the device to hang.
scsirunhostqueues() needs to run against more devices than the macro shostforeachdevice() allows. Instead of using the too limiting scsideviceget() state checks, only ignore devices in SDEVDEL state or when unable to acquire a reference. Attempt to run the queues for all other devices when scsirunhostqueues() is called.
In the Linux kernel, the following vulnerability has been resolved:
net/iucv: fix locking in .getsockopt
Mirror iucvsocksetsockopt() and wrap the whole switch in locksock()/releasesock(). The pre-existing SOMSGLIMIT-only lock becomes redundant and is removed.
Any AFIUCV HIPER user can potentially crash the kernel by racing recvmsg() with getsockopt(SOMSGSIZE): the SOMSGSIZE arm dereferences iucv->hsdev->mtu after iucvsockclose() (called from the racing recvmsg()) has set hsdev to NULL, producing a NULL pointer dereference oops.
In the Linux kernel, the following vulnerability has been resolved:
ipv4: free net->ipv4.sysctllocalreservedports after unregisternetsysctltable()
ipv4sysctlexitnet() is currently freeing net->ipv4.sysctllocalreservedports too soon.
Only after unregisternetsysctltable() we can be sure no threads can possibly use the sysctls, including /proc/sys/net/ipv4/iplocalreservedports.