From bb67093796a41e0f2601f5c0022fd8873ed59fee Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Tue, 12 Nov 2013 15:11:42 -0800 Subject: 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 Cc: Evgeniy Polyakov Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/w1/w1.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/w1/w1.h') diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h index 45908e56c2f8..ca8081a101d6 100644 --- 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; + unsigned long flags; struct w1_master *master; struct w1_family *family; -- cgit v1.2.3