osmith has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/28938 )
Change subject: gsm0808_enc_aoip_trasp_addr: add length check ......................................................................
gsm0808_enc_aoip_trasp_addr: add length check
Instead of running into OSMO_ASSERT in msg_put(), return early if the msgb is too small. As suggested by Pau in [1].
I would have returned -EMSGSIZE, but the function returns uint8_t.
[1]: https://gerrit.osmocom.org/c/osmo-bsc-nat/+/28582/2#message-a183c463ea20a8d9...
Change-Id: I632986b99d841abff0f14c6da65f030175f5c4a1 --- M src/gsm/gsm0808_utils.c M tests/gsm0808/gsm0808_test.c 2 files changed, 40 insertions(+), 8 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/38/28938/1
diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index 040872b..ac1c4bf 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -78,7 +78,7 @@ /*! Encode TS 08.08 AoIP transport address IE * \param[out] msg Message Buffer to which to append IE * \param[in] ss Socket Address to be used in IE - * \returns number of bytes added to \a msg */ + * \returns number of bytes added to \a msg; 0 if msg is too small */ uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, const struct sockaddr_storage *ss) { @@ -87,16 +87,27 @@ struct sockaddr_in6 *sin6; uint16_t port = 0; uint8_t *ptr; - uint8_t *old_tail; - uint8_t *tlv_len; + uint8_t len_tl = 2; + uint8_t len_v = sizeof(port);
OSMO_ASSERT(msg); OSMO_ASSERT(ss); OSMO_ASSERT(ss->ss_family == AF_INET || ss->ss_family == AF_INET6);
+ switch (ss->ss_family) { + case AF_INET: + len_v += IP_V4_ADDR_LEN; + break; + case AF_INET6: + len_v += IP_V6_ADDR_LEN; + break; + } + + if (msgb_tailroom(msg) < len_tl + len_v) + return 0; + msgb_put_u8(msg, GSM0808_IE_AOIP_TRASP_ADDR); - tlv_len = msgb_put(msg,1); - old_tail = msg->tail; + msgb_put_u8(msg, len_v);
switch (ss->ss_family) { case AF_INET: @@ -114,9 +125,7 @@ }
msgb_put_u16(msg, port); - - *tlv_len = (uint8_t) (msg->tail - old_tail); - return *tlv_len + 2; + return len_tl + len_v; }
/*! Decode TS 08.08 AoIP transport address IE diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 158aeba..b3aa3ab 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -924,6 +924,28 @@ msgb_free(msg); }
+static void test_enc_aoip_trasp_addr_msg_too_small() +{ + struct msgb *msg; + struct sockaddr_storage enc_addr; + struct sockaddr_in enc_addr_in; + uint8_t rc_enc; + + memset(&enc_addr_in, 0, sizeof(enc_addr_in)); + enc_addr_in.sin_family = AF_INET; + enc_addr_in.sin_port = htons(1234); + inet_aton("255.0.255.255", &enc_addr_in.sin_addr); + + memset(&enc_addr, 0, sizeof(enc_addr)); + memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in)); + + msg = msgb_alloc(7, "output buffer"); + rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr); + OSMO_ASSERT(rc_enc == 0); + + msgb_free(msg); +} + static void test_gsm0808_enc_dec_speech_codec() { struct gsm0808_speech_codec enc_sc = { @@ -2540,6 +2562,7 @@
test_enc_dec_aoip_trasp_addr_v4(); test_enc_dec_aoip_trasp_addr_v6(); + test_enc_aoip_trasp_addr_msg_too_small(); test_gsm0808_enc_dec_speech_codec(); test_gsm0808_enc_dec_speech_codec_ext_with_cfg(); test_gsm0808_enc_dec_speech_codec_with_cfg();