drivers: w1: make w1_slave::flags long to avoid memory corruption
authorMichal Nazarewicz <mina86@mina86.com>
Tue, 12 Nov 2013 23:11:42 +0000 (15:11 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 13 Nov 2013 03:09:35 +0000 (12:09 +0900)
commitbb67093796a41e0f2601f5c0022fd8873ed59fee
treef52f201e90f5b6678a83bf19a399bec238f906de
parent75f9e937d24fdf661ebd5c9bed05caa4aad90539
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.

Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
Cc: Evgeniy Polyakov <zbr@ioremap.net>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/w1/w1.c
drivers/w1/w1.h