aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlexander Couzens <lynxis@fe80.eu>2021-03-24 17:44:03 +0100
committerlaforge <laforge@osmocom.org>2021-03-29 21:26:46 +0000
commit7619ed43043bb7a88ae9e3a1c09e4deacf5f429c (patch)
treeba9503000c1376deb4b8f5bc8281c5ec0d08a36c /src
parentc2fbbd7307e9abf4e6c52051c306917299f1eb85 (diff)
gprs_ns2: fix memory leaks when receiving SNS or invalid packets
Diffstat (limited to 'src')
-rw-r--r--src/gb/gprs_ns2.c32
-rw-r--r--src/gb/gprs_ns2_sns.c11
-rw-r--r--src/gb/gprs_ns2_vc_fsm.c3
3 files changed, 25 insertions, 21 deletions
diff --git a/src/gb/gprs_ns2.c b/src/gb/gprs_ns2.c
index 507a5acd..1148d6f5 100644
--- a/src/gb/gprs_ns2.c
+++ b/src/gb/gprs_ns2.c
@@ -1243,7 +1243,7 @@ int gprs_ns2_nse_foreach_nsvc(struct gprs_ns2_nse *nse, gprs_ns2_foreach_nsvc_cb
/*! Bottom-side entry-point for received NS PDU from the driver/bind
* \param[in] nsvc NS-VC for which the message was received
- * \param msg the received message. Ownership is trasnferred, caller must not free it!
+ * \param msg the received message. Ownership is transferred, caller must not free it!
* \return 0 on success; negative on error */
int ns2_recv_vc(struct gprs_ns2_vc *nsvc,
struct msgb *msg)
@@ -1258,8 +1258,10 @@ int ns2_recv_vc(struct gprs_ns2_vc *nsvc,
rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_PKTS_IN]);
rate_ctr_add(&nsvc->ctrg->ctr[NS_CTR_BYTES_IN], msg->len);
- if (msg->len < sizeof(struct gprs_ns_hdr))
- return -EINVAL;
+ if (msg->len < sizeof(struct gprs_ns_hdr)) {
+ rc = -EINVAL;
+ goto freemsg;
+ }
if (nsh->pdu_type != NS_PDUT_UNITDATA)
LOG_NS_RX_SIGNAL(nsvc, nsh->pdu_type);
@@ -1273,11 +1275,10 @@ int ns2_recv_vc(struct gprs_ns2_vc *nsvc,
msgb_l2len(msg) - sizeof(*nsh)-1, 0, 0);
if (rc < 0) {
LOGP(DLNS, LOGL_NOTICE, "Error during TLV Parse in %s\n", msgb_hexdump(msg));
- return rc;
+ goto freemsg;
}
/* All sub-network service related message types */
- rc = ns2_sns_rx(nsvc, msg, &tp);
- break;
+ return ns2_sns_rx(nsvc, msg, &tp);
case SNS_PDUT_ACK:
case SNS_PDUT_ADD:
case SNS_PDUT_CHANGE_WEIGHT:
@@ -1287,14 +1288,13 @@ int ns2_recv_vc(struct gprs_ns2_vc *nsvc,
msgb_l2len(msg) - sizeof(*nsh)-5, 0, 0);
if (rc < 0) {
LOGP(DLNS, LOGL_NOTICE, "Error during TLV Parse in %s\n", msgb_hexdump(msg));
- return rc;
+ goto freemsg;
}
tp.lv[NS_IE_NSEI].val = nsh->data+2;
tp.lv[NS_IE_NSEI].len = 2;
tp.lv[NS_IE_TRANS_ID].val = nsh->data+4;
tp.lv[NS_IE_TRANS_ID].len = 1;
- rc = ns2_sns_rx(nsvc, msg, &tp);
- break;
+ return ns2_sns_rx(nsvc, msg, &tp);
case SNS_PDUT_CONFIG_ACK:
case SNS_PDUT_SIZE:
case SNS_PDUT_SIZE_ACK:
@@ -1302,15 +1302,12 @@ int ns2_recv_vc(struct gprs_ns2_vc *nsvc,
msgb_l2len(msg) - sizeof(*nsh), 0, 0);
if (rc < 0) {
LOGP(DLNS, LOGL_NOTICE, "Error during TLV Parse in %s\n", msgb_hexdump(msg));
- return rc;
+ goto freemsg;
}
/* All sub-network service related message types */
- rc = ns2_sns_rx(nsvc, msg, &tp);
- break;
-
+ return ns2_sns_rx(nsvc, msg, &tp);
case NS_PDUT_UNITDATA:
- rc = ns2_vc_rx(nsvc, msg, &tp);
- break;
+ return ns2_vc_rx(nsvc, msg, &tp);
default:
rc = ns2_tlv_parse(&tp, nsh->data,
msgb_l2len(msg) - sizeof(*nsh), 0, 0);
@@ -1320,9 +1317,10 @@ int ns2_recv_vc(struct gprs_ns2_vc *nsvc,
ns2_tx_status(nsvc, NS_CAUSE_PROTO_ERR_UNSPEC, 0, msg);
return rc;
}
- rc = ns2_vc_rx(nsvc, msg, &tp);
- break;
+ return ns2_vc_rx(nsvc, msg, &tp);
}
+freemsg:
+ msgb_free(msg);
return rc;
}
diff --git a/src/gb/gprs_ns2_sns.c b/src/gb/gprs_ns2_sns.c
index 144ab21b..b8c44f1f 100644
--- a/src/gb/gprs_ns2_sns.c
+++ b/src/gb/gprs_ns2_sns.c
@@ -1614,11 +1614,13 @@ int ns2_sns_rx(struct gprs_ns2_vc *nsvc, struct msgb *msg, struct tlv_parsed *tp
uint16_t nsei = nsvc->nse->nsei;
struct ns2_sns_state *gss;
struct osmo_fsm_inst *fi;
+ int rc = 0;
if (!nse->bss_sns_fi) {
LOGNSVC(nsvc, LOGL_NOTICE, "Rx %s for NS Instance that has no SNS!\n",
get_value_string(gprs_ns_pdu_strings, nsh->pdu_type));
- return -EINVAL;
+ rc = -EINVAL;
+ goto out;
}
/* FIXME: how to resolve SNS FSM Instance by NSEI (SGSN)? */
@@ -1661,10 +1663,13 @@ int ns2_sns_rx(struct gprs_ns2_vc *nsvc, struct msgb *msg, struct tlv_parsed *tp
default:
LOGPFSML(fi, LOGL_ERROR, "NSEI=%u Rx unknown SNS PDU type %s\n", nsei,
get_value_string(gprs_ns_pdu_strings, nsh->pdu_type));
- return -EINVAL;
+ rc = -EINVAL;
}
- return 0;
+out:
+ msgb_free(msg);
+
+ return rc;
}
#include <osmocom/vty/vty.h>
diff --git a/src/gb/gprs_ns2_vc_fsm.c b/src/gb/gprs_ns2_vc_fsm.c
index ad8d4dbf..a8cb570c 100644
--- a/src/gb/gprs_ns2_vc_fsm.c
+++ b/src/gb/gprs_ns2_vc_fsm.c
@@ -883,7 +883,8 @@ int ns2_vc_rx(struct gprs_ns2_vc *nsvc, struct msgb *msg, struct tlv_parsed *tp)
default:
LOGPFSML(fi, LOGL_ERROR, "NSEI=%u Rx unknown NS PDU type %s\n", nsvc->nse->nsei,
get_value_string(gprs_ns_pdu_strings, nsh->pdu_type));
- return -EINVAL;
+ rc = -EINVAL;
+ break;
}
out: