aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Chemeris <Alexander.Chemeris@gmail.com>2015-06-14 23:52:27 -0400
committerAlexander Chemeris <Alexander.Chemeris@gmail.com>2015-07-20 18:44:00 -0400
commit3dc5c93e22786c4e448a243678c435bd6726d9d4 (patch)
tree73b43f3a9659b319471e75f63af3c42725e3d911
parent3b3e16c4e4edac3ffc572ba8b754609e6a67c93f (diff)
l1sap: Fix use-after-free in loopback mode.
-rw-r--r--src/common/l1sap.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/src/common/l1sap.c b/src/common/l1sap.c
index 8b79ffee..bfac1e93 100644
--- a/src/common/l1sap.c
+++ b/src/common/l1sap.c
@@ -800,16 +800,24 @@ static int l1sap_tch_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap,
struct msgb *tmp;
int count = 0;
- /* make sure the queue doesn't get too long */
+ /* make sure the queue doesn't get too long */
llist_for_each_entry(tmp, &lchan->dl_tch_queue, list)
- count++;
+ count++;
while (count >= 1) {
tmp = msgb_dequeue(&lchan->dl_tch_queue);
msgb_free(tmp);
count--;
}
- msgb_enqueue(&lchan->dl_tch_queue, msg);
+ /* copy msg to a new msgb before enquing it, because msg
+ * will be freed on the exit from the function. */
+ tmp = l1sap_msgb_alloc(msg->len);
+ if (!tmp)
+ return 0;
+ memcpy(msgb_put(tmp, msg->len), msg->data, msg->len);
+ msgb_pull(tmp, sizeof(*l1sap));
+
+ msgb_enqueue(&lchan->dl_tch_queue, tmp);
}
return 0;