aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-10-10 17:24:34 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-10-10 17:55:13 +0200
commit10dd73cf6afdc0ba237022510ec702a56237d7d7 (patch)
tree2b68fd53fe224eac83c91a50c0a4385bac49659c
parentdade018f2fa577de2020c4bfaa9bfde770ae3b30 (diff)
bssgp: Free msgb in case of error when calling into gprs_ns_sendmsg
In the OsmoSGSN we have a crash with a DEAD/BLOCKED GPRS-NS and segmented SN-UNITDATA. For the caller it is not easy to know if the passed msg buffer has been freed or not. The most easy solution is to always take the ownership and either pass it on or free it in case of an error. Adjust indirect and direct callers of gprs_ns_sendmsg. I found the following call-chains with an external msgb parameter. gprs_ns_sendmsg <- _bssgp_tx_dl_ud <- bssgp_fc_in <- bssgp_tx_dl_ud Update the test to allocate a real msgb because for the test with '1000' we will msgb_free it right away. Sponsored-by: On-Waves ehf
-rw-r--r--src/gb/gprs_bssgp.c3
-rw-r--r--tests/gb/bssgp_fc_test.c12
2 files changed, 11 insertions, 4 deletions
diff --git a/src/gb/gprs_bssgp.c b/src/gb/gprs_bssgp.c
index 0e9fd388..7a5d6285 100644
--- a/src/gb/gprs_bssgp.c
+++ b/src/gb/gprs_bssgp.c
@@ -696,6 +696,7 @@ int bssgp_fc_in(struct bssgp_flow_control *fc, struct msgb *msg,
LOGP(DBSSGP, LOGL_NOTICE, "Single PDU (size=%u) is larger "
"than maximum bucket size (%u)!\n", llc_pdu_len,
fc->bucket_size_max);
+ msgb_free(msg);
return -EIO;
}
@@ -1039,6 +1040,7 @@ int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
if (bvci <= BVCI_PTM ) {
LOGP(DBSSGP, LOGL_ERROR, "Cannot send DL-UD to BVCI %u\n",
bvci);
+ msgb_free(msg);
return -EINVAL;
}
@@ -1046,6 +1048,7 @@ int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
if (!bctx) {
LOGP(DBSSGP, LOGL_ERROR, "Cannot send DL-UD to unknown BVCI %u\n",
bvci);
+ msgb_free(msg);
return -ENODEV;
}
diff --git a/tests/gb/bssgp_fc_test.c b/tests/gb/bssgp_fc_test.c
index 64e4b4eb..ad8f83d6 100644
--- a/tests/gb/bssgp_fc_test.c
+++ b/tests/gb/bssgp_fc_test.c
@@ -43,18 +43,22 @@ static int fc_out_cb(struct bssgp_flow_control *fc, struct msgb *msg,
unsigned int csecs = get_centisec_diff();
csecs = round_decisec(csecs);
- printf("%u: FC OUT Nr %lu\n", csecs, (unsigned long) msg);
+ printf("%u: FC OUT Nr %lu\n", csecs, (unsigned long) msg->cb[0]);
+ msgb_free(msg);
return 0;
}
static int fc_in(struct bssgp_flow_control *fc, unsigned int pdu_len)
{
+ struct msgb *msg;
unsigned int csecs = get_centisec_diff();
csecs = round_decisec(csecs);
- printf("%u: FC IN Nr %lu\n", csecs, in_ctr);
- bssgp_fc_in(fc, (struct msgb *) in_ctr, pdu_len, NULL);
- in_ctr++;
+ msg = msgb_alloc(1, "fc test");
+ msg->cb[0] = in_ctr++;
+
+ printf("%u: FC IN Nr %lu\n", csecs, msg->cb[0]);
+ bssgp_fc_in(fc, msg, pdu_len, NULL);
return 0;
}