From 594cd56b4b0867b033332f3b262bf423d6141021 Mon Sep 17 00:00:00 2001 From: Stefan Becker Date: Fri, 15 Oct 2010 15:27:08 +0300 Subject: [PATCH] fix alignment errors detected with -Wcast-align on armel --- src/core/sip-sec-ntlm-tests.c | 23 ++++++++------- src/core/sip-sec-ntlm.c | 68 +++++++++++++++++++++++-------------------- src/core/sipe-utils.c | 25 ++++++++-------- src/purple/purple-dnsquery.c | 14 +++++---- 4 files changed, 71 insertions(+), 59 deletions(-) diff --git a/src/core/sip-sec-ntlm-tests.c b/src/core/sip-sec-ntlm-tests.c index 17528d85..8a7b2c9f 100644 --- a/src/core/sip-sec-ntlm-tests.c +++ b/src/core/sip-sec-ntlm-tests.c @@ -53,15 +53,16 @@ static int failures = 0; gboolean sip_sec_ntlm_tests(void); -static void assert_equal(const char * expected, const guchar * got, int len, gboolean stringify) +static void assert_equal(const char * expected, gpointer got, int len, gboolean stringify) { const gchar * res = (gchar *) got; gchar to_str[len*2]; if (stringify) { + const guint8 *bin = got; int i, j; for (i = 0, j = 0; i < len; i++, j+=2) { - g_sprintf(&to_str[j], "%02X", (got[i]&0xff)); + g_sprintf(&to_str[j], "%02X", (bin[i]&0xff)); } len *= 2; res = to_str; @@ -119,7 +120,7 @@ gboolean sip_sec_ntlm_tests(void) guchar client_sign_key [16]; guchar server_sign_key [16]; guchar server_seal_key [16]; - guchar mac [16]; + guint32 mac [4]; guchar text_enc [18 + 12]; struct sipmsg *msg; struct sipmsg_breakdown msgbd; @@ -508,7 +509,7 @@ Response: msg_str, 0, exported_session_key2, exported_session_key2, mac); sipmsg_breakdown_free(&msgbd); assert_equal ("0100000000000000BF2E52667DDF6DED", mac, 16, TRUE); - sig = buff_to_hex_str(mac, 16); + sig = buff_to_hex_str((guint8 *)mac, 16); } @@ -693,17 +694,19 @@ Message (length 352): int target_info2_len; guint8 *nonce2; guint8 *target_info2; - guint8 *buff2; - hex_str_to_buff("59519A1727B9CA01", &buff2); + guint64 *buff2; + /* buff2 points to correctly aligned memory. Disable alignment check */ + hex_str_to_buff("59519A1727B9CA01", (void *)&buff2); /* global var */ - test_time_val = GUINT64_FROM_LE(*((guint64 *)buff2)); + test_time_val = GUINT64_FROM_LE(*buff2); g_free(buff2); target_info2_len = hex_str_to_buff("02000A0043004F0053004D004F000100180043004F0053004D004F002D004F00430053002D00520032000400160063006F0073006D006F002E006C006F00630061006C000300300063006F0073006D006F002D006F00630073002D00720032002E0063006F0073006D006F002E006C006F00630061006C000500160063006F0073006D006F002E006C006F00630061006C0000000000", &target_info2); hex_str_to_buff("DD1BAAF4E7E218D1", &nonce2); - hex_str_to_buff("D6AE875CB0FDAA41", &buff2); + /* buff2 points to correctly aligned memory. Disable alignment check */ + hex_str_to_buff("D6AE875CB0FDAA41", (void *)&buff2); /* global buff */ memcpy(test_client_challenge, buff2, 8); g_free(buff2); @@ -762,7 +765,7 @@ Message (length 352): sip_sec_ntlm_sipe_signature_make (flags, msg_str, 0, client_sign_key, client_seal_key, mac); sipmsg_breakdown_free(&msgbd); assert_equal ("0100000029618e9651b65a7764000000", mac, 16, TRUE); - sig = buff_to_hex_str(mac, 16); + sig = buff_to_hex_str((guint8 *)mac, 16); printf ("\n\nTesting (NTLMv2 / OC 2007 R2) Message Parsing, Signing, and Verification\nServer response\n(Authentication Protocol version 4)\n"); msg = sipmsg_parse_msg(response); @@ -774,7 +777,7 @@ Message (length 352): sip_sec_ntlm_sipe_signature_make (flags, msg_str, 0, server_sign_key, server_seal_key, mac); sipmsg_breakdown_free(&msgbd); assert_equal ("01000000E615438A917661BE64000000", mac, 16, TRUE); - sig = buff_to_hex_str(mac, 16); + sig = buff_to_hex_str((guint8 *)mac, 16); printf ("\n\nTesting (NTLMv2 / OC 2007 R2) MAC - client signing\n"); MAC (flags, (gchar*)request_sig,strlen(request_sig), client_sign_key,16, client_seal_key,16, 0, 100, mac); diff --git a/src/core/sip-sec-ntlm.c b/src/core/sip-sec-ntlm.c index ece3ebb7..9506865c 100644 --- a/src/core/sip-sec-ntlm.c +++ b/src/core/sip-sec-ntlm.c @@ -590,23 +590,23 @@ EndDefine /* client_challenge (8) & temp (temp_len) buff */ int temp_len = 8+8+8+4+target_info_len+4; - guint8 *temp2 = g_malloc(8 + temp_len); - memset(temp2, 0, 8 + temp_len); /* init to 0 */ - temp2[8+0] = 1; - temp2[8+1] = 1; - *((guint64 *)(temp2+8+8)) = GUINT64_TO_LE(time_val); /* should be int64 aligned: OK for sparc */ - memcpy(temp2+8+16, client_challenge, 8); - memcpy(temp2+8+28, target_info, target_info_len); + guint64 *temp2 = g_malloc0(8 + temp_len); + ((guint8 *) temp2)[8+0] = 1; + ((guint8 *) temp2)[8+1] = 1; + temp2[2] = GUINT64_TO_LE(time_val); /* should be int64 aligned: OK for sparc */ + memcpy(((guint8 *) temp2)+8+16, client_challenge, 8); + memcpy(((guint8 *) temp2)+8+28, target_info, target_info_len); /* NTProofStr */ //Set NTProofStr to HMAC_MD5(ResponseKeyNT, ConcatenationOf(CHALLENGE_MESSAGE.ServerChallenge,temp)) memcpy(temp2, server_challenge, 8); - HMAC_MD5(response_key_nt, 16, temp2, 8+temp_len, nt_proof_str); + HMAC_MD5(response_key_nt, 16, (guint8*)temp2, 8+temp_len, nt_proof_str); /* NtChallengeResponse */ //Set NtChallengeResponse to ConcatenationOf(NTProofStr, temp) memcpy(nt_challenge_response, nt_proof_str, 16); - memcpy(nt_challenge_response+16, temp2+8, temp_len); + memcpy(nt_challenge_response+16, temp2+1, temp_len); + g_free(temp2); /* SessionBaseKey */ //SessionBaseKey to HMAC_MD5(ResponseKeyNT, NTProofStr) @@ -618,8 +618,6 @@ EndDefine HMAC_MD5(response_key_lm, 16, tmp, 16, lm_challenge_response); memcpy(lm_challenge_response+16, client_challenge, 8); - g_free(temp2); - #ifndef _SIPE_COMPILING_TESTS /* Not used in NTLMv2 */ (void)neg_flags; @@ -827,7 +825,7 @@ MAC (guint32 flags, unsigned long seal_key_len, guint32 random_pad, guint32 sequence, - unsigned char *result) + guint32 *result) { guint32 *res_ptr; @@ -853,41 +851,41 @@ MAC (guint32 flags, unsigned char seal_key_ [16]; guchar hmac[16]; - guchar *tmp = g_malloc(4 + buf_len); + guint32 *tmp = g_malloc(4 + buf_len); /* SealingKey' = MD5(ConcatenationOf(SealingKey, SequenceNumber)) RC4Init(Handle, SealingKey') */ if (IS_FLAG(flags, NTLMSSP_NEGOTIATE_DATAGRAM)) { - unsigned char tmp2 [16+4]; + guint32 tmp2[4+1]; memcpy(tmp2, seal_key, seal_key_len); - *((guint32 *)(tmp2+16)) = GUINT32_TO_LE(sequence); - MD5 (tmp2, 16+4, seal_key_); + tmp2[4] = GUINT32_TO_LE(sequence); + MD5 ((guchar *)tmp2, sizeof(tmp2), seal_key_); } else { memcpy(seal_key_, seal_key, seal_key_len); } SIPE_DEBUG_INFO_NOFORMAT("NTLM MAC(): Extented Session Security"); - res_ptr = (guint32 *)result; + res_ptr = result; res_ptr[0] = GUINT32_TO_LE(1); // 4 bytes res_ptr[3] = GUINT32_TO_LE(sequence); - res_ptr = (guint32 *)tmp; + res_ptr = tmp; res_ptr[0] = GUINT32_TO_LE(sequence); - memcpy(tmp+4, buf, buf_len); + memcpy(tmp+1, buf, buf_len); - HMAC_MD5(sign_key, sign_key_len, tmp, 4 + buf_len, hmac); + HMAC_MD5(sign_key, sign_key_len, (guchar *)tmp, 4 + buf_len, hmac); + g_free(tmp); if (IS_FLAG(flags, NTLMSSP_NEGOTIATE_KEY_EXCH)) { SIPE_DEBUG_INFO_NOFORMAT("NTLM MAC(): Key Exchange"); - RC4K(seal_key_, seal_key_len, hmac, 8, result+4); + RC4K(seal_key_, seal_key_len, hmac, 8, (guchar *)(result+1)); } else { SIPE_DEBUG_INFO_NOFORMAT("NTLM MAC(): *NO* Key Exchange"); - memcpy(result+4, hmac, 8); + memcpy(result+1, hmac, 8); } - g_free(tmp); } else { /* The content of the first 4 bytes is irrelevant */ guint32 crc = CRC32(buf, strlen(buf)); @@ -899,9 +897,9 @@ MAC (guint32 flags, SIPE_DEBUG_INFO_NOFORMAT("NTLM MAC(): *NO* Extented Session Security"); - RC4K(seal_key, seal_key_len, (const guchar *)plaintext, 12, result+4); + RC4K(seal_key, seal_key_len, (const guchar *)plaintext, 12, (guchar *)(result+1)); - res_ptr = (guint32 *)result; + res_ptr = result; // Highest four bytes are the Version res_ptr[0] = GUINT32_TO_LE(0x00000001); // 4 bytes @@ -925,7 +923,8 @@ sip_sec_ntlm_parse_challenge(SipSecBuffer in_buff, guchar **target_info, int *target_info_len) { - struct challenge_message *cmsg = (struct challenge_message*)in_buff.value; + /* SipSecBuffer.value is g_malloc()'d: use (void *) to remove guint8 alignment */ + struct challenge_message *cmsg = (void *)in_buff.value; guint32 host_flags = GUINT32_FROM_LE(cmsg->flags); /* server challenge (nonce) */ @@ -1270,13 +1269,13 @@ sip_sec_ntlm_sipe_signature_make(guint32 flags, guint32 random_pad, unsigned char *sign_key, unsigned char *seal_key, - unsigned char *result) + guint32 *result) { char *res; MAC(flags, msg,strlen(msg), sign_key,16, seal_key,16, random_pad, 100, result); - res = buff_to_hex_str(result, 16); + res = buff_to_hex_str((guint8 *)result, 16); SIPE_DEBUG_INFO("NTLM calculated MAC: %s", res); g_free(res); } @@ -1645,7 +1644,8 @@ sip_sec_ntlm_message_describe(SipSecBuffer buff) if (buff.length == 0 || buff.value == NULL || buff.length < 12) return NULL; - msg = (struct ntlm_message *)buff.value; + /* SipSecBuffer.value is g_malloc()'d: use (void *) to remove guint8 alignment */ + msg = (void *)buff.value; if(!sipe_strequal("NTLMSSP", (char*)msg)) return NULL; switch (GUINT32_FROM_LE(msg->type)) { @@ -1803,7 +1803,10 @@ sip_sec_make_signature__ntlm(SipSecContext context, 0, ((context_ntlm) context)->client_sign_key, ((context_ntlm) context)->client_seal_key, - signature->value); + /* SipSecBuffer.value is g_malloc()'d: + * use (void *) to remove guint8 alignment + */ + (void *)signature->value); return SIP_SEC_E_OK; } @@ -1816,8 +1819,9 @@ sip_sec_verify_signature__ntlm(SipSecContext context, const char *message, SipSecBuffer signature) { - guint8 mac[16]; - guint32 random_pad = GUINT32_FROM_LE(((guint32 *) signature.value)[1]); + guint32 mac[4]; + /* SipSecBuffer.value is g_malloc()'d: use (void *) to remove guint8 alignment */ + guint32 random_pad = GUINT32_FROM_LE(((guint32 *)((void *)signature.value))[1]); sip_sec_ntlm_sipe_signature_make(((context_ntlm) context)->flags, message, diff --git a/src/core/sipe-utils.c b/src/core/sipe-utils.c index d85ae0d4..a0cefbaf 100644 --- a/src/core/sipe-utils.c +++ b/src/core/sipe-utils.c @@ -493,38 +493,39 @@ void sipe_utils_shrink_buffer(struct sipe_transport_connection *conn, # define HX_SIZE_OF_IFREQ(a) sizeof(a) #endif +#define IFREQ_MAX 32 + const char * sipe_utils_get_suitable_local_ip(int fd) { int source = (fd >= 0) ? fd : socket(PF_INET,SOCK_STREAM, 0); if (source >= 0) { - char buffer[1024]; - static char ip[16]; - char *tmp; + struct ifreq buffer[IFREQ_MAX]; struct ifconf ifc; guint32 lhost = htonl(127 * 256 * 256 * 256 + 1); guint32 llocal = htonl((169 << 24) + (254 << 16)); + guint i; + static char ip[16]; ifc.ifc_len = sizeof(buffer); - ifc.ifc_req = (struct ifreq *)buffer; + ifc.ifc_req = buffer; ioctl(source, SIOCGIFCONF, &ifc); if (fd < 0) close(source); - tmp = buffer; - while (tmp < buffer + ifc.ifc_len) + for (i = 0; i < IFREQ_MAX; i++) { - struct ifreq *ifr = (struct ifreq *)tmp; - tmp += HX_SIZE_OF_IFREQ(*ifr); + struct ifreq *ifr = &buffer[i]; if (ifr->ifr_addr.sa_family == AF_INET) { - struct sockaddr_in *sinptr = (struct sockaddr_in *)&ifr->ifr_addr; - if (sinptr->sin_addr.s_addr != lhost - && (sinptr->sin_addr.s_addr & htonl(0xFFFF0000)) != llocal) + struct sockaddr_in sin; + memcpy(&sin, &ifr->ifr_addr, sizeof(struct sockaddr_in)); + if (sin.sin_addr.s_addr != lhost + && (sin.sin_addr.s_addr & htonl(0xFFFF0000)) != llocal) { - long unsigned int add = ntohl(sinptr->sin_addr.s_addr); + long unsigned int add = ntohl(sin.sin_addr.s_addr); g_snprintf(ip, 16, "%lu.%lu.%lu.%lu", ((add >> 24) & 255), ((add >> 16) & 255), diff --git a/src/purple/purple-dnsquery.c b/src/purple/purple-dnsquery.c index cb7e04cb..45b99ecf 100644 --- a/src/purple/purple-dnsquery.c +++ b/src/purple/purple-dnsquery.c @@ -28,7 +28,7 @@ #include #endif -#include "glib.h" +#include #include "dnsquery.h" #include "dnssrv.h" @@ -62,11 +62,15 @@ static void dns_a_response(GSList *hosts, addr = g_slist_next(hosts)->data; if (addr->sa_family == AF_INET6) { - addrdata = &((struct sockaddr_in6 *) addr)->sin6_addr; - port = ((struct sockaddr_in6 *) addr)->sin6_port; + /* OS provides addr so it must be properly aligned */ + struct sockaddr_in6 *sin6 = (void *) addr; + addrdata = &sin6->sin6_addr; + port = sin6->sin6_port; } else { - addrdata = &((struct sockaddr_in *) addr)->sin_addr; - port = ((struct sockaddr_in *) addr)->sin_port; + /* OS provides addr so it must be properly aligned */ + struct sockaddr_in *sin = (void *) addr; + addrdata = &sin->sin_addr; + port = sin->sin_port; } inet_ntop(addr->sa_family, addrdata, ipstr, sizeof (ipstr)); -- 2.11.4.GIT