All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michal Nazarewicz <mina86@mina86.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Evgeniy Polyakov <zbr@ioremap.net>, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] drivers: w1: make w1_slave::flags long to avoid casts
Date: Thu, 31 Oct 2013 10:11:53 +0100	[thread overview]
Message-ID: <xa1teh71iz3a.fsf@mina86.com> (raw)
In-Reply-To: <20131030155938.0f5416fe3c5c2cbd3f9cd319@linux-foundation.org>

[-- Attachment #1: Type: text/plain, Size: 2998 bytes --]

On Wed, Oct 30 2013, Andrew Morton wrote:
> On Sat, 26 Oct 2013 12:56:11 +0100 Michal Nazarewicz <mpn@google.com> wrote:
>
>> From: Michal Nazarewicz <mina86@mina86.com>
>> 
>> Changing flags field of the w1_slave to unsigned long may on
>> some architectures increase the size of the structure, but
>> otherwise makes the code more kosher as casting is avoided
>> and *_bit family of calls do not attempt to operate on an
>> entity of bigger size than realy is available.
>> 
>> The current behaviour does not introduce any bugs (since any
>> bytes past flags field are preserved)
>
> hm, what does this mean....
>
>> --- a/drivers/w1/w1.c
>> +++ b/drivers/w1/w1.c
>> @@ -709,7 +709,7 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
>>  
>>  	sl->owner = THIS_MODULE;
>>  	sl->master = dev;
>> -	set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
>> +	set_bit(W1_SLAVE_ACTIVE, &sl->flags);
>
> ...  I'd have though that running this code on little-endian 64-bit
> would result in a scribble over ...
>
>> --- a/drivers/w1/w1.h
>> +++ b/drivers/w1/w1.h
>> @@ -67,8 +67,8 @@ struct w1_slave
>>  	struct w1_reg_num	reg_num;
>>  	atomic_t		refcnt;
>>  	u8			rom[9];
>> -	u32			flags;
>>  	int			ttl;
>
> ... w1_slave.ttl?

Now that I look at documentation, I think you are correct, but the
problem is on big-endian 64-bit architectures.  The fix is still
valid, but the commit message not so much.  Something along the
lines of the following would be better:

-------- >8 --------------------------------------------------------
drivers: w1: make w1_slave::flags long to avoid memory corruption

On architectures where long is more then 32 bits, modifying a 32-bit
field with set_bit (and other atomic bit operations) may cause bytes
following the field to by modified.

Because the endianness of the bits within a field is the native
endianness of the CPU[1], on big-endian machines, bit number zero is
in the last byte of the field.

Therefore, “set_bit(0, ptr)” on a 64-bit big-endian machine is
roughly equivalent to “((char *)ptr)[7] |= 1”, and since w1 driver
uses a 32-bit field for holding the flags, this causes bytes beyond
the field to be modified.

[1] From Documentation/atomic_ops.txt:

    Native atomic bit operations are defined to operate on objects
    aligned to the size of an "unsigned long" C data type, and are
    least of that size.  The endianness of the bits within each
    "unsigned long" are the native endianness of the cpu.
-------- >8 --------------------------------------------------------

>> +	unsigned long		flags;
>>  
>>  	struct w1_master	*master;
>>  	struct w1_family	*family;

-- 
Best regards,                                         _     _
.o. | Liege of Serenely Enlightened Majesty of      o' \,=./ `o
..o | Computer Science,  Michał “mina86” Nazarewicz    (o o)
ooo +--<mpn@google.com>--<xmpp:mina86@jabber.org>--ooO--(_)--Ooo--

[-- Attachment #2.1: Type: text/plain, Size: 0 bytes --]



[-- Attachment #2.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 835 bytes --]

  reply	other threads:[~2013-10-31  9:12 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-26 11:56 [PATCH] drivers: w1: make w1_slave::flags long to avoid casts Michal Nazarewicz
2013-10-30 22:59 ` Andrew Morton
2013-10-31  9:11   ` Michal Nazarewicz [this message]
2013-11-01 16:01     ` Evgeniy Polyakov
2013-11-01 19:30       ` Andrew Morton
2013-11-02  4:10         ` Рустафа Джамурахметов
2013-11-02 16:58           ` Michal Nazarewicz
2013-11-02 17:19             ` Рустафа Джамурахметов

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=xa1teh71iz3a.fsf@mina86.com \
    --to=mina86@mina86.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=zbr@ioremap.net \
    /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.