<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/libosmo-sccp/+/16897">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">sccp: Avoid memleak of xua_msg receiving malformed sccp message<br><br>first, xua_msg is allocated internally in the function. Then depending<br>on msg type different functions are called. All of those functions<br>either return the same input xua msg pointer or NULL. If they return<br>NULL due to parsing failure, we need to free the internally allocated<br>xua pointer.<br><br>Change-Id: I4189fbd66e7e05ce466b3e716a357c56d788b64c<br>---<br>M src/sccp2sua.c<br>1 file changed, 49 insertions(+), 10 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/sccp2sua.c b/src/sccp2sua.c</span><br><span>index 7e6b3a3..1106888 100644</span><br><span>--- a/src/sccp2sua.c</span><br><span>+++ b/src/sccp2sua.c</span><br><span>@@ -998,6 +998,7 @@</span><br><span>       local_ref->octet3 = tmp32 & 0xff;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \returns \ref xua in case of success, NULL on error (xua not freed!) */</span><br><span> static struct xua_msg *sccp_to_xua_cr(struct msgb *msg, struct xua_msg *xua)</span><br><span> {</span><br><span>  struct sccp_connection_request *req = (struct sccp_connection_request *)msg->l2h;</span><br><span>@@ -1013,6 +1014,7 @@</span><br><span>         return sccp_to_xua_opt(msg, &req->optional_start, xua);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \returns \ref xua in case of success, NULL on error (xua not freed!) */</span><br><span> static int sua_to_sccp_cr(struct msgb *msg, struct xua_msg *xua)</span><br><span> {</span><br><span>        struct sccp_connection_request *req;</span><br><span>@@ -1029,6 +1031,7 @@</span><br><span>         return xua_ies_to_sccp_opts(msg, &req->optional_start, req->type, xua);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \returns \ref xua in case of success, NULL on error (xua not freed!) */</span><br><span> static struct xua_msg *sccp_to_xua_cc(struct msgb *msg, struct xua_msg *xua)</span><br><span> {</span><br><span>         struct sccp_connection_confirm *cnf = (struct sccp_connection_confirm *)msg->l2h;</span><br><span>@@ -1041,6 +1044,7 @@</span><br><span>         return sccp_to_xua_opt(msg, &cnf->optional_start, xua);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \returns \ref xua in case of success, NULL on error (xua not freed!) */</span><br><span> static int sua_to_sccp_cc(struct msgb *msg, struct xua_msg *xua)</span><br><span> {</span><br><span>        struct sccp_connection_confirm *cnf;</span><br><span>@@ -1055,6 +1059,7 @@</span><br><span>         return xua_ies_to_sccp_opts(msg, &cnf->optional_start, cnf->type, xua);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \returns \ref xua in case of success, NULL on error (xua not freed!) */</span><br><span> static struct xua_msg *sccp_to_xua_cref(struct msgb *msg, struct xua_msg *xua)</span><br><span> {</span><br><span>       struct sccp_connection_refused *ref = (struct sccp_connection_refused *)msg->l2h;</span><br><span>@@ -1066,6 +1071,7 @@</span><br><span>         return sccp_to_xua_opt(msg, &ref->optional_start, xua);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \returns \ref xua in case of success, NULL on error (xua not freed!) */</span><br><span> static int sua_to_sccp_cref(struct msgb *msg, struct xua_msg *xua)</span><br><span> {</span><br><span>      struct sccp_connection_refused *ref;</span><br><span>@@ -1079,6 +1085,7 @@</span><br><span>         return xua_ies_to_sccp_opts(msg, &ref->optional_start, ref->type, xua);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \returns \ref xua in case of success, NULL on error (xua not freed!) */</span><br><span> static struct xua_msg *sccp_to_xua_rlsd(struct msgb *msg, struct xua_msg *xua)</span><br><span> {</span><br><span>       struct sccp_connection_released *rlsd = (struct sccp_connection_released *)msg->l2h;</span><br><span>@@ -1106,6 +1113,7 @@</span><br><span>      return xua_ies_to_sccp_opts(msg, &rlsd->optional_start, rlsd->type, xua);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \returns \ref xua in case of success, NULL on error (xua not freed!) */</span><br><span> static struct xua_msg *sccp_to_xua_rlc(struct msgb *msg, struct xua_msg *xua)</span><br><span> {</span><br><span>      struct sccp_connection_release_complete *rlc;</span><br><span>@@ -1129,6 +1137,7 @@</span><br><span>        return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \returns \ref xua in case of success, NULL on error (xua not freed!) */</span><br><span> static struct xua_msg *sccp_to_xua_dt1(struct msgb *msg, struct xua_msg *xua)</span><br><span> {</span><br><span>        struct sccp_data_form1 *dt1 = (struct sccp_data_form1 *) msg->l2h;</span><br><span>@@ -1157,6 +1166,7 @@</span><br><span>        return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \returns \ref xua in case of success, NULL on error (xua not freed!) */</span><br><span> static struct xua_msg *sccp_to_xua_udt(struct msgb *msg, struct xua_msg *xua)</span><br><span> {</span><br><span>        struct sccp_data_unitdata *udt = (struct sccp_data_unitdata *)msg->l2h;</span><br><span>@@ -1192,6 +1202,7 @@</span><br><span>   return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \returns \ref xua in case of success, NULL on error (xua not freed!) */</span><br><span> static struct xua_msg *sccp_to_xua_udts(struct msgb *msg, struct xua_msg *xua)</span><br><span> {</span><br><span>       struct sccp_data_unitdata_service *udts;</span><br><span>@@ -1228,6 +1239,7 @@</span><br><span>     return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \returns \ref xua in case of success, NULL on error (xua not freed!) */</span><br><span> static struct xua_msg *sccp_to_xua_it(struct msgb *msg, struct xua_msg *xua)</span><br><span> {</span><br><span>         struct sccp_data_it *it = (struct sccp_data_it *)msg->l2h;</span><br><span>@@ -1261,6 +1273,7 @@</span><br><span>        return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \returns \ref xua in case of success, NULL on error (xua not freed!) */</span><br><span> static struct xua_msg *sccp_to_xua_err(struct msgb *msg, struct xua_msg *xua)</span><br><span> {</span><br><span>        struct sccp_proto_err *err = (struct sccp_proto_err *)msg->l2h;</span><br><span>@@ -1302,34 +1315,54 @@</span><br><span>         switch (msg->l2h[0]) {</span><br><span>    case SCCP_MSG_TYPE_CR:</span><br><span>               xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE);</span><br><span style="color: hsl(0, 100%, 40%);">-                return sccp_to_xua_cr(msg, xua);</span><br><span style="color: hsl(120, 100%, 40%);">+              if (!sccp_to_xua_cr(msg, xua))</span><br><span style="color: hsl(120, 100%, 40%);">+                        goto malformed;</span><br><span style="color: hsl(120, 100%, 40%);">+               return xua;</span><br><span>  case SCCP_MSG_TYPE_CC:</span><br><span>               xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK);</span><br><span style="color: hsl(0, 100%, 40%);">-                return sccp_to_xua_cc(msg, xua);</span><br><span style="color: hsl(120, 100%, 40%);">+              if (!sccp_to_xua_cc(msg, xua))</span><br><span style="color: hsl(120, 100%, 40%);">+                        goto malformed;</span><br><span style="color: hsl(120, 100%, 40%);">+               return xua;</span><br><span>  case SCCP_MSG_TYPE_CREF:</span><br><span>             xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COREF);</span><br><span style="color: hsl(0, 100%, 40%);">-               return sccp_to_xua_cref(msg, xua);</span><br><span style="color: hsl(120, 100%, 40%);">+            if (!sccp_to_xua_cref(msg, xua))</span><br><span style="color: hsl(120, 100%, 40%);">+                      goto malformed;</span><br><span style="color: hsl(120, 100%, 40%);">+               return xua;</span><br><span>  case SCCP_MSG_TYPE_RLSD:</span><br><span>             xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE);</span><br><span style="color: hsl(0, 100%, 40%);">-               return sccp_to_xua_rlsd(msg, xua);</span><br><span style="color: hsl(120, 100%, 40%);">+            if (!sccp_to_xua_rlsd(msg, xua))</span><br><span style="color: hsl(120, 100%, 40%);">+                      goto malformed;</span><br><span style="color: hsl(120, 100%, 40%);">+               return xua;</span><br><span>  case SCCP_MSG_TYPE_RLC:</span><br><span>              xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELCO);</span><br><span style="color: hsl(0, 100%, 40%);">-               return sccp_to_xua_rlc(msg, xua);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (!sccp_to_xua_rlc(msg, xua))</span><br><span style="color: hsl(120, 100%, 40%);">+                       goto malformed;</span><br><span style="color: hsl(120, 100%, 40%);">+               return xua;</span><br><span>  case SCCP_MSG_TYPE_DT1:</span><br><span>              xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT);</span><br><span style="color: hsl(0, 100%, 40%);">-                return sccp_to_xua_dt1(msg, xua);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (!sccp_to_xua_dt1(msg, xua))</span><br><span style="color: hsl(120, 100%, 40%);">+                       goto malformed;</span><br><span style="color: hsl(120, 100%, 40%);">+               return xua;</span><br><span>  case SCCP_MSG_TYPE_UDT:</span><br><span>              xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT);</span><br><span style="color: hsl(0, 100%, 40%);">-                return sccp_to_xua_udt(msg, xua);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (!sccp_to_xua_udt(msg, xua))</span><br><span style="color: hsl(120, 100%, 40%);">+                       goto malformed;</span><br><span style="color: hsl(120, 100%, 40%);">+               return xua;</span><br><span>  case SCCP_MSG_TYPE_UDTS:</span><br><span>             xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDR);</span><br><span style="color: hsl(0, 100%, 40%);">-                return sccp_to_xua_udts(msg, xua);</span><br><span style="color: hsl(120, 100%, 40%);">+            if (!sccp_to_xua_udts(msg, xua))</span><br><span style="color: hsl(120, 100%, 40%);">+                      goto malformed;</span><br><span style="color: hsl(120, 100%, 40%);">+               return xua;</span><br><span>  case SCCP_MSG_TYPE_IT:</span><br><span>               xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COIT);</span><br><span style="color: hsl(0, 100%, 40%);">-                return sccp_to_xua_it(msg, xua);</span><br><span style="color: hsl(120, 100%, 40%);">+              if (!sccp_to_xua_it(msg, xua))</span><br><span style="color: hsl(120, 100%, 40%);">+                        goto malformed;</span><br><span style="color: hsl(120, 100%, 40%);">+               return xua;</span><br><span>  case SCCP_MSG_TYPE_ERR:</span><br><span>              xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COERR);</span><br><span style="color: hsl(0, 100%, 40%);">-               return sccp_to_xua_err(msg, xua);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (!sccp_to_xua_err(msg, xua))</span><br><span style="color: hsl(120, 100%, 40%);">+                       goto malformed;</span><br><span style="color: hsl(120, 100%, 40%);">+               return xua;</span><br><span>  /* Unsupported Message Types */</span><br><span>      case SCCP_MSG_TYPE_DT2:</span><br><span>      case SCCP_MSG_TYPE_AK:</span><br><span>@@ -1353,6 +1386,12 @@</span><br><span>      }</span><br><span> </span><br><span>        return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+malformed:</span><br><span style="color: hsl(120, 100%, 40%);">+    LOGP(DLSUA, LOGL_ERROR, "Malformed SCCP message %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+           osmo_sccp_msg_type_name(msg->l2h[0]));</span><br><span style="color: hsl(120, 100%, 40%);">+        xua_msg_free(xua);</span><br><span style="color: hsl(120, 100%, 40%);">+    return NULL;</span><br><span> }</span><br><span> </span><br><span> /*! \brief convert parsed SUA message to SCCP message</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmo-sccp/+/16897">change 16897</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/libosmo-sccp/+/16897"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmo-sccp </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I4189fbd66e7e05ce466b3e716a357c56d788b64c </div>
<div style="display:none"> Gerrit-Change-Number: 16897 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>