Re: [PATCH rdma-next 07/10] RDMA/uverbs: Prohibit write() calls with too small buffers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Nov 19, 2018 at 10:11:01AM +0200, Leon Romanovsky wrote:
> From: Jason Gunthorpe <jgg@xxxxxxxxxxxx>
> 
> The size meta-data in the prior patch describes the smallest acceptable
> buffer for the write() interface. Globally check this in the core code.
> 
> This is necessary in the case of write() methods that have a driver udata
> to prevent computing a negative udata buffer length.
> 
> The return code of -ENOSPC is chosen here as some of the handlers already
> use this code, however many other handler use EINVAL.
> 
> Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxxxx>
> Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx>
>  drivers/infiniband/core/uverbs_main.c | 19 +++++++++++++++----
>  1 file changed, 15 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
> index ac830735f45b..e00c5cc745e5 100644
> +++ b/drivers/infiniband/core/uverbs_main.c
> @@ -589,15 +589,18 @@ struct file *ib_uverbs_alloc_async_event_file(struct ib_uverbs_file *uverbs_file
>  }
>  
>  static ssize_t verify_hdr(struct ib_uverbs_cmd_hdr *hdr,
> -			  struct ib_uverbs_ex_cmd_hdr *ex_hdr,
> -			  size_t count, bool extended)
> +			  struct ib_uverbs_ex_cmd_hdr *ex_hdr, size_t count,
> +			  const struct uverbs_api_write_method *method_elm)
>  {
> -	if (extended) {
> +	if (method_elm->is_ex) {
>  		count -= sizeof(*hdr) + sizeof(*ex_hdr);
>  
>  		if ((hdr->in_words + ex_hdr->provider_in_words) * 8 != count)
>  			return -EINVAL;
>  
> +		if (hdr->in_words * 8 < method_elm->req_size)
> +			return -ENOSPC;
> +
>  		if (ex_hdr->cmd_hdr_reserved)
>  			return -EINVAL;
>  
> @@ -605,6 +608,9 @@ static ssize_t verify_hdr(struct ib_uverbs_cmd_hdr *hdr,
>  			if (!hdr->out_words && !ex_hdr->provider_out_words)
>  				return -EINVAL;
>  
> +			if (hdr->out_words * 8 < method_elm->resp_size)
> +				return -ENOSPC;
> +
>  			if (!access_ok(VERIFY_WRITE,
>  				       u64_to_user_ptr(ex_hdr->response),
>  				       (hdr->out_words + ex_hdr->provider_out_words) * 8))
> @@ -621,6 +627,11 @@ static ssize_t verify_hdr(struct ib_uverbs_cmd_hdr *hdr,
>  	if (hdr->in_words * 4 != count)
>  		return -EINVAL;
>  
> +	if (hdr->in_words * 4 < method_elm->req_size)
> +		return -ENOSPC;

At this point req_size does not include the header, while in_words * 4
does - so this test permits buffers that are too small. My woops

Jason



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux