From 95e951018530c04dad16c2490914e9a417610c80 Mon Sep 17 00:00:00 2001
From: James Kilts <jameskilts@gmail.com>
Date: Mon, 18 Jan 2010 19:35:24 +0100
Subject: [PATCH 4/4] rtcfg: Fixed various unaligned dereferences that can cause issues on ARM
 processors.  The dereferences are changed to memory copies to avoid
 a processor exception.

Signed-off-by: James Kilts <jameskilts@gmail.com>
---
 stack/rtcfg/rtcfg_client_event.c |   15 +++++++++------
 stack/rtcfg/rtcfg_event.c        |    5 ++++-
 stack/rtcfg/rtcfg_frame.c        |   10 +++++-----
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/stack/rtcfg/rtcfg_client_event.c b/stack/rtcfg/rtcfg_client_event.c
index 18a915b..3f06eeb 100644
--- a/stack/rtcfg/rtcfg_client_event.c
+++ b/stack/rtcfg/rtcfg_client_event.c
@@ -606,11 +606,11 @@ static void rtcfg_client_recv_stage_1(int ifindex, struct rtskb *rtskb)
 
             rtdev = rtskb->rtdev;
 
-            daddr = *(u32*)stage_1_cfg->client_addr;
+            memcpy(&daddr, stage_1_cfg->client_addr, 4);
             stage_1_cfg = (struct rtcfg_frm_stage_1_cfg *)
                 (((u8 *)stage_1_cfg) + RTCFG_ADDRSIZE_IP);
 
-            saddr = *(u32*)stage_1_cfg->server_addr;
+            memcpy(&saddr, stage_1_cfg->server_addr, 4);
             stage_1_cfg = (struct rtcfg_frm_stage_1_cfg *)
                 (((u8 *)stage_1_cfg) + RTCFG_ADDRSIZE_IP);
 
@@ -748,6 +748,7 @@ static int rtcfg_client_recv_announce(int ifindex, struct rtskb *rtskb)
     struct rtcfg_frm_announce *announce_frm;
     struct rtcfg_device       *rtcfg_dev = &device[ifindex];
     u32                       i;
+    u32                       announce_frm_addr;
     int                       result;
 
 
@@ -771,8 +772,10 @@ static int rtcfg_client_recv_announce(int ifindex, struct rtskb *rtskb)
                 return -EINVAL;
             }
 
+            memcpy(&announce_frm_addr, announce_frm->addr, 4);
+
             /* update routing table */
-            rt_ip_route_add_host(*(u32 *)announce_frm->addr,
+            rt_ip_route_add_host(announce_frm_addr,
                                  rtskb->mac.ethernet->h_source, rtskb->rtdev);
 
             announce_frm = (struct rtcfg_frm_announce *)
@@ -1045,7 +1048,7 @@ static void rtcfg_client_recv_dead_station(int ifindex, struct rtskb *rtskb)
                 return;
             }
 
-            ip = *(u32 *)dead_station_frm->logical_addr;
+            memcpy(&ip, dead_station_frm->logical_addr, 4);
 
             /* only delete remote IPs from routing table */
             if (rtskb->rtdev->local_ip != ip)
@@ -1132,11 +1135,11 @@ static void rtcfg_client_update_server(int ifindex, struct rtskb *rtskb)
 
             rtdev = rtskb->rtdev;
 
-            daddr = *(u32*)stage_1_cfg->client_addr;
+            memcpy(&daddr, stage_1_cfg->client_addr, 4);
             stage_1_cfg = (struct rtcfg_frm_stage_1_cfg *)
                 (((u8 *)stage_1_cfg) + RTCFG_ADDRSIZE_IP);
 
-            saddr = *(u32*)stage_1_cfg->server_addr;
+            memcpy(&saddr, stage_1_cfg->server_addr, 4);
             stage_1_cfg = (struct rtcfg_frm_stage_1_cfg *)
                 (((u8 *)stage_1_cfg) + RTCFG_ADDRSIZE_IP);
 
