From patchwork Mon May 10 16:06:01 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Neil Jones X-Patchwork-Id: 52104 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 1953CB7D62 for ; Tue, 11 May 2010 02:06:15 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752085Ab0EJQGG (ORCPT ); Mon, 10 May 2010 12:06:06 -0400 Received: from fg-out-1718.google.com ([72.14.220.153]:16874 "EHLO fg-out-1718.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751233Ab0EJQGD (ORCPT ); Mon, 10 May 2010 12:06:03 -0400 Received: by fg-out-1718.google.com with SMTP id d23so1661933fga.1 for ; Mon, 10 May 2010 09:06:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:received:in-reply-to :references:date:message-id:subject:from:to:content-type; bh=dCl+VywW4tqD4RY/jBX0S5kND09Ew3Plr4cBTBKhtgU=; b=daQBSdl1QdYI4sRY2qZSgNytOjvwHbf2PxI6ghTy6gd6d39lkMVl/SjgktDCycJMj/ z2MCuFVghM0fz3XrlIdNSjXtewEqdrr3mqalNph8KrkHuJ3ci4kfEYN8amhmjb6bA5ic v8T8rBCPVvJXyeyU9YsbGFgnJuWw4ErFQSS6U= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; b=l1GO5ikDjAJrPfMKwdR/eT8CFRxX6pAPLpWZ4YVLGpOZxL1bzAIbpYXMgSQlA9ESyy qrXd06VREG+EzLBWx0liPdNzFhPRKziy+UWIIwHCp6z1IZKt4eTbskG9VhU9rZB486pT PedeE8ExcFA8KgPrqK5R+KrNyJVbd6pfIHtJo= MIME-Version: 1.0 Received: by 10.87.62.17 with SMTP id p17mr9971517fgk.30.1273507561607; Mon, 10 May 2010 09:06:01 -0700 (PDT) Received: by 10.86.33.3 with HTTP; Mon, 10 May 2010 09:06:01 -0700 (PDT) In-Reply-To: References: Date: Mon, 10 May 2010 17:06:01 +0100 Message-ID: Subject: [PATCH] drivers/net/usb/asix.c Fix unaligned access From: Neil Jones To: netdev@vger.kernel.org Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From b277dbc256de7b1a8c47ca374914c097ff4cdd50 Mon Sep 17 00:00:00 2001 From: Neil Jones Date: Thu, 6 May 2010 11:20:53 +0100 Subject: [PATCH] drivers/net/usb/asix.c:        Fix unaligned accesses Using this driver can cause unaligned accesses in the IP layer This has been fixed by aligning the skb data correctly using the spare room left over by the 4 byte header inserted between packets by the device. Signed-off-by: Neil Jones ---  drivers/net/usb/asix.c |   37 ++++++++++++++++++++++++++++++++++++-  1 files changed, 36 insertions(+), 1 deletions(-)                } else { -- 1.5.5.2 diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index a516185..5b4f0df 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -319,16 +319,51 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb)                /* get the packet length */                size = (u16) (header & 0x0000ffff); -               if ((skb->len) - ((size + 1) & 0xfffe) == 0) +               if ((skb->len) - ((size + 1) & 0xfffe) == 0) { +                       u8 alignment = (u32)skb->data & 0x3; +                       if (alignment != 0x2) { +                               /* +                                * not 16bit aligned so use the room provided by +                                * the 32 bit header to align the data +                                * +                                * note we want 16bit alignment as MAC header is +                                * 14bytes thus ip header will be aligned on +                                * 32bit boundary so accessing ipheader elements +                                * using a cast to struct ip header wont cause +                                * an unaligned accesses. +                                */ +                               u8 realignment = (alignment + 2) & 0x3; +                               memmove(skb->data - realignment, +                                       skb->data, +                                       size); +                               skb->data -= realignment; +                               skb_set_tail_pointer(skb, size); +                       }                        return 2; +               } + +                if (size > ETH_FRAME_LEN) {                        deverr(dev,"asix_rx_fixup() Bad RX Length %d", size);                        return 0;                }                ax_skb = skb_clone(skb, GFP_ATOMIC);                if (ax_skb) { +                       u8 alignment = (u32)packet & 0x3;                        ax_skb->len = size; + +                       if (alignment != 0x2) { +                               /* +                                * not 16bit aligned use the room provided by +                                * the 32 bit header to align the data +                                */ +                               u8 realignment = (alignment + 2) & 0x3; +                               memmove(packet - realignment, packet, size); +                               packet -= realignment; +                       }                        ax_skb->data = packet; + +                        skb_set_tail_pointer(ax_skb, size);                        usbnet_skb_return(dev, ax_skb);