Re: [PATCH] io_uring/query: cap user size passed to copy_struct_to_user

Gabriel Krisman Bertazi <[email protected]>
Newsgroups org.kernel.vger.io-uring,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Organization SUSE
Message-ID <[email protected]>
Laxman Acharya <[email protected]> writes:

> From: Laxman Acharya Padhya <[email protected]>
>
> io_handle_query_entry() clamps hdr.size for the inbound copy_from_user()
> but keeps the original user value as usize. copy_struct_to_user() uses
> that usize and, when it is larger than the kernel result, clear_user()s
> the trailing bytes.
>
> As hdr.size is a __u32, a query can request nearly 4 GiB of zeroing,
> including on the error path where res_size stays 0. The interface is
> reachable without a ring via IORING_REGISTER_QUERY.
>
> Reject sizes larger than PAGE_SIZE, as recommended for copy_struct_*
> interfaces.
>
> Fixes: c265ae75f900 ("io_uring: introduce io_uring querying")
> Cc: [email protected] # 6.18+
> Signed-off-by: Laxman Acharya Padhya <[email protected]>

Looks good. feel free to add:

Reviewed-by: Gabriel Krisman Bertazi <[email protected]>

> ---
>  io_uring/query.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/io_uring/query.c b/io_uring/query.c
> index 88a325736992..f2b5e19e5af6 100644
> --- a/io_uring/query.c
> +++ b/io_uring/query.c
> @@ -76,6 +76,9 @@ static int io_handle_query_entry(union io_query_data *data, void __user *uhdr,
>  
>  	if (copy_from_user(&hdr, uhdr, sizeof(hdr)))
>  		return -EFAULT;
> +	/* copy_struct_to_user() zeros up to usize bytes */
> +	if (hdr.size > PAGE_SIZE)
> +		return -E2BIG;
>  	usize = hdr.size;
>  	hdr.size = min(hdr.size, IO_MAX_QUERY_SIZE);
>  	udata = u64_to_user_ptr(hdr.query_data);
> -- 
> 2.51.2

-- 
Gabriel Krisman Bertazi
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.