diff --git a/stack/rtcfg/rtcfg_event.c b/stack/rtcfg/rtcfg_event.c
index 03c0963..784351e 100644
--- a/stack/rtcfg/rtcfg_event.c
+++ b/stack/rtcfg/rtcfg_event.c
@@ -506,6 +506,7 @@ static int rtcfg_server_recv_announce(int ifindex, RTCFG_EVENT event_id,
     struct list_head          *entry;
     struct rtcfg_frm_announce *announce;
     struct rtcfg_connection   *conn;
+    u32                        announce_addr;
 
 
     if (rtskb->len < sizeof(struct rtcfg_frm_announce)) {
@@ -522,8 +523,10 @@ static int rtcfg_server_recv_announce(int ifindex, RTCFG_EVENT event_id,
         switch (announce->addr_type) {
 #ifdef CONFIG_RTNET_RTIPV4
             case RTCFG_ADDR_IP:
+                memcpy(&announce_addr, announce->addr, 4);
+
                 if (((conn->addr_type & RTCFG_ADDR_MASK) == RTCFG_ADDR_IP) &&
-                    (*(u32 *)announce->addr == conn->addr.ip_addr)) {
+                    (announce_addr == conn->addr.ip_addr)) {
                     /* save MAC address - Ethernet-specific! */
                     memcpy(conn->mac_addr, rtskb->mac.ethernet->h_source,
                            ETH_ALEN);
diff --git a/stack/rtcfg/rtcfg_frame.c b/stack/rtcfg/rtcfg_frame.c
index d682e04..8bbc948 100644
--- a/stack/rtcfg/rtcfg_frame.c
+++ b/stack/rtcfg/rtcfg_frame.c
@@ -170,12 +170,12 @@ int rtcfg_send_stage_1(struct rtcfg_connection *conn)
     if (stage_1_frm->addr_type == RTCFG_ADDR_IP) {
         rtskb_put(rtskb, 2*RTCFG_ADDRSIZE_IP);
 
-        *(u32*)stage_1_frm->client_addr = conn->addr.ip_addr;
+        memcpy(stage_1_frm->client_addr, &(conn->addr.ip_addr), 4);
 
         stage_1_frm = (struct rtcfg_frm_stage_1_cfg *)
             (((u8 *)stage_1_frm) + RTCFG_ADDRSIZE_IP);
 
-        *(u32*)stage_1_frm->server_addr = rtdev->local_ip;
+        memcpy(stage_1_frm->server_addr, &(rtdev->local_ip), 4);
 
         stage_1_frm = (struct rtcfg_frm_stage_1_cfg *)
             (((u8 *)stage_1_frm) + RTCFG_ADDRSIZE_IP);
@@ -332,7 +332,7 @@ int rtcfg_send_announce_new(int ifindex)
     if (announce_new->addr_type == RTCFG_ADDR_IP) {
         rtskb_put(rtskb, RTCFG_ADDRSIZE_IP);
 
-        *(u32*)announce_new->addr = rtdev->local_ip;
+        memcpy(announce_new->addr, &(rtdev->local_ip), 4);
 
         announce_new = (struct rtcfg_frm_announce *)
             (((u8 *)announce_new) + RTCFG_ADDRSIZE_IP);
@@ -388,7 +388,7 @@ int rtcfg_send_announce_reply(int ifindex, u8 *dest_mac_addr)
     if (announce_rpl->addr_type == RTCFG_ADDR_IP) {
         rtskb_put(rtskb, RTCFG_ADDRSIZE_IP);
 
-        *(u32*)announce_rpl->addr = rtdev->local_ip;
+        memcpy(announce_rpl->addr, &(rtdev->local_ip), 4);
 
         announce_rpl = (struct rtcfg_frm_announce *)
             (((u8 *)announce_rpl) + RTCFG_ADDRSIZE_IP);
@@ -512,7 +512,7 @@ int rtcfg_send_dead_station(struct rtcfg_connection *conn)
     if (dead_station_frm->addr_type == RTCFG_ADDR_IP) {
         rtskb_put(rtskb, RTCFG_ADDRSIZE_IP);
 
-        *(u32*)dead_station_frm->logical_addr = conn->addr.ip_addr;
+        memcpy(dead_station_frm->logical_addr, &(conn->addr.ip_addr), 4);
 
         dead_station_frm = (struct rtcfg_frm_dead_station *)
             (((u8 *)dead_station_frm) + RTCFG_ADDRSIZE_IP);
-- 
1.6.5.1.msysgit.1

