Messages in this thread | | | Date | Wed, 11 Mar 2009 13:51:08 +0100 (CET) | From | yann.poupet@free ... | Subject | [PROBLEM]: potential unaligned memory access in drivers/usb/gadget/rndis.c |
| |
Hello,
while working on a 2.6.18.2 kernel on ARM9 arch., I noticed RNDIS module might trigger lots of unaligned access exceptions. Looks like it comes from rndis_add_hdr() function, which uses pointer from skb_pull as if it is aligned on a 4bytes boundary.
void rndis_add_hdr (struct sk_buff *skb) { struct rndis_packet_msg_type *header;
if (!skb) return; header = (void *) skb_push (skb, sizeof *header); memset (header, 0, sizeof *header); header->MessageType = __constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG); header->MessageLength = cpu_to_le32(skb->len); header->DataOffset = __constant_cpu_to_le32 (36); header->DataLength = cpu_to_le32(skb->len - sizeof *header); }
It happened to me that skb_pull() returns a pointer to a location not aligned on a 4 bytes boundary.
As a quick workaround, I modified the code to:
void rndis_add_hdr (struct sk_buff *skb) { struct rndis_packet_msg_type *header; static struct rndis_packet_msg_type new = { __constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG), /* MessageType */ 0, /* MessageLength */ __constant_cpu_to_le32 (36), /* DataOffset */ 0, /* DataLength */ 0, /* OOBDataOffset */ 0, /* OOBDataLength */ 0, /* NumOOBDataElements */ 0, /* PerPacketInfoOffset */ 0, /* PerPacketInfoLength */ 0, /* VcHandle */ 0, /* Reserved */ };
if (!skb) return; header = (void *) skb_push (skb, sizeof *header); memset (header, 0, sizeof *header); /* probably not necessary */ new.MessageLength = cpu_to_le32(skb->len); new.DataLength = cpu_to_le32(skb->len - sizeof *header); memcpy((u8*)header,(u8*)&new,sizeof(new)); }
and did not have the unaligned exceptions anymore.
I had a look at rndis.c in latest kernel version (2.6.28.7), the rndis_add_hdr() function is the same as for 2.6.18.2.
Hope this helps.
Regards,
Yann Poupet.
| |