pespin has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/43424?usp=email )
Change subject: sccp2sua: sccp_to_xua_*(): Fix potential read buffer overflow ......................................................................
sccp2sua: sccp_to_xua_*(): Fix potential read buffer overflow
All the sccp_to_xua_*() functions were lacking proper input length validation to make sure already the header and pointer tables were available in the input buffer.
Related: OS#7080 Reported-By: Tristan Madani tristan@talencesecurity.com Change-Id: I310c9b65625aef227100cbc37709dc63fc4e7f8a --- M src/sccp2sua.c 1 file changed, 42 insertions(+), 0 deletions(-)
Approvals: osmith: Looks good to me, approved Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve
diff --git a/src/sccp2sua.c b/src/sccp2sua.c index 84e06df..910ed84 100644 --- a/src/sccp2sua.c +++ b/src/sccp2sua.c @@ -1164,6 +1164,9 @@ { struct sccp_connection_request *req = (struct sccp_connection_request *)msg->l2h;
+ if (msgb_l2len(msg) < sizeof(*req)) + return NULL; + /* Fixed Part */ xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, req->proto_class); xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&req->source_local_reference)); @@ -1200,6 +1203,9 @@ { struct sccp_connection_confirm *cnf = (struct sccp_connection_confirm *)msg->l2h;
+ if (msgb_l2len(msg) < sizeof(*cnf)) + return NULL; + /* Fixed Part */ xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, cnf->proto_class); xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&cnf->destination_local_reference)); @@ -1233,6 +1239,9 @@ { const struct sccp_connection_refused *ref = (const struct sccp_connection_refused *)msg->l2h;
+ if (msgb_l2len(msg) < sizeof(*ref)) + return NULL; + /* Fixed Part */ xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&ref->destination_local_reference)); xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | ref->cause); @@ -1262,6 +1271,9 @@ { const struct sccp_connection_released *rlsd = (const struct sccp_connection_released *)msg->l2h;
+ if (msgb_l2len(msg) < sizeof(*rlsd)) + return NULL; + /* Fixed Part */ xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&rlsd->destination_local_reference)); xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&rlsd->source_local_reference)); @@ -1296,6 +1308,9 @@ const struct sccp_connection_release_complete *rlc; rlc = (const struct sccp_connection_release_complete *) msg->l2h;
+ if (msgb_l2len(msg) < sizeof(*rlc)) + return NULL; + /* Fixed Part */ xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&rlc->destination_local_reference)); xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&rlc->source_local_reference)); @@ -1324,6 +1339,9 @@ { const struct sccp_data_form1 *dt1 = (const struct sccp_data_form1 *) msg->l2h;
+ if (msgb_l2len(msg) < sizeof(*dt1)) + return NULL; + /* Fixed Part */ xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&dt1->destination_local_reference)); xua_msg_add_u32(xua, SUA_IEI_SEGMENTATION, dt1->segmenting); @@ -1356,6 +1374,9 @@ { const struct sccp_data_unitdata *udt = (const struct sccp_data_unitdata *)msg->l2h;
+ if (msgb_l2len(msg) < sizeof(*udt)) + return NULL; + /* Fixed Part */ xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, udt->proto_class); /* Variable Part */ @@ -1406,6 +1427,9 @@ { const struct sccp_data_ext_unitdata *xudt = (const struct sccp_data_ext_unitdata *)msg->l2h;
+ if (msgb_l2len(msg) < sizeof(*xudt)) + return NULL; + /* Fixed Part */ xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, xudt->proto_class); xua_msg_add_u32(xua, SUA_IEI_S7_HOP_CTR, xudt->hop_counter); @@ -1453,6 +1477,9 @@ { struct sccp_data_long_unitdata *ludt = (struct sccp_data_long_unitdata *)msg->l2h;
+ if (msgb_l2len(msg) < sizeof(*ludt)) + return NULL; + /* Fixed Part */ xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, ludt->proto_class); xua_msg_add_u32(xua, SUA_IEI_S7_HOP_CTR, ludt->hop_counter); @@ -1493,6 +1520,9 @@ const struct sccp_data_unitdata_service *udts; udts = (const struct sccp_data_unitdata_service *)msg->l2h;
+ if (msgb_l2len(msg) < sizeof(*udts)) + return NULL; + /* Fixed Part */ xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RETURN | udts->return_cause); /* Variable Part */ @@ -1544,6 +1574,9 @@ const struct sccp_data_ext_unitdata_service *xudts; xudts = (const struct sccp_data_ext_unitdata_service *)msg->l2h;
+ if (msgb_l2len(msg) < sizeof(*xudts)) + return NULL; + /* Fixed Part */ xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RETURN | xudts->return_cause); xua_msg_add_u32(xua, SUA_IEI_S7_HOP_CTR, xudts->hop_counter); @@ -1584,6 +1617,9 @@ const struct sccp_data_long_unitdata_service *ludts; ludts = (const struct sccp_data_long_unitdata_service *)msg->l2h;
+ if (msgb_l2len(msg) < sizeof(*ludts)) + return NULL; + /* Fixed Part */ xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RETURN | ludts->return_cause); xua_msg_add_u32(xua, SUA_IEI_S7_HOP_CTR, ludts->hop_counter); @@ -1623,6 +1659,9 @@ { const struct sccp_data_it *it = (const struct sccp_data_it *)msg->l2h;
+ if (msgb_l2len(msg) < sizeof(*it)) + return NULL; + /* Fixed Part */ xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, it->proto_class); xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&it->source_local_reference)); @@ -1662,6 +1701,9 @@ { const struct sccp_proto_err *err = (const struct sccp_proto_err *)msg->l2h;
+ if (msgb_l2len(msg) < sizeof(*err)) + return NULL; + /* Fixed Part */ xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&err->destination_local_reference)); xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_ERROR | err->error_cause);