diff mbox

Fix accesses at LBA28 boundary (old bug, but nasty) (v2)

Message ID 4BBCC648.30807@teksavvy.com
State Not Applicable
Delegated to: David Miller
Headers show

Commit Message

Mark Lord April 7, 2010, 5:52 p.m. UTC
Most drives from Seagate, Hitachi, and possibly other brands,
do not allow LBA28 access to sector number 0x0fffffff (2^28 - 1).
So instead use LBA48 for such accesses.

This bug could bite a lot of systems, especially when the user has
taken care to align partitions to 4KB boundaries. On misaligned systems,
it is less likely to be encountered, since a 4KB read would end at
0x10000000 rather than at 0x0fffffff.

Signed-off-by: Mark Lord <mlord@pobox.com>
---

Reposting with the pre-existing (u64) cast removed.

--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Alan Cox April 7, 2010, 7:18 p.m. UTC | #1
On Wed, 07 Apr 2010 13:52:08 -0400
Mark Lord <kernel@teksavvy.com> wrote:

> Most drives from Seagate, Hitachi, and possibly other brands,
> do not allow LBA28 access to sector number 0x0fffffff (2^28 - 1).
> So instead use LBA48 for such accesses.
> 
> This bug could bite a lot of systems, especially when the user has
> taken care to align partitions to 4KB boundaries. On misaligned systems,
> it is less likely to be encountered, since a 4KB read would end at
> 0x10000000 rather than at 0x0fffffff.
> 
> Signed-off-by: Mark Lord <mlord@pobox.com>

Acked-by: Alan Cox <alan@linux.intel.com>
--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Tejun Heo April 7, 2010, 9:01 p.m. UTC | #2
On 04/08/2010 02:52 AM, Mark Lord wrote:
> Most drives from Seagate, Hitachi, and possibly other brands,
> do not allow LBA28 access to sector number 0x0fffffff (2^28 - 1).
> So instead use LBA48 for such accesses.
> 
> This bug could bite a lot of systems, especially when the user has
> taken care to align partitions to 4KB boundaries. On misaligned systems,
> it is less likely to be encountered, since a 4KB read would end at
> 0x10000000 rather than at 0x0fffffff.
> 
> Signed-off-by: Mark Lord <mlord@pobox.com>

Heh, yeah, killing the cast works too.

Acked-by: Tejun Heo <tj@kernel.org>

Thanks.
Jeff Garzik April 8, 2010, 5 p.m. UTC | #3
On 04/07/2010 01:52 PM, Mark Lord wrote:
> Most drives from Seagate, Hitachi, and possibly other brands,
> do not allow LBA28 access to sector number 0x0fffffff (2^28 - 1).
> So instead use LBA48 for such accesses.
>
> This bug could bite a lot of systems, especially when the user has
> taken care to align partitions to 4KB boundaries. On misaligned systems,
> it is less likely to be encountered, since a 4KB read would end at
> 0x10000000 rather than at 0x0fffffff.
>
> Signed-off-by: Mark Lord <mlord@pobox.com>
> ---
>
> Reposting with the pre-existing (u64) cast removed.
>
> --- linux-2.6.34-rc3/include/linux/ata.h 2010-03-30 12:24:39.000000000
> -0400
> +++ linux/include/linux/ata.h 2010-04-06 18:39:41.167702612 -0400
> @@ -1025,8 +1025,8 @@
>
> static inline int lba_28_ok(u64 block, u32 n_block)
> {
> - /* check the ending block number */
> - return ((block + n_block) < ((u64)1 << 28)) && (n_block <= 256);
> + /* check the ending block number: must be LESS THAN 0x0fffffff */
> + return ((block + n_block) < ((1 << 28) - 1)) && (n_block <= 256);
> }

applied.

Neither 'git am' nor patch(1) would apply the patch for some reason, so 
I applied it manually.  Weird...  I could not spot obvious whitespace or 
word-wrap corruption.

--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Mark Lord April 15, 2010, 1:46 p.m. UTC | #4
On 08/04/10 01:00 PM, Jeff Garzik wrote:
> On 04/07/2010 01:52 PM, Mark Lord wrote:
>> Most drives from Seagate, Hitachi, and possibly other brands,
>> do not allow LBA28 access to sector number 0x0fffffff (2^28 - 1).
>> So instead use LBA48 for such accesses.
>>
>> This bug could bite a lot of systems, especially when the user has
>> taken care to align partitions to 4KB boundaries. On misaligned systems,
>> it is less likely to be encountered, since a 4KB read would end at
>> 0x10000000 rather than at 0x0fffffff.
>>
>> Signed-off-by: Mark Lord <mlord@pobox.com>
>> ---
>>
>> Reposting with the pre-existing (u64) cast removed.
>>
>> --- linux-2.6.34-rc3/include/linux/ata.h 2010-03-30 12:24:39.000000000
>> -0400
>> +++ linux/include/linux/ata.h 2010-04-06 18:39:41.167702612 -0400
>> @@ -1025,8 +1025,8 @@
>>
>> static inline int lba_28_ok(u64 block, u32 n_block)
>> {
>> - /* check the ending block number */
>> - return ((block + n_block) < ((u64)1 << 28)) && (n_block <= 256);
>> + /* check the ending block number: must be LESS THAN 0x0fffffff */
>> + return ((block + n_block) < ((1 << 28) - 1)) && (n_block <= 256);
>> }
>
> applied.
>
> Neither 'git am' nor patch(1) would apply the patch for some reason, so
> I applied it manually. Weird... I could not spot obvious whitespace or
> word-wrap corruption.
..

I figured this this out (paritially) today:
Somehow, the (v2) repost ended up with MS-DOS line separators (CR-LF).

I imagine those would confuse most of the tools,
yet remain transparent (hidden) in editors and email programs.

Dunno how they got in there, though.

Cheers
  
--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

--- linux-2.6.34-rc3/include/linux/ata.h	2010-03-30 12:24:39.000000000 -0400
+++ linux/include/linux/ata.h	2010-04-06 18:39:41.167702612 -0400
@@ -1025,8 +1025,8 @@ 
  
  static inline int lba_28_ok(u64 block, u32 n_block)
  {
-	/* check the ending block number */
-	return ((block + n_block) < ((u64)1 << 28)) && (n_block <= 256);
+	/* check the ending block number: must be LESS THAN 0x0fffffff */
+	return ((block + n_block) < ((1 << 28) - 1)) && (n_block <= 256);
  }
  
  static inline int lba_48_ok(u64 block, u32 n_block)