All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matan Barak <matanb-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
To: Yann Droneaud <ydroneaud-RlY5vtjFyJ3QT0dZR+AlfA@public.gmane.org>,
	Roland Dreier <roland-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: Or Gerlitz <ogerlitz-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Subject: Re: [PATCH for v3.13 2/7] IB/uverbs: remove implicit cast in INIT_UDATA()
Date: Wed, 27 Nov 2013 10:21:44 +0200	[thread overview]
Message-ID: <5295AB98.8080205@mellanox.com> (raw)
In-Reply-To: <471895ee06633a624e934cf501c7a460755fe4a4.1385501822.git.ydroneaud-RlY5vtjFyJ3QT0dZR+AlfA@public.gmane.org>

On 27/11/2013 12:02 AM, Yann Droneaud wrote:
> Currently, INIT_UDATA() does an implicit cast to a pointer,
> so that 'response' address, eg. output buffer, can be used
> as is to initialize a struct ib_udata:
>
>          do {                                                    \
>                  (udata)->inbuf  = (void __user *) (ibuf);       \
>                  (udata)->outbuf = (void __user *) (obuf);       \
>                  (udata)->inlen  = (ilen);                       \
>                  (udata)->outlen = (olen);                       \
>          } while (0)
>
> ...
>
>          INIT_UDATA(&udata, buf + sizeof cmd,
>                     (unsigned long) cmd.response + sizeof resp,
>                     in_len - sizeof cmd, out_len - sizeof  resp);
>
> ...
>
> Hidding the integer to pointer conversion is prone to error
> that won't be catched by compiler/static analyzer is some case.
>
> In the other hand, sparse reports an error if literal 0 is used
> to initialize inbuf or outbuf, for example in:
>
>          INIT_UDATA(&ucore,
>                     (hdr.in_words) ? buf : 0,
>                     (unsigned long)ex_hdr.response,
>                     hdr.in_words * 8,
>                     hdr.out_words * 8);
>
> It was reported by kbuild test robot in message[1]:
>
>    From: kbuild test robot <fengguang.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
>    Subject: "drivers/infiniband/core/uverbs_main.c:683:17:
>        sparse: Using plain integer as NULL pointer",
>    Message-Id: <528b3984.SVGs20ZWpcuR/Jls%fengguang.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
>
> This patch fixes the warnings reported by sparse and allows the compiler
> to report a warning in case a plain integer get used to initialize
> a udata pointer.
>
> This patch requires struct ib_udata to be modified to have a
> const void __user *inbuf field[2], otherwise compiler will report warnings
> regarding const to non const conversion:
>
> drivers/infiniband/core/uverbs_main.c: In function ‘ib_uverbs_write’:
> drivers/infiniband/core/uverbs_main.c:682:24: attention : assignment discards ‘const’ qualifier from pointer target type [enabled by default]
> drivers/infiniband/core/uverbs_main.c:688:22: attention : assignment discards ‘const’ qualifier from pointer target type [enabled by default]
> drivers/infiniband/core/uverbs_cmd.c: In function ‘ib_uverbs_get_context’:
> drivers/infiniband/core/uverbs_cmd.c:307:23: attention : assignment discards ‘const’ qualifier from pointer target type [enabled by default]
> drivers/infiniband/core/uverbs_cmd.c: In function ‘ib_uverbs_alloc_pd’:
> drivers/infiniband/core/uverbs_cmd.c:516:23: attention : assignment discards ‘const’ qualifier from pointer target type [enabled by default]
> ...
>
> [1] https://lists.01.org/pipermail/kbuild-all/2013-November/002120.html
>
> [2] https://patchwork.kernel.org/patch/2846202/
>      http://marc.info/?i=3050a98379b4342ea59d59aeaf1ce162171df928.1376847403.git.ydroneaud-RlY5vtjFyJ3QT0dZR+AlfA@public.gmane.org
>
> Link: http://marc.info/?i=cover.1385501822.git.ydroneaud-RlY5vtjFyJ3QT0dZR+AlfA@public.gmane.org
> Signed-off-by: Yann Droneaud <ydroneaud-RlY5vtjFyJ3QT0dZR+AlfA@public.gmane.org>
> ---
>   drivers/infiniband/core/uverbs.h      | 12 ++++++------
>   drivers/infiniband/core/uverbs_cmd.c  | 20 ++++++++++----------
>   drivers/infiniband/core/uverbs_main.c | 13 ++++++++-----
>   3 files changed, 24 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
> index 9879568aed8c..0dca1975d59d 100644
> --- a/drivers/infiniband/core/uverbs.h
> +++ b/drivers/infiniband/core/uverbs.h
> @@ -47,12 +47,12 @@
>   #include <rdma/ib_umem.h>
>   #include <rdma/ib_user_verbs.h>
>
> -#define INIT_UDATA(udata, ibuf, obuf, ilen, olen)			\
> -	do {								\
> -		(udata)->inbuf  = (const void __user *) (ibuf);		\
> -		(udata)->outbuf = (void __user *) (obuf);		\
> -		(udata)->inlen  = (ilen);				\
> -		(udata)->outlen = (olen);				\
> +#define INIT_UDATA(udata, ibuf, obuf, ilen, olen)	\
> +	do {						\
> +		(udata)->inbuf  = (ibuf);		\
> +		(udata)->outbuf = (obuf);		\
> +		(udata)->inlen  = (ilen);		\
> +		(udata)->outlen = (olen);		\
>   	} while (0)
>
>   /*
> diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
> index 65f6e7dc380c..d9d91c412628 100644
> --- a/drivers/infiniband/core/uverbs_cmd.c
> +++ b/drivers/infiniband/core/uverbs_cmd.c
> @@ -305,7 +305,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
>   	}
>
>   	INIT_UDATA(&udata, buf + sizeof cmd,
> -		   (unsigned long) cmd.response + sizeof resp,
> +		   (void __user *)(unsigned long)cmd.response + sizeof resp,

The response field is already __u64 and casting to (void __user *) 
should match the machine's pointer type size. Why do we have to cast to 
(unsigned long) and then cast to (void __user *) ?

>   		   in_len - sizeof cmd, out_len - sizeof resp);
>
>   	ucontext = ibdev->alloc_ucontext(ibdev, &udata);
> @@ -514,7 +514,7 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
>   		return -EFAULT;
>
>   	INIT_UDATA(&udata, buf + sizeof cmd,
> -		   (unsigned long) cmd.response + sizeof resp,
> +		   (void __user *)(unsigned long)cmd.response + sizeof resp,
>   		   in_len - sizeof cmd, out_len - sizeof resp);
>
>   	uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
> @@ -711,7 +711,7 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
>   		return -EFAULT;
>
>   	INIT_UDATA(&udata, buf + sizeof cmd,
> -		   (unsigned long) cmd.response + sizeof resp,
> +		   (void __user *)(unsigned long)cmd.response + sizeof resp,
>   		   in_len - sizeof cmd, out_len - sizeof  resp);
>
>   	mutex_lock(&file->device->xrcd_tree_mutex);
> @@ -923,7 +923,7 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
>   		return -EFAULT;
>
>   	INIT_UDATA(&udata, buf + sizeof cmd,
> -		   (unsigned long) cmd.response + sizeof resp,
> +		   (void __user *)(unsigned long)cmd.response + sizeof resp,
>   		   in_len - sizeof cmd, out_len - sizeof resp);
>
>   	if ((cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK))
> @@ -1215,7 +1215,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
>   		return -EFAULT;
>
>   	INIT_UDATA(&udata, buf + sizeof cmd,
> -		   (unsigned long) cmd.response + sizeof resp,
> +		   (void __user *)(unsigned long)cmd.response + sizeof resp,
>   		   in_len - sizeof cmd, out_len - sizeof resp);
>
>   	if (cmd.comp_vector >= file->device->num_comp_vectors)
> @@ -1311,7 +1311,7 @@ ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file,
>   		return -EFAULT;
>
>   	INIT_UDATA(&udata, buf + sizeof cmd,
> -		   (unsigned long) cmd.response + sizeof resp,
> +		   (void __user *)(unsigned long)cmd.response + sizeof resp,
>   		   in_len - sizeof cmd, out_len - sizeof resp);
>
>   	cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0);
> @@ -1513,7 +1513,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
>   		return -EPERM;
>
>   	INIT_UDATA(&udata, buf + sizeof cmd,
> -		   (unsigned long) cmd.response + sizeof resp,
> +		   (void __user *)(unsigned long)cmd.response + sizeof resp,
>   		   in_len - sizeof cmd, out_len - sizeof resp);
>
>   	obj = kzalloc(sizeof *obj, GFP_KERNEL);
> @@ -1700,7 +1700,7 @@ ssize_t ib_uverbs_open_qp(struct ib_uverbs_file *file,
>   		return -EFAULT;
>
>   	INIT_UDATA(&udata, buf + sizeof cmd,
> -		   (unsigned long) cmd.response + sizeof resp,
> +		   (void __user *)(unsigned long)cmd.response + sizeof resp,
>   		   in_len - sizeof cmd, out_len - sizeof resp);
>
>   	obj = kmalloc(sizeof *obj, GFP_KERNEL);
> @@ -2976,7 +2976,7 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
>   	xcmd.srq_limit	 = cmd.srq_limit;
>
>   	INIT_UDATA(&udata, buf + sizeof cmd,
> -		   (unsigned long) cmd.response + sizeof resp,
> +		   (void __user *)(unsigned long)cmd.response + sizeof resp,
>   		   in_len - sizeof cmd, out_len - sizeof resp);
>
>   	ret = __uverbs_create_xsrq(file, &xcmd, &udata);
> @@ -3001,7 +3001,7 @@ ssize_t ib_uverbs_create_xsrq(struct ib_uverbs_file *file,
>   		return -EFAULT;
>
>   	INIT_UDATA(&udata, buf + sizeof cmd,
> -		   (unsigned long) cmd.response + sizeof resp,
> +		   (void __user *)(unsigned long)cmd.response + sizeof resp,
>   		   in_len - sizeof cmd, out_len - sizeof resp);
>
>   	ret = __uverbs_create_xsrq(file, &cmd, &udata);
> diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
> index 34386943ebcf..14d864371050 100644
> --- a/drivers/infiniband/core/uverbs_main.c
> +++ b/drivers/infiniband/core/uverbs_main.c
> @@ -635,6 +635,7 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
>   		__u32 command;
>
>   		struct ib_uverbs_ex_cmd_hdr ex_hdr;
> +		char __user *response;
>   		struct ib_udata ucore;
>   		struct ib_udata uhw;
>   		int err;
> @@ -668,7 +669,9 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
>   		if ((hdr.in_words + ex_hdr.provider_in_words) * 8 != count)
>   			return -EINVAL;
>
> -		if (ex_hdr.response) {
> +		response = (char __user *)(unsigned long)ex_hdr.response;
> +
> +		if (response) {
>   			if (!hdr.out_words && !ex_hdr.provider_out_words)
>   				return -EINVAL;
>   		} else {
> @@ -677,14 +680,14 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
>   		}
>
>   		INIT_UDATA(&ucore,
> -			   (hdr.in_words) ? buf : 0,
> -			   (unsigned long)ex_hdr.response,
> +			   (hdr.in_words) ? buf : NULL,
> +			   response,
>   			   hdr.in_words * 8,
>   			   hdr.out_words * 8);
>
>   		INIT_UDATA(&uhw,
> -			   (ex_hdr.provider_in_words) ? buf + ucore.inlen : 0,
> -			   (ex_hdr.provider_out_words) ? (unsigned long)ex_hdr.response + ucore.outlen : 0,
> +			   (ex_hdr.provider_in_words) ? buf + ucore.inlen : NULL,
> +			   (ex_hdr.provider_out_words) ? response + ucore.outlen : NULL,
>   			   ex_hdr.provider_in_words * 8,
>   			   ex_hdr.provider_out_words * 8);
>
>

Best regards,
Matan
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  parent reply	other threads:[~2013-11-27  8:21 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-26 22:02 [PATCH for v3.13 0/7] create_flow/destroy_flow fixes for v3.13 Yann Droneaud
     [not found] ` <cover.1385501822.git.ydroneaud-RlY5vtjFyJ3QT0dZR+AlfA@public.gmane.org>
2013-11-26 22:02   ` [PATCH for v3.13 1/7] IB/core: const'ify inbuf in struct ib_udata Yann Droneaud
2013-11-26 22:02   ` [PATCH for v3.13 2/7] IB/uverbs: remove implicit cast in INIT_UDATA() Yann Droneaud
     [not found]     ` <471895ee06633a624e934cf501c7a460755fe4a4.1385501822.git.ydroneaud-RlY5vtjFyJ3QT0dZR+AlfA@public.gmane.org>
2013-11-27  8:21       ` Matan Barak [this message]
     [not found]         ` <5295AB98.8080205-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2013-11-27 12:18           ` Yann Droneaud
2013-11-26 22:02   ` [PATCH for v3.13 3/7] IB/uverbs: set outbuf to NULL when no core response space is provided Yann Droneaud
2013-11-26 22:02   ` [PATCH for v3.13 4/7] IB/uverbs: check reserved field in extended command header Yann Droneaud
2013-11-26 22:02   ` [PATCH for v3.13 5/7] IB/uverbs: check comp_mask in destroy_flow Yann Droneaud
2013-11-26 22:02   ` [PATCH for v3.13 6/7] IB/uverbs: check reserved fields in create_flow Yann Droneaud
2013-11-26 22:02   ` [PATCH for v3.13 7/7] IB/uverbs: set error code when fail to consume all flow_spec items Yann Droneaud
2013-11-27  8:34   ` [PATCH for v3.13 0/7] create_flow/destroy_flow fixes for v3.13 Matan Barak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5295AB98.8080205@mellanox.com \
    --to=matanb-vpraknaxozvwk0htik3j/w@public.gmane.org \
    --cc=linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=ogerlitz-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org \
    --cc=roland-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=ydroneaud-RlY5vtjFyJ3QT0dZR+AlfA@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.