| Age | Commit message (Collapse) | Author |
|
git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Paolo Abeni:
"Including fixes from Bluetooth, IPsec, WiFi and CAN.
Current release - regressions:
- eth: wwan: mhi_wwan_ctrl: send a DTR drop before it can be coalesced
Previous releases - regressions:
- core:
- use a dedicated flag to track disabled napi instances
- frags: limit the truesize of a reassembly queue
- reject a negative TCP header offset in qdisc_pkt_len_segs_init()y
- tcp:
- reject unhashed sockets during established lookups
- free ireq->ipv6_opt after an RCU grace period
- ipv6:
- fix fib6 walker UAF on NLM_F_REPLACE
- raw: fix use-after-free in rawv6_send_hdrinc()
- wifi:
- mac80211: reinstate IEEE80211_TX_CTL_AMPDU, fix ath9k stall
- brcmfmac: map msgbuf RX packet IDs bidirectional, fix firmware
crash loop
- vsock: size receive SKBs from declared payload
- xfrm: fix use-after-free of migrated state in xfrm_do_migrate_state()
- bluetooth: hci_sync: copy the LE accept list under hdev->lock
- ptp: fix use-after-free in extts_fifo_show() reading tsevqs unlocked
- can: protect the receive lists with a per-device lock
- eth:
- bnxt: don't keep MSI-X vectors added before FW reserves them
- vxlan: stop rejecting dynamic FDB entries with a nexthop ID
Previous releases - always broken:
- sched: sch_qfq: prevent aggregate self-replacement
- bridge: disable MRP ports before the FDB flush in del_nbp()
- mptcp: do not use fast open on MP_JOIN subflows
- ipv6: serialize multicast router socket ownership
- bluetooth: hci_core: keep link-key filtering inside RCU
- eth:
- atl1c: drop oversized RX frames instead of panicking
- stmmac: a bunch of XDP path fixes
- b53: enable IGMP and MLD control packet CPU copies"
* tag 'net-7.4-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (170 commits)
tcp: ipv6: free ireq->ipv6_opt after an RCU grace period
mptcp: pm: kernel: use RCU to free endpoint listeners
tcp: initialize send sequence numbers before deferring TFO
net: bridge: disable MRP ports before the FDB flush in del_nbp()
net: stmmac: set XDP metadata length on the page_pool RX path
bonding: fix missing down path on speed/duplex failure after FAIL->UP
ip6mr: Serialize multicast router socket ownership
bonding: 3ad: don't set BOND_LINK_FAIL on a slave that is not up
net: ethernet: ti: am65-cpsw-nuss: Enable timestamping of unicast PTP packets
net: count last skb of each sk_backlog pass in __release_sock()
net: 8139cp: keep Rx masked while NAPI is scheduled
net/smc: don't spin in smc_rx_recvmsg() while a pipe holds spliced data
net: dsa: b53: restore the NSP IMP port 2 Gbps mode
net: ethernet: bgmac: preserve forced 2.5 Gbps link speed
l2tp: only return sessions of the given tunnel in l2tp_session_get()
tipc: raise the minimum bearer MTU to fit tunnel and crypto overhead
mptcp: do not use Fast Open on MP_JOIN subflows
tcp: ipv6: do not read ireq->pktopts from tcp_v6_send_synack()
ipv4: Call rt_add_uncached_list() if !do_cache in ip_route_input_slow().
ipv6: Flush rt->from in rt6_uncached_list_flush_dev().
...
|
|
vhost_vsock_alloc_skb() sizes the skb from iov_length(), the total guest
descriptor length. virtio_transport_inc_rx_pkt() instead adds hdr->len to
rx_bytes and buf_used, and budgets each queued skb as SKB_TRUESIZE(0). The
guest controls the descriptor length and hdr->len independently.
A guest can therefore provide a 64 KiB descriptor while declaring a zero
payload. The descriptor-sized skb remains queued, rx_bytes and buf_used
remain unchanged, and only the fixed queue-entry budget limits retention.
This is not a lifetime leak: the skb is freed when dequeued or at socket
teardown. Repeating this across connections can nevertheless exhaust host
memory. On Linux v7.2, 455 such descriptors retained 30,255,680 bytes for
a 262,144-byte receive buffer; a full-payload control retained 265,984
bytes.
Vhost previously read hdr->len and allocated pkt->buf from that value. The
conversion from virtio_vsock_pkt to sk_buff instead allocated receive skbs
from the descriptor length, introducing the allocation-accounting mismatch.
Copy the header into a stack object and validate hdr->len before allocating
the skb. Size the allocation as sizeof(hdr) + payload_len so descriptor
capacity no longer determines queued memory. Check payload_len against
len - sizeof(hdr) to avoid addition overflow on 32-bit hosts.
Fixes: 71dc9ec9ac7d ("virtio/vsock: replace virtio_vsock_pkt with sk_buff")
Cc: stable@vger.kernel.org
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Link: https://patch.msgid.link/20261004235101.1464007-1-4ncienth@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
iov_iter_get_pages2() returns a byte count that excludes the offset into
the first page, but also returns a reference to that page in pages[].
On the misaligned-I/O fallback, vhost_scsi_revert_map_iov_to_sgl() puts
pages already added to the SG list. The cleanup loop starts at
pages[npages], but accounts for its first page as PAGE_SIZE bytes
rather than PAGE_SIZE - offset. If the remaining data starts at a
non-zero offset, it can finish one page early and leave a page reference
behind.
Use PAGE_SIZE - offset for the first remaining page and clear offset for
later pages, as in the mapping loop. Without this, each affected request
leaks one page reference.
Fixes: bca939d5bcd0 ("vhost-scsi: Dynamically allocate scatterlists")
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20261023104035.6686-1-physicalmtea@gmail.com>
|
|
Initialize the completion and as hash buckets before cdev_device_add()
makes the device accessible.
Fixes: 4c8cf31885f6 ("vhost: introduce vDPA-based backend")
Assisted-by: OpenAI-Codex:GPT-5.6
Signed-off-by: Linfeng Sun <linfeng.sun.dev@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20261011-fix-null-pointer-in-vhost_vdpa_release-v2-1-66ba929971ce@gmail.com>
|
|
Enabling a backend without VHOST_SET_VRING_KICK dereferences a NULL
vq->kick in vhost_poll_start(). Reject the request with -EINVAL.
Fixes: 264ee5aa81ec ("tools/virtio: Add --reset")
Assisted-by: OpenAI-Codex:GPT-5.6
Signed-off-by: Linfeng Sun <linfeng.sun.dev@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20261011-fix-null-pointer-in-vhost_test_set_backend-v1-1-60b2f12d64c6@gmail.com>
|
|
vhost_scsi_set_endpoint() allocates command pools only for I/O
virtqueues that are already set up, but publishes the backend for every
virtqueue. Userspace can complete a skipped queue after attaching the
endpoint, then kick it with scsi_tags uninitialized and trigger the
alloc_hint warning in sbitmap_get().
Delayed virtqueue setup is not supported. Leave skipped I/O virtqueues
inactive and reject changes to the vring size or addresses while an
endpoint is attached. Userspace must clear the endpoint before changing
the vring configuration.
I found this bug myself, though the patch was written with AI assistance.
Fixes: 25b98b64e284 ("vhost scsi: alloc cmds per vq instead of session")
Assisted-by: OpenAI-Codex:GPT-5.6
Signed-off-by: Linfeng Sun <linfeng.sun.dev@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20261010-fix-warning-in-sbitmap_get-v3-1-33de562d1359@gmail.com>
|
|
vhost_get_vq_desc() returns the number of device readable (output) and
device writable (input) iovec segments. A guest can submit an eventq
descriptor chain that fills vq->iov with output segments, setting out
to ARRAY_SIZE(vq->iov) and in to zero.
When the host later queues a vhost-scsi event, vhost_scsi_do_evt_work()
uses out as the index of the first input segment. This accesses one element
beyond vq->iov and triggers an array-index-out-of-bounds report. With
panic_on_warn enabled, the report panics the host.
The event queue accepts device writable buffers only. Reject chains that
contain output segments or lack an input segment before using out as an
index. The input check prevents the out-of-bounds access, while the output
check validates the eventq descriptor direction.
I found the descriptor direction issue myself, though the patch was
written with AI assistance. The out-of-bounds read with an
output-only chain was separately reported by Jia Jia.
Fixes: a6c9af87363c ("tcm_vhost: Add hotplug/hotunplug support")
Reported-by: Jia Jia <physicalmtea@gmail.com>
Assisted-by: OpenAI-Codex:GPT-5
Signed-off-by: Linfeng Sun <linfeng.sun.dev@gmail.com>
Message-ID: <20261009-fix-arrary-index-out-of-bounds-in-vhost_scsi_complete_events-v2-1-1f7689a54735@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
vhost_scsi_handle_vq() moves pi_bytesout or pi_bytesin into the
protection sgl and subtracts those bytes from exp_data_len. The length
passed to TCM is still exp_data_len + prot_bytes.
prot_bytes comes from virtio_scsi_cmd_req_pi. With
VIRTIO_SCSI_F_T10_PI negotiated, vhost reads that header and does not
check that the CDB is a READ or WRITE. sbc_check_prot() replaces
data_length from the CDB only when the protect field is non-zero.
target_cmd_size_check() leaves a write's data_length unchanged when the
CDB size is smaller, so a command that does not get that replacement
keeps a data_length larger than the data sgl.
The KASAN report is a MODE SELECT whose header had pi_bytesout set.
The data sgl held only the parameter list. spc_emulate_modeselect()
walked data_length and read the next physical page.
Pass the data sgl length. Protected READ and WRITE still take their
length from the CDB in sbc_check_prot().
KASAN reports:
BUG: KASAN: use-after-free in spc_emulate_modeselect+0x145/0x380 [target_core_mod]
Read of size 1
spc_emulate_modeselect
__target_execute_cmd
target_execute_cmd
vhost_scsi_write_pending
transport_generic_new_cmd
__target_submit
target_queued_submit_work
process_one_work
worker_thread
kthread
ret_from_fork
ret_from_fork_asm
Fixes: 9f977ef7b671 ("vhost-scsi: Include prot_bytes into expected data transfer length")
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20261012103954.136698-1-physicalmtea@gmail.com>
|
|
vhost_add_used_n_in_order() advances start by nheads[i] but wraps it
with a single subtraction. If start + nheads[i] >= 2 * vq->num, start
can remain outside the ring.
With used-ring logging enabled, start > vq->num makes (vq->num - start)
underflow. log_write() then sets bits beyond the dirty-log bitmap,
potentially corrupting adjacent userspace memory. This is reachable on
the vhost-net TX path with VIRTIO_F_IN_ORDER: done_idx can reach
VHOST_NET_BATCH (64), triggering the issue with a 32-entry ring.
Wrap start with a mask to keep it within the ring. VHOST_SET_VRING_NUM
enforces a nonzero power-of-two ring size, allowing start to be wrapped
using & (vq->num - 1).
Fixes: 67a873df0c41 ("vhost: basic in order support")
Cc: stable@vger.kernel.org
Reviewed-by: Weibin Liu <liuwb@xiaopeng.com>
Signed-off-by: Fang Xieyan <fangxy@xiaopeng.com>
Acked-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20261020232956.99970-1-fangxy@xiaopeng.com>
|
|
The misaligned I/O fallback copies the full bounce scatterlist to the
request buffer during completion. If a data-in command transfers less
than requested, part of a newly allocated bounce page can remain unwritten.
Allocate bounce pages with __GFP_ZERO so all bytes copied during completion
have a defined value. This path is already the slow fallback for
misaligned I/O, so the added initialization cost is acceptable.
Found during an LLM-assisted source audit and validated with a QEMU/KVM
vhost-scsi target using misaligned data-in commands.
Fixes: 5ced58bfa132 ("vhost-scsi: Fix alignment handling with windows")
Cc: stable@vger.kernel.org
Assisted-by: LLM (OpenAI Codex, gpt-5.6-sol)
Signed-off-by: Shubham Antil <shubham@octane.security>
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20261020105503.75904-1-shubham@octane.security>
|
|
move_to_indirect() validates an indirect descriptor table only with
"len % sizeof(struct vring_desc)". A descriptor flagged
VRING_DESC_F_INDIRECT with len == 0 passes that test, so *desc_max is
set to 0 while *descs points at the empty table. __vringh_iov() then
copies one struct vring_desc from descs[0] -- 16 bytes past the end of
the table -- before the "indirect_count > desc_max" loop detection
aborts the walk. The over-read value is discarded when the walk aborts
and is never used to map anything, but the access itself is out of
bounds.
Reject any len smaller than one descriptor, alongside the existing
stride check, so an empty table is refused with -EINVAL and no
descriptor is ever fetched from it.
Fixes: f87d0fbb5798 ("vringh: host-side implementation of virtio rings.")
Cc: stable@vger.kernel.org
Assisted-by: Hawkeye:GLM-5.3-flash
Assisted-by: Qoder:Qwen3.8-Max
Signed-off-by: Fang Xieyan <fangxy@xiaopeng.com>
Message-ID: <20260926160755.21485-1-fangxy@xiaopeng.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
In __vringh_iov(), the F_INDIRECT branch descends into the indirect
table and continues before the descriptor accounting runs. A top-level
indirect descriptor is therefore never charged to count. If such a
descriptor sets NEXT to point back at itself, returning from the
indirect table resumes at the same top-level descriptor, which is again
not counted, so the walk never makes forward progress.
Because count stays flat and indirect_count is reset to 0 on every
return to the top-level table, neither bound in the loop check trips.
A guest can spin the vringh worker at 100% CPU inside __vringh_iov(),
an uninterruptible host DoS.
Move the descriptor accounting above the indirect switch so that a
top-level indirect descriptor is charged one top-level traversal step
before the walk descends into its table, bringing this re-entry under
the existing vrh->vring.num bound. Each top-level descriptor is still
charged at most one step and indirect_count still bounds a single
table, so legitimate chains (including the multiple-indirect case in
tools/virtio/vringh_test.c) stay within vring.num, while a cyclic
indirect descriptor is now rejected with -ELOOP.
Fixes: dbd29e075228 ("vringh: Fix loop descriptors check in the indirect cases")
Cc: Xie Yongji <xieyongji@bytedance.com>
Cc: stable@vger.kernel.org
Assisted-by: Hawkeye:GLM-5.3-flash
Assisted-by: Qoder:Qwen3.8-Max
Signed-off-by: Fang Xieyan <fangxy@xiaopeng.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260922122955.69433-2-fangxy@xiaopeng.com>
|
|
VHOST_SET_VRING_CALL releases the previous call eventfd inside
vhost_vring_ioctl() -- it swaps the new context into vq->call_ctx.ctx
and then eventfd_ctx_put()s the old one, which is a synchronous
kfree(). The parent vdpa device is only told about the change
afterwards, when vhost_vdpa_vring_ioctl() reaches ops->set_vq_cb().
Parent drivers cache the pointer handed to them in
vdpa_callback::trigger and do not take a reference on it, so
throughout that window the parent holds a dangling eventfd_ctx and may
signal it. The documentation added with the field describes what
signalling it means but says nothing about how long it stays valid.
This is the same hazard that "vhost_vdpa: assign irq bypass producer
token correctly" addressed for the irq bypass producer token, by
moving vhost_vdpa_unsetup_vq_irq() ahead of the vhost_vring_ioctl()
call. The producer token was only one of the two consumers of that
pointer; the one the parent keeps via ->set_vq_cb() was left behind
the free.
With VDUSE the window is directly reachable from userspace, because
the device emulation daemon can inject an interrupt at any time from a
different fd, and neither side shares a lock with the other: VDUSE
takes vq->irq_lock, vhost takes vhost_dev.mutex + vq->mutex.
BUG: KASAN: slab-use-after-free in _raw_spin_lock_irqsave+0x76/0xe0
Write of size 4 at addr ffff8881084e8788 by task vduse_uaf/2987
_raw_spin_lock_irqsave+0x76/0xe0
eventfd_signal_mask+0x69/0x120
vduse_dev_ioctl+0x337/0x1a60 <- vduse_vq_signal_irqfd(), inlined
__x64_sys_ioctl+0x120/0x170 <- VDUSE_VQ_INJECT_IRQ
Allocated by task 2986:
do_eventfd+0x50/0x200
__x64_sys_eventfd2+0x2e/0x40
kmalloc-64, freed 64-byte region [ffff8881084e8780, ffff8881084e87c0)
One thread loops VHOST_SET_VRING_CALL on /dev/vhost-vdpa-N with a
fresh eventfd and then unbinds it, while another loops
VDUSE_VQ_INJECT_IRQ on /dev/vduse/<name>. This reproduces in 5 out of
5 ten-second runs on v7.1.6 and 3 out of 3 on v7.2-rc6. With the patch
there are no reports in 3 out of 3 runs on either, while the same
workload still gets ~30000 interrupts per run delivered into live
eventfds, so the path is still being exercised.
Tell the parent to drop the callback before vhost_vring_ioctl() can
free the eventfd, mirroring what is already done for the bypass
producer, and restore it if the ioctl fails -- on failure the swap
never happened, the old context is still installed, and leaving the
parent without a callback would silently drop that vq's interrupts.
Clearing the callback only stops a parent from starting to use the
context; a handler that already loaded it can still be running. For
parents with a real interrupt, wait for it with synchronize_irq() on
the vq's irq. VDUSE does not implement get_vq_irq, so that case stays
covered by the teardown above.
Fixes: 5e68470f4e80 ("vdpa: Add eventfd for the vdpa callback")
Signed-off-by: Yu Zhang <yuz08559@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260918040436.47982-1-yuz08559@gmail.com>
|
|
vhost_vdpa_pa_unmap() unpins each mapping a page at a time, dirtying
each page first if the mapping is writable. Each mapping is physically
contiguous, so use unpin_user_page_range_dirty_lock() instead, which
marks every folio dirty once and drops its pins in one go. Do the same
for the pages left pinned in the vhost_vdpa_pa_map() error path.
This removes the last use of set_page_dirty_lock() in vhost.
Signed-off-by: Tal Zussman <tz2294@columbia.edu>
Message-ID: <20261031-vhost-vdpa-unpin-v1-2-94ffc9683256@columbia.edu>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
When pin_user_pages() or vhost_vdpa_map() fails, vhost_vdpa_pa_map()
is supposed to unpin the pages pinned after the last successfully
mapped chunk, i.e. the range [map_pfn, last_pfn]. The unpin is guarded
by nchunks, but nchunks is reset to 0 every time a chunk is mapped from
inside the current page list, so a failure after any such boundary
leaves that pending range pinned forever. With physically scattered
memory nearly every page list contains a boundary, so the leak happens
on practically every failed IOTLB update.
The pending range is non-empty exactly when a page has been pinned,
which last_pfn already tells us, so drop nchunks and test last_pfn.
Fixes: ad89653f79f1 ("vhost-vdpa: fix page pinning leakage in error path (rework)")
Cc: stable@vger.kernel.org
Signed-off-by: Tal Zussman <tz2294@columbia.edu>
Reported-by: Linfeng Sun <linfeng.sun.dev@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20261031-vhost-vdpa-unpin-v1-1-94ffc9683256@columbia.edu>
|
|
vhost_chr_write_iter() validates the type and size of an IOTLB update, but
does not validate its permission field. An invalid permission can therefore
reach perm_to_iommu_flags() and trigger its warning in vhost_vdpa_map().
Reject IOTLB UPDATE messages whose permission field is empty or contains
bits outside VHOST_ACCESS_RW before dispatching them to a backend.
Fixes: 4c8cf31885f6 ("vhost: introduce vDPA-based backend")
Signed-off-by: Linfeng Sun <linfeng.sun.dev@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260913-fix-vhost_chr_write_iter-v1-1-76bf1f436cfe@gmail.com>
|
|
With VIRTIO_F_IN_ORDER, one used ring element can represent multiple
buffers, so vhost_add_used_n_in_order() can write consecutive elements to
nonadjacent slots. Dirty logging combines the initial slot with a length
based on the final position, which can miss written elements or log past
the end of the ring.
Replay nheads[] after the write barrier and log the written slots,
coalescing adjacent elements and splitting at gaps and wraps.
Fixes: 67a873df0c41 ("vhost: basic in order support")
Signed-off-by: Linfeng Sun <linfeng.sun.dev@gmail.com>
Message-ID: <20260912-fix-log_write-v1-1-72c23db01268@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
putu16_iotlb() performs a write operation (__put_user / WRITE_ONCE)
but requests IOTLB translation with VHOST_MAP_RO (read-only
permission). This means the IOTLB lookup succeeds only if the page
has read permission, ignoring write permission entirely. A page
mapped read-only in the IOTLB would incorrectly allow the write,
while a page mapped write-only would incorrectly deny it.
The neighbouring getu16_iotlb() correctly uses VHOST_MAP_RO for its
read operation, and the copydesc write path (putdesc_iotlb) correctly
uses VHOST_MAP_WO, confirming this is a copy-paste error.
Fix by changing VHOST_MAP_RO to VHOST_MAP_WO to match the write
semantics of putu16_iotlb().
Fixes: 0ea9ee430111 ("vhost/vringh: add IOTLB support")
Signed-off-by: Dudu Lu <phx0fer@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260413090526.80563-1-phx0fer@gmail.com>
|
|
vhost_scsi_send_evt() is called with the event virtqueue mutex held.
If the worker is gone, the fallback currently calls
vhost_scsi_complete_events(), which tries to acquire the same mutex again
and deadlocks the caller.
Split event completion into a helper for callers that already hold the
mutex and a locking wrapper for the event worker. Use the helper on the
fallback path.
Link: https://lore.kernel.org/all/20260905005352.1E5B01F00A3D@smtp.kernel.org/
Fixes: b1b2ce58ed23 ("vhost-scsi: Handle vhost_vq_work_queue failures for events")
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260915094244.7900-3-physicalmtea@gmail.com>
|
|
vhost_scsi_send_evt() uses llist_add(), so pending events are LIFO.
vhost_scsi_complete_events() walks the detached list directly.
This can deliver a later hotplug or hotunplug event before an earlier
one.
Reverse the detached list before processing it.
This keeps delivery in enqueue order.
Fixes: a6c9af87363c ("tcm_vhost: Add hotplug/hotunplug support")
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260915094244.7900-2-physicalmtea@gmail.com>
|
|
vdpa can release pinned pages and file references before the device stops
using the corresponding mappings, allowing stale DMA to corrupt memory.
Invalidate mappings before dropping their backing references. For set_map
backends, publish an IOTLB without the invalidated range and keep the old
references if that fails. Do this immediately even within a batch.
Serialize vdpa_sim set_map updates with its worker so publishing a new map
cannot race an active transfer. Abort mlx5 map replacement when resumable
virtqueues cannot be suspended, since changing the memory region while
those queues remain active would preserve the same stale DMA window. Reject
zero-sized and wrapping invalidations before calculating their inclusive
range end.
I found this bug myself, though the patch was written with AI assistance.
Fixes: 4c8cf31885f6 ("vhost: introduce vDPA-based backend")
Assisted-by: OpenAI-Codex:GPT-5
Signed-off-by: Linfeng Sun <linfeng.sun.dev@gmail.com>
Message-ID: <20260911-fix-vdpa-iotlb-lifetime-v3-2-8766d371748e@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
The simulator translates IOTLB entries into iovecs or bvecs under
iommu_lock, then drops the lock before copying data. A concurrent DMA
unmap can delete the mapping and release its pinned backing pages while
the copy is still in progress, leading to a UAF in _copy_from_iter().
Use the existing simulator mutex to serialize DMA map changes with the
full backend work function. Also make vhost-vdpa stop device access before
unpinning the backing pages. Otherwise, waiting in the simulator DMA unmap
callback happens after the pages have already been released and cannot
protect their lifetime.
Keep iommu_lock for the IOTLB table itself and avoid adding a second
long-lived lock to the simulator.
I found this bug myself, though the patch was written with AI assistance.
Fixes: 2c53d0f64c06 ("vdpasim: vDPA device simulator")
Assisted-by: OpenAI-Codex:GPT-5
Signed-off-by: Linfeng Sun <linfeng.sun.dev@gmail.com>
Message-ID: <20260911-fix-vdpa-iotlb-lifetime-v3-1-8766d371748e@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
Pull vhost,virtio updates from Michael Tsirkin:
"This adds CPR support for vhost.
Plus some fixes, notably for a host of races we had when callback fire
around device reset"
* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost:
tools/virtio: add missing device-id/virtio.h wrapper header
vhost/vsock: add VHOST_RESET_OWNER ioctl
vhost: synchronize with RCU readers when freeing workers
vhost/vsock: re-scan TX virtqueue on device start
vhost/vsock: suppress EHOSTUNREACH fast-fail during CPR pause
vhost/vsock: split out vhost_vsock_drop_backends helper
virtio_pci: drop callback sync on reset
virtio_pci_modern: move avq cleanup from reset to del_vqs
virtio: synchronize callbacks after device reset
virtio_vdpa: implement synchronize_cbs()
platform/mellanox: mlxbf-tmfifo: implement synchronize_cbs()
um: virtio_uml: implement synchronize_cbs()
remoteproc: implement synchronize_cbs() for virtio devices
virtio_ccw: always take irq_lock in the classic interrupt handler
virtio_ccw: fix synchronize_cbs() after interrupt fallback
|
|
getu16_iotlb() and putu16_iotlb() use __get_user() and __put_user() when
the IOTLB maps to user virtual addresses. Nothing nearby checks the
translated address: that relies on the mapping having been validated
against the user's VMAs when it was set up.
Use get_user() and put_user(), which do the same single, untorn access
and also check the address. The only atomic-context use, the vdpa
simulators' notification check, now disables page faults around it, so
the might_fault() in the checked accessors stays quiet there.
This is part of getting rid of __get_user() and __put_user() entirely.
Tested-and-acked-by: Michael S. Tsirkin <mst@redhat.com>
Fixes: 42823a871fd4 ("vringh: support VA with iotlb")
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
This ioctl is needed for QEMU's CPR (checkpoint-restore) migration of
the guest with vhost-vsock device. For this to work, we need to reset
the device ownership on the source side by calling RESET_OWNER, and then
claim it on the dest side by calling SET_OWNER. We expect not to lose any
AF_VSOCK connection while this happens.
To that end, unlike the release path, RESET_OWNER keeps the guest CID
hashed: established connections survive, and host sends issued while
the device is between owners simply stay on send_pkt_queue until the
next device start drains them.
Since the device stays reachable through the CID hash, the lockless
send/cancel paths can race with the worker teardown in
vhost_workers_free(). The previous commit ("vhost: synchronize with
RCU readers when freeing workers") makes that safe.
Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260724114542.734623-6-andrey.drobyshev@virtuozzo.com>
|
|
vhost_vq_work_queue() only holds the RCU read lock while it dereferences
vq->worker and queues work on it. vhost_workers_free() however clears
the vq->worker pointers and immediately frees the workers, without
waiting for a grace period. A caller that fetched the worker right
before the pointer was cleared can therefore still be queueing work on
it while it is freed. And even when the queueing itself wins the race,
the work is never run, so its VHOST_WORK_QUEUED bit stays set and all
future attempts to queue it are silently skipped.
None of the current callers can actually hit this: net and scsi stop
their virtqueues before the workers are freed, and vsock unhashes the
device and does synchronize_rcu() of its own in vhost_vsock_dev_release()
before the workers go away. But the upcoming VHOST_RESET_OWNER support
in vhost-vsock keeps the device hashed while its workers are freed, so
the lockless send/cancel paths become able to race with the teardown.
Fix this by threading a bool 'sync' param through the chain:
vhost_dev_reset_owner()
vhost_dev_cleanup()
vhost_workers_free()
When set, after clearing the vq->worker pointers, wait for a grace
period and flush the workers so any work the last RCU readers queued
runs (clearing VHOST_WORK_QUEUED) before the workers are freed. Only
the vsock RESET_OWNER path (added in the next patch) passes sync=true;
every other teardown has already quiesced and passes false, so they do
not need to wait the grace period.
Suggested-by: Stefano Garzarella <sgarzare@redhat.com>
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260724114542.734623-5-andrey.drobyshev@virtuozzo.com>
|
|
During QEMU CPR live-update (and VHOST_RESET_OWNER in general) the guest
keeps running while the host drops and later re-attaches vhost backends.
If the guest adds a buffer to the TX virtqueue (guest->host) and kicks
while the backend is temporarily NULL (between vhost_vsock_drop_backends()
and the next vhost_vsock_start()), then the kick is delivered to the
vhost worker, handle_tx_kick() sees a NULL backend and returns, and the
kick signal is consumed. The buffer is then left in the ring.
Then upon device start vhost_vsock_start() only re-kicks the RX send
worker, never the TX VQ, so the buffer is processed only if the guest
happens to kick again. But if the guest itself is now waiting for data
from the host, it will never kick TX VQ again, and we end up in a
deadlock.
The issue itself is pre-existing, but it only manifests during a device
pause caused by VHOST_RESET_OWNER. Namely, the deadlock is reproduced
during active host->guest socat data transfer under multiple consecutive
CPR live-update's.
To fix this, in vhost_vsock_start(), after kicking the RX send worker, also
queue the TX vq poll so any buffers the guest enqueued while we were paused
get scanned.
The VHOST_RESET_OWNER ioctl itself is implemented in the following
patch, thus this patch is a preparation to support VHOST_RESET_OWNER.
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260724114542.734623-4-andrey.drobyshev@virtuozzo.com>
|
|
Earlier commit bb26ed5f3a8b ("vhost/vsock: Refuse the connection
immediately when guest isn't ready") added a fast-fail in
vhost_transport_send_pkt(). It rejects every host send with -EHOSTUNREACH
until the destination calls SET_RUNNING(1). The fast-fail condition checks
whether device's backends are dropped, and if they're, the guest is
considered to be not ready.
However, there might be other reasons for backends to be nulled. In
particular, when QEMU is performing CPR (checkpoint-restore) migration,
device ownership is being RESET and SET again, which leads to backends
drop and reattach. If we end up connecting during this window, an
AF_VSOCK client gets -EHOSTUNREACH, which is wrong.
Add an 'ever_started' flag which is set once in vhost_vsock_start() and is
never cleared. The behaviour changes to:
* When device was never started -> flag is unset -> no listener can
exist yet -> fast-fail;
* Once the device starts -> flag is set -> we don't fast-fail ->
we queue and preserve during any later stop / CPR pause.
The VHOST_RESET_OWNER ioctl is implemented in a following patch, and
without RESET_OWNER the problem we fix here isn't manifesting - thus
this patch is a preparation to support RESET_OWNER.
Important caveat: after the first start, a connect during any stopped
window is queued instead of fast-failed. That was the behaviour before
the patch bb26ed5f3a8b, and we're restoring it now. However we still
keep the behaviour originally intended by that commit (i.e. fast-fail if
there's no real listener yet) while fixing the CPR path.
Suggested-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260724114542.734623-3-andrey.drobyshev@virtuozzo.com>
|
|
Split the actual backend dropping part from vhost_vsock_stop. We're
going to need it for the VHOST_RESET_OWNER implementation in the
following patch, when vsock->dev.mutex is already taken and owner is
checked.
Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260724114542.734623-2-andrey.drobyshev@virtuozzo.com>
|
|
When VIRTIO_F_ACCESS_PLATFORM changes, cached vring pointers and IOTLB
metadata are interpreted in a different address space. Keeping them
across the transition can leave stale ring mappings in use.
Clearing d->iotlb before taking the VQ locks also lets a worker observe
a transient NULL d->iotlb and fall back to d->umem while translating a
descriptor.
Add a common vhost_clear_device_iotlb() helper for vhost-net and
vhost-vsock. Take all VQ mutexes in index order before dropping the
device-wide IOTLB, invalidate each VQ's cached ring access and metadata,
clear pending IOTLB messages, and free the old table after the handoff.
This serializes the transition with workers and prevents mixed address
space mappings.
On the first direct-to-IOTLB transition, invalidate the cached vring
addresses. When an existing device IOTLB is replaced, preserve the
GIOVA ring addresses and reset only the metadata cache. After clearing
ACCESS_PLATFORM, userspace must configure the vring addresses for the
new address mode.
vhost_vq_invalidate_access() clears desc, avail, and used together.
Treat the VQ as invalidated only when all three are NULL, since a single
GIOVA address may legitimately be zero.
Fixes: 6b1e6cc7855b ("vhost: new device IOTLB API")
Fixes: e13a6915a03f ("vhost/vsock: add IOTLB API support")
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260828085721.57816-1-physicalmtea@gmail.com>
|
|
max_io_vqs is currently validated only when a vhost-scsi device is opened.
This allows sysfs to show values larger than the driver will actually use,
e.g. writing 2048 succeeds even though vhost_scsi_open() later clamps it to
VHOST_SCSI_MAX_IO_VQ. This makes the sysfs value differ from the value that
will actually be used.
hv# echo 2048 > /sys/module/vhost_scsi/parameters/max_io_vqs
hv# cat /sys/module/vhost_scsi/parameters/max_io_vqs
2048
[ 315.630495] Invalid max_io_vqs of 2048. Using 1024.
Keep accepting out-of-range values for compatibility, but clamp them in the
module parameter setter and store the effective value. This preserves the
existing behavior that invalid values do not make module loading or sysfs
writes fail. It also makes reads report the value that will actually be
used.
With the parameter value kept in range, remove the duplicate validation
from vhost_scsi_open().
Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260802172534.260047-3-dongli.zhang@oracle.com>
|
|
vhost_scsi_open() allocates one "struct vhost_scsi_virtqueue" for each
virtqueue. With large max_io_vqs values, this array can require a
high-order contiguous allocation and trigger a page allocator warning.
hv# cat /sys/module/vhost_scsi/parameters/max_io_vqs
256
[ 766.075787] ------------[ cut here ]------------
[ 766.077030] WARNING: mm/page_alloc.c:5280 at __alloc_frozen_pages_noprof+0x32c/0x15c0, CPU#23: qemu-system-x86/5964
... ...
[ 766.080351] RIP: 0010:__alloc_frozen_pages_noprof+0x32c/0x15c0
... ...
[ 766.085813] Call Trace:
[ 766.085969] <TASK>
[ 766.086098] ? srso_alias_return_thunk+0x5/0xfbef5
[ 766.086365] ? context_struct_compute_av+0x38a/0x4b0
[ 766.086652] alloc_pages_mpol+0x9f/0x170
[ 766.086883] ___kmalloc_large_node+0xb6/0xd0
[ 766.087124] ? srso_alias_return_thunk+0x5/0xfbef5
[ 766.087389] __kmalloc_large_node_noprof+0x18/0xa0
[ 766.087655] __kmalloc_noprof+0x3a0/0x440
[ 766.087877] ? vhost_scsi_open+0xcb/0x2d0 [vhost_scsi]
[ 766.088162] vhost_scsi_open+0xcb/0x2d0 [vhost_scsi]
[ 766.088449] misc_open+0x123/0x160
[ 766.088679] chrdev_open+0xb1/0x230
[ 766.088885] ? __pfx_chrdev_open+0x10/0x10
[ 766.089157] do_dentry_open+0x11a/0x470
[ 766.089389] vfs_open+0x29/0xf0
[ 766.089596] path_openat+0x7c0/0x1100
[ 766.089821] do_file_open+0xdd/0x190
[ 766.090032] ? srso_alias_return_thunk+0x5/0xfbef5
[ 766.090332] do_sys_openat2+0x7e/0x100
[ 766.090601] __x64_sys_openat+0x51/0xa0
[ 766.090857] do_syscall_64+0xfe/0x590
[ 766.091087] entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 766.091411] RIP: 0033:0x7f9525a11fa6
The array does not require physical contiguity, so allocate it with
kvzalloc_objs() and free it with kvfree().
Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260802172534.260047-2-dongli.zhang@oracle.com>
|
|
vhost allocates a message node whenever address translation misses. If
userspace reads these messages without resolving them, repeated virtqueue
kicks can grow the pending message list until the host runs out of memory.
Virtqueue processing stops at the first translation miss and cannot make
progress until userspace installs a mapping. Keep a pointer to that
outstanding message in the virtqueue and suppress additional misses until
the node is resolved or discarded.
The pointer remains set while the message is queued for reading, copied to
userspace, or waiting on the pending list. Clear it under the IOTLB lock
when the owning node is freed. This bounds outstanding miss messages by the
fixed number of virtqueues without introducing an arbitrary queue limit.
Signed-off-by: Linfeng Sun <linfeng.sun.dev@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260903-fix-kernel-panic-in-vhost_iotlb_miss_pending_list-v1-1-39b8cd427978@gmail.com>
|
|
vhost_vdpa_config_cb() loads v->config_ctx and signals it without taking
a reference and without holding any lock:
struct eventfd_ctx *config_ctx = v->config_ctx;
if (config_ctx)
eventfd_signal(config_ctx);
VHOST_VDPA_SET_CONFIG_CALL replaces that field and drops what is normally
the last reference to the old context:
swap(ctx, v->config_ctx);
if (ctx)
eventfd_ctx_put(ctx);
eventfd_ctx_put() drops the last kref and frees the context immediately,
with no RCU grace period, so a callback that has already loaded the
pointer goes on to dereference freed memory. The two sides share no
lock: the ioctl runs under vhost_dev.mutex, while the parent invokes the
callback from its own interrupt or workqueue context.
This is not the reopen refcount underflow fixed by commit f6bbf0010ba0
("vhost-vdpa: fix use-after-free of v->config_ctx"), which was about
vhost_vdpa_config_put() leaving a stale pointer behind. Here the pointer
is maintained correctly and it is the read side that is unprotected.
With VDUSE as the parent this is reachable from userspace with access to
/dev/vduse (root by default). VDUSE_DEV_INJECT_CONFIG_IRQ queues
dev->inject, and vduse_dev_irq_inject() runs the callback under VDUSE's
own dev->irq_lock, which vhost does not hold. vduse_dev_reset() does
flush_work(&dev->inject), but VHOST_VDPA_SET_CONFIG_CALL never goes
through reset, so an inject already in flight is not waited for. A
process that injects config interrupts on the VDUSE fd while another
thread swaps the call fd on the vhost-vdpa fd hits it in seconds:
BUG: KASAN: slab-use-after-free in native_queued_spin_lock_slowpath
Read of size 4 at addr ffff888107d21808 by task kworker/u17:1/2993
Workqueue: vduse-irq vduse_dev_irq_inject
Call Trace:
native_queued_spin_lock_slowpath+0x97/0x5b0
_raw_spin_lock_irqsave+0xd4/0xe0
eventfd_signal_mask+0x69/0x120
vhost_vdpa_config_cb+0x34/0x50
vduse_dev_irq_inject+0x46/0x60
process_one_work+0x468/0x950
Allocated by task 2992:
do_eventfd+0x50/0x200
__x64_sys_eventfd2+0x2e/0x40
Freed by task 2992:
eventfd_ctx_put+0xb9/0xc0
vhost_vdpa_unlocked_ioctl+0x116c/0x2190
Add a spinlock covering every access to config_ctx, so the callback
either signals a context that is still alive or observes NULL, and the
put happens only once no callback can reach the old value.
Clearing the parent's callback before the put would not be enough: of the
in-tree set_config_cb() implementations only VDUSE takes a lock, the rest
store the pointer unlocked, so that would not order against an in-flight
invocation.
Fixes: 776f395004d8 ("vhost_vdpa: Support config interrupt in vdpa")
Signed-off-by: Yu Zhang <yuz08559@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260807100025.19750-3-yuz08559@gmail.com>
|
|
vhost_vdpa_set_config_call() swaps the eventfd_ctx_fdget() return value
into v->config_ctx before checking it, so on failure the field briefly
holds an ERR_PTR:
ctx = fd == VHOST_FILE_UNBIND ? NULL : eventfd_ctx_fdget(fd);
swap(ctx, v->config_ctx);
if (!IS_ERR_OR_NULL(ctx))
eventfd_ctx_put(ctx);
if (IS_ERR(v->config_ctx)) {
long ret = PTR_ERR(v->config_ctx);
v->config_ctx = NULL;
return ret;
}
Commit 0bde59c1723a ("vhost-vdpa: set v->config_ctx to NULL if
eventfd_ctx_fdget() fails") added that clearing, and spelled out the
invariant the rest of the file relies on: "we consider 'v->config_ctx'
valid if it is not NULL". The window between the swap and the clearing
still breaks it. vhost_vdpa_config_cb() only tests for NULL, so a config
interrupt delivered inside the window hands the ERR_PTR to
eventfd_signal().
Check the fd before installing it instead. That closes the window and
matches how vhost_vring_ioctl() handles the same failure for the vq call
fd.
It also stops a rejected fd from tearing down a config interrupt that was
working: until now the swap replaced the live context and put it, so
after an EBADF the device silently stopped delivering config interrupts
until userspace installed a new fd.
Fixes: 776f395004d8 ("vhost_vdpa: Support config interrupt in vdpa")
Signed-off-by: Yu Zhang <yuz08559@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260807100025.19750-2-yuz08559@gmail.com>
|
|
vhost_vring_set_num() accepts any non-zero power-of-two queue size that
fits in 16 bits. vhost-vdpa then passes that value to set_vq_num()
without comparing it with get_vq_num_max().
A process with access to /dev/vhost-vdpa-* can therefore configure a
queue larger than the device advertises. With vdpa_sim, the worker can
walk descriptors beyond the mapped descriptor ring. KASAN reports a
16-byte out-of-bounds read, corresponding to one vring_desc, in the
vringh IOTLB path:
BUG: KASAN: out-of-bounds in _copy_from_iter
Read of size 16
copy_from_iotlb
copydesc_iotlb
vringh_getdesc_iotlb
vdpasim_net_work
Cache get_vq_num_max() immediately after reset. Some backends derive
it from writable queue-size state, so querying it after SET_NUM may
return the current size instead of the device capability. Invalidate
the cached value before reset so a failed reset leaves SET_NUM
disabled.
For VHOST_SET_VRING_NUM, copy the complete vring state once and use
the same index and size for validation, vq->num, and set_vq_num().
This ensures that validation and use operate on the same copied values.
Fixes: 4c8cf31885f6 ("vhost: introduce vDPA-based backend")
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260810010300.132959-1-physicalmtea@gmail.com>
|
|
Pull vhost,vdpa,virtio updates from Michael Tsirkin:
- transport v3 support in virtio-mmio
- suspend support in vduse
- fixes, cleanups all over the place
* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost: (54 commits)
vduse: Add suspend
vduse: do not take rwsem at reset work flush
vduse: add F_QUEUE_READY feature
vduse: add VDUSE_SET_FEATURES ioctl
vduse: add VDUSE_GET_FEATURES ioctl
vduse: store control device pointer
tools/virtio: Fix control typo in trace agent comment
tools/virtio: Fix userspace typo in vringh test comment
vhost: reject zero-size IOTLB INVALIDATE
vdpa: Remove redundant dev_err()
virtio_ring: fix infinite loop in virtnet_poll_cleantx when device is broken
vdpa/mlx5: roll back MR update after VQ setup failure
MAINTAINERS: remove Gabriel from LiteX and fw-cfg drivers
virtio_mem: fix typo in comment
vdpa/solidrun: fix typos in snet_ctrl comments
virtio: fix article before virtio in dma-buf comment
vhost: fix inaccurate kdoc in iotlb helpers
virtio: rtc: time out alarm requests
vdpa/mlx5: fix wrong MLX5_ADDR_OF struct type in alloc_inout()
vdpa: octeon_ep: add missing MODULE_DEVICE_TABLE()
...
|
|
Reject VHOST_IOTLB_INVALIDATE messages with size == 0 to prevent
iova + size - 1 from underflowing to U64_MAX, which would
incorrectly delete the entire IOTLB.
Signed-off-by: xiongweimin <xiongweimin@kylinos.cn>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260716030236.124322-1-xiongwm2026@163.com>
|
|
Correct missing "if" in the add_range_ctx return description, and
align vhost_iotlb_alloc documentation with its NULL return on
allocation failure.
Signed-off-by: xiongweimin <xiongweimin@kylinos.cn>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260714024434.188302-1-15927021679@163.com>
|
|
The clear_user() call in VHOST_GET_FEATURES_ARRAY incorrectly starts
at argp, which is the beginning of the features array, overwriting the
data just written by copy_to_user(). It should start after the copied
elements at argp + copied * sizeof(u64) to only zero the trailing
unused space.
Use size_mul() for both the offset and length calculations so the
arithmetic stays consistent with the surrounding code and remains
overflow-safe.
Fixes: 333c515d1896 ("vhost-net: allow configuring extended features")
Signed-off-by: Yufeng Wang <wangyufeng@kylinos.cn>
Acked-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260626070438.59149-1-r4o5m6e8o@163.com>
|
|
Add tun_wake_queue() to tun.c and export it for use by vhost-net. The
function validates that the file belongs to a device implemented by
drivers/net/tun.c, in IFF_TUN as well as in IFF_TAP mode, and that the
tfile exists, dereferences the tun_struct under RCU, and delegates to
__tun_wake_queue().
vhost_net_buf_produce() now calls tun_wake_queue() after a successful
batched consume of the ring to allow the netdev subqueue to be woken up.
The point is to allow the queue to be stopped when it gets full, which is
required for traffic shaping, implemented by the following
"stop tail-drop when IFF_BACKPRESSURE is set".
As __tun_wake_queue() returns early unless IFF_BACKPRESSURE is set, a
tun/tap device that does not opt in only pays for the added check.
macvtap and ipvtap rings, which get_tap_ptr_ring() accepts too, are
unaffected: their producer is the tap_handle_frame() rx_handler and not
ndo_start_xmit, so stopping a netdev TX queue would not hold it back.
drivers/net/tap.c has no netdev_ops of its own either. No
tap_wake_queue() is needed.
cons_cnt and the wake decision are best-effort and are not reverted by
ptr_ring_unconsume(), so vhost_net_buf_unproduce() can leave the subqueue
woken over a full ring. The producer re-stops it on the next packet, and
that path only runs from vhost_net_stop_vq() and vhost_net_set_backend(),
when the consumer is going away, so a stopped queue is the correct end
state rather than a stall.
Co-developed-by: Tim Gebauer <tim.gebauer@tu-dortmund.de>
Signed-off-by: Tim Gebauer <tim.gebauer@tu-dortmund.de>
Signed-off-by: Simon Schippers <simon.schippers@tu-dortmund.de>
Link: https://patch.msgid.link/20260803183641.96882-4-simon.schippers@tu-dortmund.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
vhost_scsi_setup_vq_cmds() runs from VHOST_SCSI_SET_ENDPOINT and allocates
each command's protection scatterlist array (prot_sgl) according to the
acknowledged VIRTIO_SCSI_F_T10_PI bit. The command pools are not rebuilt
when VHOST_SET_FEATURES changes that bit later.
Although virtio feature bits must not change after feature negotiation,
vhost_scsi_set_features() currently accepts such a request after the
endpoint is active and updates acked_features. Enabling T10-PI after
endpoint setup therefore leaves prot_sgl NULL while the I/O path follows
the new feature bit.
For a 129-page protection payload, vhost_scsi_mapal() passes the missing
first chunk to sg_alloc_table_chained():
sg_alloc_table_chained(table, 129, first_chunk=NULL,
nents_first_chunk=inline_sg_cnt)
sg_pool_index() then hits:
BUG_ON(nents > SG_CHUNK_SIZE); /* 129 > 128 */
The kernel reported the following call trace and register state:
Call Trace:
<TASK>
? __sg_alloc_table+0x1d8/0x250
? __pfx_vhost_run_work_list+0x10/0x10 [vhost]
sg_alloc_table_chained+0x59/0xf0
? __pfx_sg_pool_alloc+0x10/0x10
? vhost_scsi_calc_sgls.constprop.0+0x43/0x60 [vhost_scsi]
vhost_scsi_handle_vq+0xf02/0x1700 [vhost_scsi]
? __pfx_vhost_scsi_handle_vq+0x10/0x10 [vhost_scsi]
vhost_scsi_handle_kick+0x37/0x50 [vhost_scsi]
vhost_run_work_list+0x8e/0xd0 [vhost]
vhost_task_fn+0xe1/0x210
ret_from_fork+0x348/0x540
</TASK>
RIP: 0010:0x4
CR2 = 0x4
RSP: 0018:ffffc90000dbf940 EFLAGS: 00010202
RAX: ffffffff82396810 RBX: ffff88811dc28b80 RCX: 0000000000000000
RDX: 0000000000000000 RSI: 0000000000000820 RDI: 0000000000000081
VHOST_F_LOG_ALL is a vhost-specific runtime feature and remains the only
exception.
Reject changes to any feature other than VHOST_F_LOG_ALL while the
endpoint is active. This preserves the existing runtime log toggle while
preventing feature-dependent command resources and data-path state from
becoming inconsistent. Userspace must clear the endpoint before changing
any other negotiated feature and set the endpoint up again afterward.
Fixes: bf2d650391be ("vhost-scsi: Allocate T10 PI structs only when enabled")
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260726144314.1652934-1-physicalmtea@gmail.com>
|
|
vhost-scsi translates guest response descriptors into userspace iovecs
when commands are submitted. Target-core completes those commands
asynchronously, so VHOST_SET_MEM_TABLE can replace the memory table while
an in-flight command still retains response iovecs translated through the
old table.
If the old mapping is reused after VHOST_SET_MEM_TABLE returns, command
completion can write the response to an unrelated userspace object.
Flush the vhost-scsi backend after vhost_dev_ioctl() handles a device
ioctl. This waits for in-flight commands that can still use the old
response iovecs before the ioctl returns.
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260724060919.1569170-1-physicalmtea@gmail.com>
|
|
vq->meta_iotlb[] caches the vhost_iotlb_map that backs each vring
metadata region, and iotlb_access_ok() returns early on a cache hit,
taking the hit as proof that the region has already been validated:
if (vhost_vq_meta_fetch(vq, addr, len, type))
return true;
The cache is reset on VHOST_IOTLB_UPDATE and VHOST_IOTLB_INVALIDATE, on
device IOTLB (re)initialisation and on vq reset, but not when
VHOST_SET_VRING_ADDR replaces vq->desc, vq->avail and vq->used, nor when
VHOST_SET_VRING_NUM changes the region sizes.
With a device IOTLB attached both ioctls are accepted while the vq is
live, and neither validates the addresses at ioctl time: vq_access_ok()
and vq_log_used_access_ok() return true early because the addresses are
GIOVAs, deferring validation to prefetch time. Once the cache has been
populated that deferred validation no longer runs -- vq_meta_prefetch()
hits the stale entry and returns true -- and vhost_vq_meta_fetch() keeps
translating through the old mapping as
map->addr + addr - map->start
for an address the mapping no longer covers. vhost_copy_to_user() and
vhost_copy_from_user() consume the result with __copy_to_user() and
__copy_from_user(), which do not check it either, so a subsequent used
ring update or descriptor fetch accesses memory outside the region the
IOTLB actually maps.
Reset the metadata cache whenever the vring is reconfigured, so the new
addresses are pushed back through iotlb_access_ok()'s slow path.
Fixes: f88949138058 ("vhost: introduce O(1) vq metadata cache")
Cc: stable@vger.kernel.org
Assisted-by: tencentos-corvus-ai:kimi-k3
Signed-off-by: Jun Yang <junvyyang@tencent.com>
Message-ID: <20260803014823.68623-1-juny24602@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
When T10 PI is negotiated, vhost-scsi splits protection bytes from
the data iterator before mapping the request scatterlists. A malformed
request can claim protection bytes that cover or exceed the full payload
length. The former leaves no data bytes to map, while the latter
underflows exp_data_len before advancing the iterator. Both cases can let
a zero data SGL count reach sg_alloc_table_chained(), which triggers
BUG_ON(!nents).
Reject protection lengths that cover or exceed the payload before
subtracting prot_bytes and advancing the iterator. Also propagate
negative errors from the protection SGL calculation before calling the
allocator, matching the data SGL path.
Fixes: bca939d5bcd0 ("vhost-scsi: Dynamically allocate scatterlists")
Suggested-by: Jia Jia <physicalmtea@gmail.com>
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Assisted-by: OpenAI-Codex:GPT-5
Signed-off-by: Linfeng Sun <linfeng.sun.dev@gmail.com>
Message-ID: <20260727081841.923151-1-slf@hdu.edu.cn>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
vhost_vdpa_pa_map() adds the IOVA page offset to the user-controlled map
size before computing the number of pages to pin. On 32-bit systems,
where unsigned long is narrower than u64, that addition can overflow and
the code can pin and map fewer pages than the requested IOTLB range.
Reject sizes that overflow the unsigned long page-count calculation.
Fixes: 22af48cf91aa ("vdpa: factor out vhost_vdpa_pa_map() and vhost_vdpa_pa_unmap()")
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <CAMuQ4bX-iDvcUOPPY+NLz95tkRJYwWqvzAr=U48uNaub_HZLGw@mail.gmail.com>
|
|
vhost_iotlb_add_range_ctx() only retires an old entry when the table
has a non-zero limit, has exactly reached that limit and has
VHOST_IOTLB_FLAG_RETIRE set. Non-retiring tables can keep allocating
entries after reaching their configured limit.
Existing vhost devices allocate their IOTLB with max_iotlb_entries from
vhost.c, which defaults to 2048 and is tunable by module parameter. Use
the caller-provided limit at the allocation point instead of adding a
separate default in the common IOTLB helper, and reject non-positive
values in vhost paths that can report an error.
Other vhost IOTLB users should not create zero-limit tables when entries
can be populated from userspace or guest-controlled requests. Add
caller-side max_iotlb_entries parameters for mlx5 vDPA, VDUSE and
vhost-vDPA. Reject non-positive VDUSE and vhost-vDPA values, and require
at least two entries for vdpa_sim and mlx5 vDPA paths that install
full-range mappings, since those mappings are split into two IOTLB
entries.
Handle full-range mappings in the common helper by checking that the
IOTLB can hold both split entries before inserting the first half. This
avoids returning an error after leaving a half mapping behind.
When the table is full, keep the existing retire behavior for retiring
tables and return -ENOSPC for non-retiring tables. Reuse the retired map
node instead of freeing it and allocating a replacement, so a stream of
IOTLB updates cannot keep forcing GFP_ATOMIC allocations after the table
has reached its limit. If a zero-limit IOTLB still reaches the common
helper, treat it as a configuration error and return -EINVAL.
I found this bug myself, though the patch was written with AI assistance.
Fixes: 0bbe30668d89 ("vhost: factor out IOTLB")
Assisted-by: OpenAI-Codex:GPT-5
Signed-off-by: Linfeng Sun <linfeng.sun.dev@gamil.com>
Message-ID: <AMYAtgAiKmgYcSQT5ukl-4qq.3.1781960405943.Hmail.241270009@hdu.edu.cn>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
This reverts commit baf808fe4fcd35767ab732b4ab2ea80dabfd97a6.
There is no netdev queue left to wake after reverting
commit 1d6e569b7d0c ("tun/tap & vhost-net: avoid ptr_ring tail-drop
when a qdisc is present").
Signed-off-by: Simon Schippers <simon.schippers@tu-dortmund.de>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Link: https://patch.msgid.link/20260728092240.250257-4-simon.schippers@tu-dortmund.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
When vhost owns the virtio-net header, i.e. when
VHOST_NET_F_VIRTIO_NET_HDR is negotiated, sock_hlen is 0,
meaning that no header will be forwarded to the TAP device.
In the current vhost_net_build_xdp() implementation,
when sock_hlen == 0, the gso pointer can point at the start of the
Ethernet frame instead of a virtio-net header.
This results in a wrong interpretation of the destination MAC address
bytes as struct virtio_net_hdr fields.
This can, for some MAC addresses, trigger -EINVAL and return early
before the TX descriptor is completed, which can stall vhost-net TX.
Before 97b2409f28e0, the gso pointer was set to the zeroed padding area,
using it as a synthetic virtio-net header. Restore that behavior.
Fixes: 97b2409f28e0 ("vhost-net: reduce one userspace copy when building XDP buff")
Signed-off-by: Enrico Zanda <enrico.zanda@arm.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Link: https://patch.msgid.link/20260708152242.2268848-1-enrico.zanda@arm.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull non-MM updates from Andrew Morton:
- "taskstats: fix TGID dead-thread stat retention" (Yiyang Chen)
Fix a taskstats TGID aggregation bug where fields added in the TGID
query path were not preserved after thread exit, and adds a kselftest
covering the regression.
- "lib/tests: string_helpers: Slight improvements" (Andy Shevchenko)
Improve lib/tests/string_helpers_kunit.c a little
- "lib/base64: decode fixes" (Josh Law)
Address minor issues in lib/base64.c
- "selftests/filelock: Make output more kselftestish" (Mark Brown)
Make the output from the ofdlocks test a bit easier for tooling to
work with. Also ignore the generated file
- "uaccess: unify inline vs outline copy_{from,to}_user() selection"
(Yury Norov)
Simplify the usercopy code by removing the selectability of inlining
copy_{from,to}_user().
- "ocfs2: validate inline xattr header consumers" (ZhengYuan Huang)
Fix a number of possible issues in the ocfs2 xattr code
- "lib and lib/cmdline enhancements" (Dmitry Antipov)
Provide additional robustness checking in the cmdline handling code
and its in-kernel testing and selftests
- "cleanup the RAID6 P/Q library" (Christoph Hellwig)
Clean up the RAID6 P/Q library to match the recent updates to the
RAID 5 XOR library and other CRC/crypto libraries
- "ocfs2: harden inode validators against forged metadata" (Michael
Bommarito)
Add three structural checks to OCFS2 dinode validation so malformed
on-disk fields are rejected before ocfs2_populate_inode() copies them
into the in-core inode
- "lib/raid: replace __get_free_pages() call with kmalloc()" (Mike
Rapoport)
Clean up the lib/raid code by using kmalloc() in more places
* tag 'mm-nonmm-stable-2026-06-21-10-22' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (108 commits)
ocfs2: fix circular locking dependency in ocfs2_dio_end_io_write
ocfs2: fix NULL h_transaction deref in ocfs2_assure_trans_credits
lib: interval_tree_test: validate benchmark parameters
ocfs2: avoid moving extents to occupied clusters
treewide: fix transposed "sign" typos and update spelling.txt
ocfs2: fix UBSAN array-index-out-of-bounds in ocfs2_sum_rightmost_rec
fat: reject BPB volumes whose data area starts beyond total sectors
selftests/uevent: increase __UEVENT_BUFFER_SIZE to avoid ENOBUFS on busy systems
lib/test_firmware: allocate the configured into_buf size
fs: efs: remove unneeded debug prints
checkpatch: cuppress warnings when Reported-by: is followed by Link:
MAINTAINERS: add Alexander as a kcov reviewer
mailmap: update Alexander Sverdlin's Email addresses
fs: fat: inode: replace sprintf() with scnprintf()
ocfs2: fix out-of-bounds write in ocfs2_remove_refcount_extent
ocfs2: fix race between ocfs2_control_install_private() and ocfs2_control_release()
ocfs2/dlm: require a ref for locking_state debugfs open
ocfs2: reject FITRIM ranges shorter than a cluster
ocfs2: validate fast symlink target during inode read
ocfs2: add journal NULL check in ocfs2_checkpoint_inode()
...
|