CVE-2026-46234
Description
In the Linux kernel, the following vulnerability has been resolved:
vsock: fix buffer size clamping order
In vsock_update_buffer_size(), the buffer size was being clamped to the maximum first, and then to the minimum. If a user sets a minimum buffer size larger than the maximum, the minimum check overrides the maximum check, inverting the constraint.
This breaks the intended socket memory boundaries by allowing the vsk->buffer_size to grow beyond the configured vsk->buffer_max_size.
Fix this by checking the minimum first, and then the maximum. This ensures the buffer size never exceeds the buffer_max_size.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
In the Linux kernel's vsock, buffer size clamping order was inverted, allowing a minimum larger than the maximum to override the cap, potentially exceeding configured limits.
Vulnerability
In the Linux kernel's vsock implementation, the function vsock_update_buffer_size() clamped the buffer size to the maximum before the minimum. If a user configured a minimum buffer size larger than the maximum, the minimum check overrides the maximum check, allowing vsk->buffer_size to exceed vsk->buffer_max_size. This incorrect clamping order can break intended socket memory boundaries. The issue is present in certain kernel versions prior to the fix [1].
Exploitation
An attacker with local user access and the ability to set socket buffer sizes via the vsock interface (e.g., using setsockopt with SO_VM_SOCKETS_BUFFER_SIZE or similar) can set the minimum buffer size larger than the maximum. Due to the inverted clamping order, the minimum check overrides the maximum, allowing the buffer size to grow beyond the configured maximum. No special privileges beyond the ability to create and configure vsock sockets are required [1].
Impact
A successful exploitation could cause the kernel to allocate memory for the buffer beyond the intended maximum limit, potentially leading to memory pressure or resource exhaustion on the host. This may impact system stability and availability, as well as violate memory isolation between sockets. The vulnerability does not directly lead to code execution or information disclosure, but it can degrade system performance or enable denial of service [1].
Mitigation
The fix is included in Linux kernel commit a998a7e250bf976539e05a00ec64a81292afecaa, which changes the clamping order to check the minimum first and then the maximum [1]. Users should apply kernel updates that include this commit. The patch has been backported to stable kernel versions. No workarounds are known other than updating to a fixed kernel. This CVE is not listed on CISA's Known Exploited Vulnerabilities (KEV) catalog.
AI Insight generated on May 28, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
100b6888150146vsock: fix buffer size clamping order
2 files changed · +6 −8
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index d912ed2f012a3e..08f4dfb9782c28 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1951,12 +1951,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index d912ed2f012a3e..08f4dfb9782c28 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1951,12 +1951,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
a998a7e250bfvsock: fix buffer size clamping order
2 files changed · +6 −8
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index ca1289e64bcc8a..187cc259f820b5 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1728,12 +1728,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index ca1289e64bcc8a..187cc259f820b5 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1728,12 +1728,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
d114bfdc9b76vsock: fix buffer size clamping order
2 files changed · +6 −8
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index d912ed2f012a3e..08f4dfb9782c28 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1951,12 +1951,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index d912ed2f012a3e..08f4dfb9782c28 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1951,12 +1951,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
2602f7bb5818vsock: fix buffer size clamping order
2 files changed · +6 −8
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index cbd649bf01459d..9d0e1915abbe86 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1846,12 +1846,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index cbd649bf01459d..9d0e1915abbe86 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1846,12 +1846,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
310da27932ddvsock: fix buffer size clamping order
2 files changed · +6 −8
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 282d973233245f..1db7a1f8e55f6d 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1801,12 +1801,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 282d973233245f..1db7a1f8e55f6d 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1801,12 +1801,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
a998a7e250bfvsock: fix buffer size clamping order
2 files changed · +6 −8
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index ca1289e64bcc8a..187cc259f820b5 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1728,12 +1728,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index ca1289e64bcc8a..187cc259f820b5 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1728,12 +1728,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
2602f7bb5818vsock: fix buffer size clamping order
2 files changed · +6 −8
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index cbd649bf01459d..9d0e1915abbe86 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1846,12 +1846,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index cbd649bf01459d..9d0e1915abbe86 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1846,12 +1846,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
0b6888150146vsock: fix buffer size clamping order
2 files changed · +6 −8
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index d912ed2f012a3e..08f4dfb9782c28 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1951,12 +1951,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index d912ed2f012a3e..08f4dfb9782c28 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1951,12 +1951,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
310da27932ddvsock: fix buffer size clamping order
2 files changed · +6 −8
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 282d973233245f..1db7a1f8e55f6d 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1801,12 +1801,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 282d973233245f..1db7a1f8e55f6d 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1801,12 +1801,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
d114bfdc9b76vsock: fix buffer size clamping order
2 files changed · +6 −8
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index d912ed2f012a3e..08f4dfb9782c28 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1951,12 +1951,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
net/vmw_vsock/af_vsock.c+3 −4 modifieddiff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index d912ed2f012a3e..08f4dfb9782c28 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1951,12 +1951,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk, const struct vsock_transport *transport, u64 val) { - if (val > vsk->buffer_max_size) - val = vsk->buffer_max_size; - if (val < vsk->buffer_min_size) val = vsk->buffer_min_size; + if (val > vsk->buffer_max_size) + val = vsk->buffer_max_size; + if (val != vsk->buffer_size && transport && transport->notify_buffer_size) transport->notify_buffer_size(vsk, &val); -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Incorrect clamping order in vsock_update_buffer_size(): the maximum check was performed before the minimum check, so when buffer_min_size > buffer_max_size, the minimum override could push the buffer size above the configured maximum."
Attack vector
An attacker who can set SO_VM_SOCKET_BUFFER_MIN_SIZE to a value larger than SO_VM_SOCKET_BUFFER_MAX_SIZE on a vsock socket can cause vsk->buffer_size to exceed vsk->buffer_max_size [patch_id=2897537]. The bug is in the function vsock_update_buffer_size() in net/vmw_vsock/af_vsock.c, where the old code clamped to max first, then to min — if the min is larger than the max, the min check overrides the max check, inverting the intended constraint. This allows the socket buffer to grow beyond the configured upper memory boundary.
Affected code
The vulnerable function is vsock_update_buffer_size() in net/vmw_vsock/af_vsock.c [patch_id=2897537]. The function is responsible for clamping a requested buffer size to the per-socket minimum and maximum bounds (vsk->buffer_min_size and vsk->buffer_max_size).
What the fix does
The patch reverses the order of the two clamping checks in vsock_update_buffer_size() [patch_id=2897537]. The old code first capped val to buffer_max_size, then raised it to buffer_min_size — if buffer_min_size > buffer_max_size, the second check would override the first. The fix applies the minimum clamp first, then the maximum clamp, so that buffer_max_size is always the final upper bound. This ensures vsk->buffer_size never exceeds vsk->buffer_max_size regardless of how the user configures the min/max values.
Preconditions
- authThe attacker must be able to set socket options (SO_VM_SOCKET_BUFFER_MIN_SIZE and SO_VM_SOCKET_BUFFER_MAX_SIZE) on a vsock socket.
- configThe attacker must configure buffer_min_size to a value greater than buffer_max_size.
Generated on May 28, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- git.kernel.org/stable/c/0b68881501460c3761f196469e1e503218c5e536nvd
- git.kernel.org/stable/c/2602f7bb5818e92315feeaeb71d8ce4d5c9ab160nvd
- git.kernel.org/stable/c/310da27932dd0afe7ce7456dfe1f0814c3301f41nvd
- git.kernel.org/stable/c/a998a7e250bf976539e05a00ec64a81292afecaanvd
- git.kernel.org/stable/c/d114bfdc9b76bf93b881e195b7ec957c14227babnvd
News mentions
0No linked articles in our index yet.