Re: [PATCH net v1] vsock: validate buffer min/max size in setsockopt

David Laight <[email protected]>
Newsgroups dev.linux.lists.virtualization,org.kernel.vger.netdev
Message-ID <20260824131632.2d325c42@pumpkin>
On Mon, 24 Aug 2026 17:12:57 +0800
Rongguang Wei <[email protected]> wrote:

> From: Rongguang Wei <[email protected]>
> 
> SO_VM_SOCKETS_BUFFER_MIN_SIZE and SO_VM_SOCKETS_BUFFER_MAX_SIZE
> do not cross-validate against each other, allowing userspace to
> set buffer_min_size > buffer_max_size.
> When min > max, buffer_size is silently clamped to an incorrect
> value. For example, setting min=512KB then max=128 results in
> buffer_size=128 despite the user requesting much larger buffers
> via SO_VM_SOCKETS_BUFFER_SIZE.
> 
> Reproduced with a test program:
> setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MIN_SIZE,
> 	   512 * 1024, sizeof(int));
> setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE,
> 	   128, sizeof(int));
> // User asked for 1MB but got 128 bytes silently
> setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
> 	   1024 * 1024, sizeof(int));
> 
> After that use getsockopt to get the buffer_size = 128 and
> buffer_min_size = 524288, buffer_max_size = 128.
> The buffer_min_size > buffer_max_size and the kernel accepted
> contradictory values without error.
> 
> Add value check to fix this issue. Return -EINVAL to userspace
> when setting MAX_SIZE to a value smaller than the current MIN_SIZE
> or setting MIN_SIZE to a value larger than the current MAX_SIZE.

That is going to break userspace that sets the minimum before the maximum
when the new minimum is larger than the old maximum.

David

> 
> Fixes: b9f2b0ffde0c ("vsock: handle buffer_size sockopts in the core")
> Signed-off-by: Rongguang Wei <[email protected]>
> ---
>  net/vmw_vsock/af_vsock.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
> index a33b2a2d381d..5faa30ee8745 100644
> --- a/net/vmw_vsock/af_vsock.c
> +++ b/net/vmw_vsock/af_vsock.c
> @@ -2050,12 +2050,20 @@ static int vsock_connectible_setsockopt(struct socket *sock,
>  
>  	case SO_VM_SOCKETS_BUFFER_MAX_SIZE:
>  		COPY_IN(val);
> +		if (val < vsk->buffer_min_size) {
> +			err = -EINVAL;
> +			goto exit;
> +		}
>  		vsk->buffer_max_size = val;
>  		vsock_update_buffer_size(vsk, transport, vsk->buffer_size);
>  		break;
>  
>  	case SO_VM_SOCKETS_BUFFER_MIN_SIZE:
>  		COPY_IN(val);
> +		if (val > vsk->buffer_max_size) {
> +			err = -EINVAL;
> +			goto exit;
> +		}
>  		vsk->buffer_min_size = val;
>  		vsock_update_buffer_size(vsk, transport, vsk->buffer_size);
>  		break;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.