All of lore.kernel.org
 help / color / mirror / Atom feed
From: Harsh Bora <harsh@linux.vnet.ibm.com>
To: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: linux-fsdevel@vger.kernel.org, fengguang.wu@intel.com,
	aneesh.kumar@linux.vnet.ibm.com, jvrao@linux.vnet.ibm.com,
	"M. Mohan Kumar" <mohan@in.ibm.com>
Subject: Re: [PATCH] Typecasting required for comparing unlike datatypes
Date: Fri, 10 Dec 2010 13:43:26 +0530	[thread overview]
Message-ID: <4D01E126.2070705@linux.vnet.ibm.com> (raw)
In-Reply-To: <20101210165959.8b25d6c2.kamezawa.hiroyu@jp.fujitsu.com>

On 12/10/2010 01:29 PM, KAMEZAWA Hiroyuki wrote:
> On Fri, 10 Dec 2010 12:48:05 +0530
> Harsh Bora<harsh@linux.vnet.ibm.com>  wrote:
>
>> On 12/10/2010 12:31 PM, KAMEZAWA Hiroyuki wrote:
>>> On Fri, 10 Dec 2010 12:09:42 +0530
>>> Harsh Bora<harsh@linux.vnet.ibm.com>   wrote:
>>> 	return -EINVAL;
>>>>> +	}
>>>>> +	/*
>>>>> +	 * The file supports 'unsigned long' offset. (but loff_t is signed)
>>>>> +	 * When pos is negative, -1 is the biggest number. So if pos + count
>>>>> +	 * is larger than pos, it's overflow.
>>>>> +	 * (ex) -1 + 10 = 9 ...means
>>>>> +	 *    0xffff + 0xa = 0x9 =>    overflow.
>>>>> +	 */
>>>>> +	if ((pos<    0)&&    (pos + count>    0))
>>>>
>>>> Well, that works fine for what I am concerned but I think there is a
>>>> mismatch in the code and the comment above. As per the comments above,
>>>> it should be like:
>>>> 			if ((pos<   0)&&   (pos + count>   pos))
>>>>
>>>
>>> Ah, yes. updated. Thank you for review and test.
>>> -Kame
>>> ==
>>> commit 4a3956c790290efeb647bbb0c3a90476bb57800e adds support for
>>> negative (unsigned) page offset for very large files as /proc/<pid>/mem
>>> and /dev/mem.
>>>
>>> In that patch, overlap check routine is added but it was wrong.
>>>
>>> Considering 'pos' is loff_t, a signed value,
>>>
>>> In usual case, at comparing 'pos' and 'pos+count'
>>>
>>> 	(positive) / (positive)  OK
>>> 	(positive) / (nevative)  EOVERFLOW
>>> 	(negative) / (positive)  EINVAL
>>> 	(negative) / (negative)  EINVAL
>>>
>>> In FMODE_UNSIGNED_OFFSET case,
>>>
>>> 	(positive) / (positive)  OK
>>> 	(positive) / (nevative)  OK (ex. 0x7fff ->   0x8000)
>>> 	(nevative) / (negative)  OK
>>> 	(negative) / (positive)  EOVERFLOW (ex. 0xffff ->   0x1)
>>>
>>> Changelog:
>>>    - fixed a comment.
>>>
>>> Signed-off-by: KAMEZAWA Hiroyuki<kamezawa.hiroyu@jp.fujitsu.com>
>>>
>>> ---
>>>    fs/read_write.c |   21 +++++++++++++++++----
>>>    1 file changed, 17 insertions(+), 4 deletions(-)
>>>
>>> Index: linux-2.6.37-rc5/fs/read_write.c
>>> ===================================================================
>>> --- linux-2.6.37-rc5.orig/fs/read_write.c
>>> +++ linux-2.6.37-rc5/fs/read_write.c
>>> @@ -37,11 +37,24 @@ __negative_fpos_check(struct file *file,
>>>    	 * pos or pos+count is negative here, check overflow.
>>>    	 * too big "count" will be caught in rw_verify_area().
>>>    	 */
>>> -	if ((pos<   0)&&   (pos + count<   pos))
>>> +	/* negative pos is allowed only when the flag is set */
>>> +	if (!(file->f_mode&   FMODE_UNSIGNED_OFFSET)) {
>>> +		if ((pos>   0)&&   (pos + count>   0))
> Hmm.
>
>> Do we really need 2 checks? If first one is true, second one has to be
>> true for count being unsigned?
>
>    pos is signed value. Then, if pos is near to LOGN_MAX, pos+count can be<  0.

Well, if you mean that, you need to typecast. Going back to what I 
proposed, you need to put it like that:
	if ((pos>   0)&&   ( (loff_t) (pos + count) >   0))
otherwise, the result of pos + count becomes an unsigned value on a 64 
bit system ..
>
>
>>> +			return 0;
>>> +		if ((pos>   0)&&   (pos + count<   0))
>> BTW, when will the above condition be true ? As if first condition is
>> true, the second cant be true, as the count is unsigned.
>>
> Ah, hmm, type casting problem ?
>
> 	(signed) + (unsigned) =>  (unsigned)
>
> ah, ok. count should be signed...
No, count shouldnt be signed, you may guess why. typecating the sum to 
loff_t is the solution.

Regards,
Harsh
> Is this messy ?
> ==
> commit 4a3956c790290efeb647bbb0c3a90476bb57800e adds support for
> negative (unsigned) page offset for very large files as /proc/<pid>/mem
> and /dev/mem.
>
> In that patch, overlap check routine is added but it was wrong.
>
> Considering 'pos' is loff_t, a signed value,
>
> In usual case, at comparing 'pos' and 'pos+count'
>
> 	(positive) / (positive)  OK
> 	(positive) / (nevative)  EOVERFLOW
> 	(negative) / (positive)  EINVAL
> 	(negative) / (negative)  EINVAL
>
> In FMODE_UNSIGNED_OFFSET case,
>
> 	(positive) / (positive)  OK
> 	(positive) / (nevative)  OK (ex. 0x7fff ->  0x8000)
> 	(nevative) / (negative)  OK
> 	(negative) / (positive)  EOVERFLOW (ex. 0xffff ->  0x1)
>
> Changelog v1->v2:
>   - fixed signed+unsigned=unsigned problem.
> Changelog v0->v1:
>   - fixed a comment.
>
> Signed-off-by: KAMEZAWA Hiroyuki<kamezawa.hiroyu@jp.fujitsu.com>
>
> ---
>   fs/read_write.c |   24 ++++++++++++++++++++----
>   1 file changed, 20 insertions(+), 4 deletions(-)
>
> Index: linux-2.6.37-rc5/fs/read_write.c
> ===================================================================
> --- linux-2.6.37-rc5.orig/fs/read_write.c
> +++ linux-2.6.37-rc5/fs/read_write.c
> @@ -33,15 +33,31 @@ EXPORT_SYMBOL(generic_ro_fops);
>   static int
>   __negative_fpos_check(struct file *file, loff_t pos, size_t count)
>   {
> +	ssize_t len = (ssize_t)count;
> +	/* len>  0 is checked before this call. */
> +	BUG_ON(len<  0);
>   	/*
>   	 * pos or pos+count is negative here, check overflow.
>   	 * too big "count" will be caught in rw_verify_area().
>   	 */
> -	if ((pos<  0)&&  (pos + count<  pos))
> +	/* negative pos is allowed only when the flag is set */
> +	if (!(file->f_mode&  FMODE_UNSIGNED_OFFSET)) {
> +		if ((pos>  0)&&  (pos + len>  0))
> +			return 0;
> +		if ((pos>  0)&&  (pos + len<  0))
> +			return -EOVERFLOW;
> +		return -EINVAL;
> +	}
> +	/*
> +	 * The file supports 'unsigned long' offset. (but loff_t is signed)
> +	 * When pos is negative, -1 is the biggest number. So if pos + count
> +	 * is larger than 0, it's overflow.
> +	 * (ex) -1 + 10 = 9 ...means
> +	 *    0xffff + 0xa = 0x9 =>  overflow.
> +	 */
> +	if ((pos<  0)&&  (pos + len>  0))
>   		return -EOVERFLOW;
> -	if (file->f_mode&  FMODE_UNSIGNED_OFFSET)
> -		return 0;
> -	return -EINVAL;
> +	return 0;
>   }
>
>   /**
>
>


  reply	other threads:[~2010-12-10  8:13 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-12-08 12:55 [PATCH] Typecasting required for comparing unlike datatypes Harsh Prateek Bora
2010-12-09 18:32 ` Harsh Bora
2010-12-10  0:06   ` KAMEZAWA Hiroyuki
2010-12-10  0:53 ` KAMEZAWA Hiroyuki
2010-12-10  6:39   ` Harsh Bora
2010-12-10  7:01     ` KAMEZAWA Hiroyuki
2010-12-10  7:18       ` Harsh Bora
2010-12-10  7:59         ` KAMEZAWA Hiroyuki
2010-12-10  8:13           ` Harsh Bora [this message]
2010-12-10  8:20             ` KAMEZAWA Hiroyuki
2010-12-10  8:18 ` KAMEZAWA Hiroyuki
2010-12-10  8:31   ` Harsh Bora
2010-12-15  9:50   ` Al Viro
2010-12-16  0:24     ` KAMEZAWA Hiroyuki
2010-12-19  7:02       ` Harsh Bora

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=4D01E126.2070705@linux.vnet.ibm.com \
    --to=harsh@linux.vnet.ibm.com \
    --cc=aneesh.kumar@linux.vnet.ibm.com \
    --cc=fengguang.wu@intel.com \
    --cc=jvrao@linux.vnet.ibm.com \
    --cc=kamezawa.hiroyu@jp.fujitsu.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=mohan@in.ibm.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 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.