public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Alex Elder <elder@inktank.com>
To: Cong Ding <dinggnu@gmail.com>
Cc: Sage Weil <sage@inktank.com>,
	"David S. Miller" <davem@davemloft.net>,
	ceph-devel@vger.kernel.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] net/ceph/osdmap.c: fix undefined behavior when using snprintf()
Date: Wed, 23 Jan 2013 10:48:07 -0600	[thread overview]
Message-ID: <51001447.3030600@inktank.com> (raw)
In-Reply-To: <1358882429-19066-1-git-send-email-dinggnu@gmail.com>

On 01/22/2013 01:20 PM, Cong Ding wrote:
> The variable "str" is used as both the source and destination in function
> snprintf(), which is undefined behavior based on C11. The original description
> in C11 is:
> 	"If copying takes place between objects that
> 	overlap, the behavior is undefined."

Yes, this was an ill-advised thing to do in this function.

In fact, the only place this function is used (in osdmap_show()),
the non-static buffer was not initialized before the call.  (It
might happen to work because the same stack space was getting
reused each time through the loop.  Eeeeew!)

This is just an awful couple of functions.

> And, the function of ceph_osdmap_state_str() is to return the osdmap state, so
> it should return "doesn't exist" when all the conditions are not satisfied. I
> fix it in this patch.
> 
> Based on C11, snprintf() does nothing if n==0:
> 	"If n is zero, nothing is written, and s may be a
> 	null pointer. Otherwise, output characters beyond
> 	the n-1st are discarded rather than being written to
> 	the array, and a null character is written at the
> 	end of the characters actually written into the
> 	array."
> so I remove the unnecessary check of len (because it is not a busy path and
> saves a few lines of code).

True.  But since you know it's not going to do anything why
not only make the call if len is non-zero?  I.e.:

	else if (len)
		snprintf(str, len, "doesn't exist");

With your permission I'll make this change and will commit
this for you.  OK?

> Signed-off-by: Cong Ding <dinggnu@gmail.com>

Reviewed-by: Alex Elder <elder@inktank.com>

> ---
>  net/ceph/osdmap.c |   27 ++++++++-------------------
>  1 file changed, 8 insertions(+), 19 deletions(-)
> 
> diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
> index de73214..3131a99d3 100644
> --- a/net/ceph/osdmap.c
> +++ b/net/ceph/osdmap.c
> @@ -13,26 +13,15 @@
>  
>  char *ceph_osdmap_state_str(char *str, int len, int state)
>  {
> -	int flag = 0;
> -
> -	if (!len)
> -		goto done;
> -
> -	*str = '\0';
> -	if (state) {
> -		if (state & CEPH_OSD_EXISTS) {
> -			snprintf(str, len, "exists");
> -			flag = 1;
> -		}
> -		if (state & CEPH_OSD_UP) {
> -			snprintf(str, len, "%s%s%s", str, (flag ? ", " : ""),
> -				 "up");
> -			flag = 1;
> -		}
> -	} else {
> +	if ((state & CEPH_OSD_EXISTS) && (state & CEPH_OSD_UP))
> +		snprintf(str, len, "exists, up");
> +	else if (state & CEPH_OSD_EXISTS)
> +		snprintf(str, len, "exists");
> +	else if (state & CEPH_OSD_UP)
> +		snprintf(str, len, "up");
> +	else
>  		snprintf(str, len, "doesn't exist");
> -	}
> -done:
> +
>  	return str;
>  }
>  
> 


  reply	other threads:[~2013-01-23 16:55 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-22 19:20 [PATCH] net/ceph/osdmap.c: fix undefined behavior when using snprintf() Cong Ding
2013-01-23 16:48 ` Alex Elder [this message]
2013-01-23 17:41   ` Cong Ding
2013-01-23 17:47     ` Alex Elder

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=51001447.3030600@inktank.com \
    --to=elder@inktank.com \
    --cc=ceph-devel@vger.kernel.org \
    --cc=davem@davemloft.net \
    --cc=dinggnu@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=sage@inktank.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox