Re: [BUG] vsock: refcount_t saturation and OOM via buffer size invariant inversion

From: Stefano Garzarella

Date: Tue Mar 31 2026 - 08:38:06 EST


On Tue, Mar 24, 2026 at 06:28:12PM +0100, Norbert Szetei wrote:
Hello,

we have discovered a bug in AF_VSOCK where an unprivileged user can bypass socket
memory constraints. This leads to refcount_t saturation and OOM. While
refcount_t prevents a true UAF by saturating, the resulting state triggers
kernel warnings and kernel panic, depending on the setup.

In vsock_connectible_setsockopt(), the SO_VM_SOCKETS_BUFFER_MIN_SIZE and
SO_VM_SOCKETS_BUFFER_MAX_SIZE options are used to update the buffer's minimum
and maximum values independently.

The vsock_update_buffer_size() function clamps the buffer size to the maximum
first, then the minimum:

// https://github.com/torvalds/linux/blob/c369299895a591d96745d6492d4888259b004a9e/net/vmw_vsock/af_vsock.c#L1950
if (val > vsk->buffer_max_size)
val = vsk->buffer_max_size;

if (val < vsk->buffer_min_size)
val = vsk->buffer_min_size;

vsk->buffer_size = val;

By setting buffer_min_size to a large value, the second clamp overrides the
first, forcing vsk->buffer_size to exceed the intended maximum. The transport
layer then uses this value, allowing unbounded SKB allocation that saturates the
32-bit sk_wmem_alloc refcount.

The fix should ensure that SO_VM_SOCKETS_BUFFER_MIN_SIZE cannot be used to set a
value higher than the current buffer_max_size. Conversely,
SO_VM_SOCKETS_BUFFER_MAX_SIZE should not be allowed to be set lower than the
current buffer_min_size.

Okay, but that wouldn't change much. As long as the user sets the maximum to match the minimum you set in the POC, it behaves exactly the same way, right?

Maybe we should add a sysctl to set a global upper bound, but this is another problem, I agree that we should improve the kernel behavior around min/max. I see 3 options:

1. Just invert the checks, fist check for min, then for max.

2. Simply adjust the min and max values so that they make sense. For example, if the minimum value being set is greater than the maximum, the kernel could adjust the maximum to the same value. However, this would not change the behavior of your POC.

3. Force the minimum to be less than or equal to the maximum. This, however, would require a certain order when setting the minimum and maximum, especially relative to the default. For example, if you increase the minimum beyond the default maximum, you must adjust the maximum first; conversely, if you want to set the maximum below the default minimum, you must adjust the minimum first.

I'm more into 1 or 2. 3 IMO is too much.

Do you want to send a patch?

Thanks,
Stefano