>From 78946b22cd558fe6abad834ee41046116bb21f1a Mon Sep 17 00:00:00 2001
From: George McCollister <georgem@opteron.novatech-llc.com>
Date: Thu, 21 Jan 2010 12:06:39 -0600
Subject: [PATCH] Pointers to non 32 bit aligned data were being cast to uint32_t *

uint32_t pointers must point to 32 bit aligned data on ARM. Instead of padding the data to force it into alignment I altered the code to memcpy the data to an aligned location. I'd appreciate any and all feedback especially on whether I took the best approach.

pam_test_client auth and pam_test_client acct now work on my armeb-xscale-linux-gnueabi target.

Signed-off-by: George McCollister <georgem@opteron.novatech-llc.com>
---
 server/responder/common/responder_cmd.c |    2 +-
 server/responder/pam/pamsrv_cmd.c       |   18 +++++----
 sss_client/pam_sss.c                    |   65 ++++++++++++++++++-------------
 3 files changed, 49 insertions(+), 36 deletions(-)

diff --git a/server/responder/common/responder_cmd.c b/server/responder/common/responder_cmd.c
index 5d40d29..cd98903 100644
--- a/server/responder/common/responder_cmd.c
+++ b/server/responder/common/responder_cmd.c
@@ -56,7 +56,7 @@ int sss_cmd_get_version(struct cli_ctx *cctx)
 
         sss_packet_get_body(cctx->creq->in, &req_body, &req_blen);
         if (req_blen == sizeof(uint32_t)) {
-            client_version = (uint32_t ) *req_body;
+            memcpy(&client_version, req_body, sizeof(uint32_t));
             DEBUG(5, ("Received client version [%d].\n", client_version));
 
             i=0;
diff --git a/server/responder/pam/pamsrv_cmd.c b/server/responder/pam/pamsrv_cmd.c
index 8a7ccd9..324ab83 100644
--- a/server/responder/pam/pamsrv_cmd.c
+++ b/server/responder/pam/pamsrv_cmd.c
@@ -37,12 +37,12 @@ static int extract_authtok(uint32_t *type, uint32_t *size, uint8_t **tok, uint8_
 
     if (blen-(*c) < 2*sizeof(uint32_t)) return EINVAL;
 
-    data_size = ((uint32_t *)&body[*c])[0];
+    memcpy(&data_size, &body[*c], sizeof(uint32_t));
     *c += sizeof(uint32_t);
     if (data_size < sizeof(uint32_t) || (*c)+(data_size) > blen) return EINVAL;
     *size = data_size - sizeof(uint32_t);
 
-    *type = ((uint32_t *)&body[*c])[0];
+    memcpy(type, &body[*c], sizeof(uint32_t));
     *c += sizeof(uint32_t);
 
     *tok = body+(*c);
@@ -58,7 +58,7 @@ static int extract_string(char **var, uint8_t *body, size_t blen, size_t *c) {
 
     if (blen-(*c) < sizeof(uint32_t)+1) return EINVAL;
 
-    size = ((uint32_t *)&body[*c])[0];
+    memcpy(&size, &body[*c], sizeof(uint32_t));
     *c += sizeof(uint32_t);
     if (*c+size > blen) return EINVAL;
 
@@ -78,10 +78,10 @@ static int extract_uint32_t(uint32_t *var, uint8_t *body, size_t blen, size_t *c
 
     if (blen-(*c) < 2*sizeof(uint32_t)) return EINVAL;
 
-    size = ((uint32_t *)&body[*c])[0];
+    memcpy(&size, &body[*c], sizeof(uint32_t));
     *c += sizeof(uint32_t);
 
-    *var = ((uint32_t *)&body[*c])[0];
+    memcpy(var, &body[*c], sizeof(uint32_t));
     *c += sizeof(uint32_t);
 
     return EOK;
@@ -96,17 +96,18 @@ static int pam_parse_in_data_v2(struct sss_names_ctx *snctx,
     uint32_t size;
     char *pam_user;
     int ret;
+    uint32_t terminator = END_OF_PAM_REQUEST;
 
     if (blen < 4*sizeof(uint32_t)+2 ||
         ((uint32_t *)body)[0] != START_OF_PAM_REQUEST ||
-        ((uint32_t *)(&body[blen - sizeof(uint32_t)]))[0] != END_OF_PAM_REQUEST) {
+        memcmp(&body[blen - sizeof(uint32_t)], &terminator, sizeof(uint32_t)) != 0) {
         DEBUG(1, ("Received data is invalid.\n"));
         return EINVAL;
     }
 
     c = sizeof(uint32_t);
     do {
-        type = ((uint32_t *)&body[c])[0];
+        memcpy(&type, &body[c], sizeof(uint32_t));
         c += sizeof(uint32_t);
         if (c > blen) return EINVAL;
 
@@ -670,6 +671,7 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
     size_t blen;
     int timeout;
     int ret;
+    uint32_t terminator = END_OF_PAM_REQUEST;
     preq = talloc_zero(cctx, struct pam_auth_req);
     if (!preq) {
         return ENOMEM;
@@ -685,7 +687,7 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
 
     sss_packet_get_body(cctx->creq->in, &body, &blen);
     if (blen >= sizeof(uint32_t) &&
-        ((uint32_t *)(&body[blen - sizeof(uint32_t)]))[0] != END_OF_PAM_REQUEST) {
+        memcmp(&body[blen - sizeof(uint32_t)], &terminator, sizeof(uint32_t)) != 0) {
         DEBUG(1, ("Received data not terminated.\n"));
         ret = EINVAL;
         goto done;
diff --git a/sss_client/pam_sss.c b/sss_client/pam_sss.c
index 951a1dc..7dff361 100644
--- a/sss_client/pam_sss.c
+++ b/sss_client/pam_sss.c
@@ -105,16 +105,20 @@ static size_t add_authtok_item(enum pam_item_type type,
                                const char *tok, const size_t size,
                                uint8_t *buf) {
     size_t rp=0;
+    uint32_t c;
 
     if (tok == NULL) return 0;
 
-    ((uint32_t *)(&buf[rp]))[0] = type;
+    c = type;
+    memcpy(&buf[rp], &c, sizeof(uint32_t));
     rp += sizeof(uint32_t);
 
-    ((uint32_t *)(&buf[rp]))[0] = size + sizeof(uint32_t);
+    c = size + sizeof(uint32_t);
+    memcpy(&buf[rp], &c, sizeof(uint32_t));
     rp += sizeof(uint32_t);
 
-    ((uint32_t *)(&buf[rp]))[0] = authtok_type;
+    c = authtok_type;
+    memcpy(&buf[rp], &c, sizeof(uint32_t));
     rp += sizeof(uint32_t);
 
     memcpy(&buf[rp], tok, size);
@@ -127,15 +131,18 @@ static size_t add_authtok_item(enum pam_item_type type,
 static size_t add_uint32_t_item(enum pam_item_type type, const uint32_t val,
                                 uint8_t *buf) {
     size_t rp=0;
+    uint32_t c;
 
-
-    ((uint32_t *)(&buf[rp]))[0] = type;
+    c = type;
+    memcpy(&buf[rp], &c, sizeof(uint32_t));
     rp += sizeof(uint32_t);
 
-    ((uint32_t *)(&buf[rp]))[0] = sizeof(uint32_t);
+    c = sizeof(uint32_t);
+    memcpy(&buf[rp], &c, sizeof(uint32_t));
     rp += sizeof(uint32_t);
 
-    ((uint32_t *)(&buf[rp]))[0] = val;
+    c = val;
+    memcpy(&buf[rp], &c, sizeof(uint32_t));
     rp += sizeof(uint32_t);
 
     return rp;
@@ -144,13 +151,16 @@ static size_t add_uint32_t_item(enum pam_item_type type, const uint32_t val,
 static size_t add_string_item(enum pam_item_type type, const char *str,
                            const size_t size, uint8_t *buf) {
     size_t rp=0;
+    uint32_t c;
 
     if (str == NULL || *str == '\0') return 0;
 
-    ((uint32_t *)(&buf[rp]))[0] = type;
+    c = type;
+    memcpy(&buf[rp], &c, sizeof(uint32_t));
     rp += sizeof(uint32_t);
 
-    ((uint32_t *)(&buf[rp]))[0] = size;
+    c = size;
+    memcpy(&buf[rp], &c, sizeof(uint32_t));
     rp += sizeof(uint32_t);
 
     memcpy(&buf[rp], str, size);
@@ -179,6 +189,7 @@ static int pack_message_v3(struct pam_items *pi, size_t *size,
     int len;
     uint8_t *buf;
     int rp;
+    uint32_t terminator = END_OF_PAM_REQUEST;
 
     len = sizeof(uint32_t) +
           2*sizeof(uint32_t) + pi->pam_user_size +
@@ -231,7 +242,7 @@ static int pack_message_v3(struct pam_items *pi, size_t *size,
                            pi->pam_newauthtok, pi->pam_newauthtok_size,
                            &buf[rp]);
 
-    ((uint32_t *)(&buf[rp]))[0] = END_OF_PAM_REQUEST;
+    memcpy(&buf[rp], &terminator, sizeof(uint32_t));
     rp += sizeof(uint32_t);
 
     if (rp != len) {
@@ -362,43 +373,43 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf)
     int ret;
     size_t p=0;
     char *env_item;
-    int32_t *c;
-    int32_t *type;
-    int32_t *len;
-    int32_t *pam_status;
+    int32_t c;
+    int32_t type;
+    int32_t len;
+    int32_t pam_status;
 
     if (buflen < (2*sizeof(int32_t))) {
         D(("response buffer is too small"));
         return PAM_BUF_ERR;
     }
 
-    pam_status = ((int32_t *)(buf+p));
+    memcpy(&pam_status, buf+p, sizeof(int32_t));
     p += sizeof(int32_t);
 
 
-    c = ((int32_t *)(buf+p));
+    memcpy(&c, buf+p, sizeof(int32_t));
     p += sizeof(int32_t);
 
-    while(*c>0) {
+    while(c>0) {
         if (buflen < (p+2*sizeof(int32_t))) {
             D(("response buffer is too small"));
             return PAM_BUF_ERR;
         }
 
-        type = ((int32_t *)(buf+p));
+        memcpy(&type, buf+p, sizeof(int32_t));
         p += sizeof(int32_t);
 
-        len = ((int32_t *)(buf+p));
+        memcpy(&len, buf+p, sizeof(int32_t));
         p += sizeof(int32_t);
 
-        if (buflen < (p + *len)) {
+        if (buflen < (p + len)) {
             D(("response buffer is too small"));
             return PAM_BUF_ERR;
         }
 
-        switch(*type) {
+        switch(type) {
             case PAM_USER_INFO:
-                if (buf[p + (*len -1)] != '\0') {
+                if (buf[p + (len -1)] != '\0') {
                     D(("user info does not end with \\0."));
                     break;
                 }
@@ -410,13 +421,13 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf)
             case ENV_ITEM:
             case PAM_ENV_ITEM:
             case ALL_ENV_ITEM:
-                if (buf[p + (*len -1)] != '\0') {
+                if (buf[p + (len -1)] != '\0') {
                     D(("env item does not end with \\0."));
                     break;
                 }
 
                 D(("env item: [%s]", &buf[p]));
-                if (*type == PAM_ENV_ITEM || *type == ALL_ENV_ITEM) {
+                if (type == PAM_ENV_ITEM || type == ALL_ENV_ITEM) {
                     ret = pam_putenv(pamh, (char *)&buf[p]);
                     if (ret != PAM_SUCCESS) {
                         D(("pam_putenv failed."));
@@ -424,7 +435,7 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf)
                     }
                 }
 
-                if (*type == ENV_ITEM || *type == ALL_ENV_ITEM) {
+                if (type == ENV_ITEM || type == ALL_ENV_ITEM) {
                     env_item = strdup((char *)&buf[p]);
                     if (env_item == NULL) {
                         D(("strdup failed"));
@@ -438,9 +449,9 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf)
                 }
                 break;
         }
-        p += *len;
+        p += len;
 
-        --(*c);
+        --c;
     }
 
     return PAM_SUCCESS;
-- 
1.6.4.2

