From 10e46b45ef6b52b1e81419ff3de62df6f0abe1c0 Mon Sep 17 00:00:00 2001 From: George McCollister Date: Thu, 21 Jan 2010 12:06:39 -0600 Subject: 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 --- 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 5d40d29fe..cd9890305 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 8a7ccd95f..324ab8352 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 951a1dcef..7dff361e0 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; -- cgit