gbproxy: Address two unaligned memory access warnings

The lines 461 and 303 were producing unaligned memory access as
the BVCI was not aligned properly. Introduce a tlvp_val16_unal to
read 16bit from the data, use memcpy to the stack to make sure
that it is working in the aligned and unaligned case.
This commit is contained in:
Holger Hans Peter Freyther 2012-09-04 20:42:20 +02:00
parent 7a7c2f8567
commit ffd6856249
1 changed files with 14 additions and 8 deletions

View File

@ -39,6 +39,13 @@
#include <openbsc/debug.h> #include <openbsc/debug.h>
#include <openbsc/gb_proxy.h> #include <openbsc/gb_proxy.h>
static uint16_t tlvp_val16_unal(const struct tlv_parsed *tp, int pos)
{
uint16_t res;
memcpy(&res, TLVP_VAL(tp, pos), sizeof(res));
return res;
}
struct gbprox_peer { struct gbprox_peer {
struct llist_head list; struct llist_head list;
@ -306,7 +313,7 @@ static int gbprox_rx_sig_from_bss(struct msgb *msg, struct gprs_nsvc *nsvc,
* don't want the SGSN to reset, as the signalling endpoint * don't want the SGSN to reset, as the signalling endpoint
* is common for all point-to-point BVCs (and thus all BTS) */ * is common for all point-to-point BVCs (and thus all BTS) */
if (TLVP_PRESENT(&tp, BSSGP_IE_BVCI)) { if (TLVP_PRESENT(&tp, BSSGP_IE_BVCI)) {
uint16_t bvci = ntohs(*(uint16_t *)TLVP_VAL(&tp, BSSGP_IE_BVCI)); uint16_t bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
LOGP(DGPRS, LOGL_INFO, "NSEI=%u Rx BVC RESET (BVCI=%u)\n", LOGP(DGPRS, LOGL_INFO, "NSEI=%u Rx BVC RESET (BVCI=%u)\n",
nsvc->nsei, bvci); nsvc->nsei, bvci);
if (bvci == 0) { if (bvci == 0) {
@ -367,7 +374,7 @@ static int gbprox_rx_paging(struct msgb *msg, struct tlv_parsed *tp,
LOGP(DGPRS, LOGL_INFO, "NSEI=%u(SGSN) BSSGP PAGING ", LOGP(DGPRS, LOGL_INFO, "NSEI=%u(SGSN) BSSGP PAGING ",
nsvc->nsei); nsvc->nsei);
if (TLVP_PRESENT(tp, BSSGP_IE_BVCI)) { if (TLVP_PRESENT(tp, BSSGP_IE_BVCI)) {
uint16_t bvci = ntohs(*(uint16_t *)TLVP_VAL(tp, BSSGP_IE_BVCI)); uint16_t bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI));
LOGPC(DGPRS, LOGL_INFO, "routing by BVCI to peer BVCI=%u\n", LOGPC(DGPRS, LOGL_INFO, "routing by BVCI to peer BVCI=%u\n",
bvci); bvci);
} else if (TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA)) { } else if (TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA)) {
@ -400,7 +407,7 @@ static int rx_reset_from_sgsn(struct msgb *msg, struct tlv_parsed *tp,
return bssgp_tx_status(BSSGP_CAUSE_MISSING_MAND_IE, return bssgp_tx_status(BSSGP_CAUSE_MISSING_MAND_IE,
NULL, msg); NULL, msg);
} }
ptp_bvci = ntohs(*(uint16_t *)TLVP_VAL(tp, BSSGP_IE_BVCI)); ptp_bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI));
if (ptp_bvci >= 2) { if (ptp_bvci >= 2) {
/* A reset for a PTP BVC was received, forward it to its /* A reset for a PTP BVC was received, forward it to its
@ -464,7 +471,7 @@ static int gbprox_rx_sig_from_sgsn(struct msgb *msg, struct gprs_nsvc *nsvc,
/* simple case: BVCI IE is mandatory */ /* simple case: BVCI IE is mandatory */
if (!TLVP_PRESENT(&tp, BSSGP_IE_BVCI)) if (!TLVP_PRESENT(&tp, BSSGP_IE_BVCI))
goto err_mand_ie; goto err_mand_ie;
bvci = ntohs(*(uint16_t *)TLVP_VAL(&tp, BSSGP_IE_BVCI)); bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
rc = gbprox_relay2bvci(msg, bvci, ns_bvci); rc = gbprox_relay2bvci(msg, bvci, ns_bvci);
break; break;
case BSSGP_PDUT_PAGING_PS: case BSSGP_PDUT_PAGING_PS:
@ -484,10 +491,9 @@ static int gbprox_rx_sig_from_sgsn(struct msgb *msg, struct gprs_nsvc *nsvc,
"cause=0x%02x(%s) ", *TLVP_VAL(&tp, BSSGP_IE_CAUSE), "cause=0x%02x(%s) ", *TLVP_VAL(&tp, BSSGP_IE_CAUSE),
bssgp_cause_str(*TLVP_VAL(&tp, BSSGP_IE_CAUSE))); bssgp_cause_str(*TLVP_VAL(&tp, BSSGP_IE_CAUSE)));
if (TLVP_PRESENT(&tp, BSSGP_IE_BVCI)) { if (TLVP_PRESENT(&tp, BSSGP_IE_BVCI)) {
uint16_t *bvci = (uint16_t *) uint16_t bvci = tlvp_val16_unal(&tp, BSSGP_IE_BVCI);
TLVP_VAL(&tp, BSSGP_IE_BVCI);
LOGPC(DGPRS, LOGL_NOTICE, LOGPC(DGPRS, LOGL_NOTICE,
"BVCI=%u\n", ntohs(*bvci)); "BVCI=%u\n", ntohs(bvci));
} else } else
LOGPC(DGPRS, LOGL_NOTICE, "\n"); LOGPC(DGPRS, LOGL_NOTICE, "\n");
break; break;
@ -508,7 +514,7 @@ static int gbprox_rx_sig_from_sgsn(struct msgb *msg, struct gprs_nsvc *nsvc,
case BSSGP_PDUT_BVC_UNBLOCK_ACK: case BSSGP_PDUT_BVC_UNBLOCK_ACK:
if (!TLVP_PRESENT(&tp, BSSGP_IE_BVCI)) if (!TLVP_PRESENT(&tp, BSSGP_IE_BVCI))
goto err_mand_ie; goto err_mand_ie;
bvci = ntohs(*(uint16_t *)TLVP_VAL(&tp, BSSGP_IE_BVCI)); bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
if (bvci == 0) { if (bvci == 0) {
LOGP(DGPRS, LOGL_NOTICE, "NSEI=%u(SGSN) BSSGP " LOGP(DGPRS, LOGL_NOTICE, "NSEI=%u(SGSN) BSSGP "
"%sBLOCK_ACK for signalling BVCI ?!?\n", nsvc->nsei, "%sBLOCK_ACK for signalling BVCI ?!?\n", nsvc->nsei,