pespin submitted this change.

View Change

Approvals: osmith: Looks good to me, approved Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve
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(-)

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);

To view, visit change 43424. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: merged
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I310c9b65625aef227100cbc37709dc63fc4e7f8a
Gerrit-Change-Number: 43424
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de>
Gerrit-Reviewer: laforge <laforge@osmocom.org>
Gerrit-Reviewer: osmith <osmith@sysmocom.de>
Gerrit-Reviewer: pespin <pespin@sysmocom.de>