summaryrefslogtreecommitdiffstats
path: root/src/host/trxcon/sched_lchan_tchf.c
diff options
context:
space:
mode:
authorVadim Yanitskiy <axilirator@gmail.com>2018-07-24 22:24:13 +0700
committerVadim Yanitskiy <axilirator@gmail.com>2018-07-24 22:24:13 +0700
commit8f6909a94f14be583e57044d13a45ded5eaf3d2c (patch)
tree84e3dfc3a21c6e566b307bef7b64e87d48c09a7a /src/host/trxcon/sched_lchan_tchf.c
parent812866daab20dbb9242d7b3a7f417f6d0e1d8a0e (diff)
trxcon/scheduler: fix: check primitive len before encoding
We used to trust (and still doing this) the messages coming from L1CTL interface too much, and not to check the primitive length before passing the payload to the libosmocoding API. As was discovered and described in OS#3415, sending a L1CTL message (either DATA_REQ, or TRAFFIC_REQ) with an incorrect length (lower than expected) may cause heap overflow. Let's explicitly check a primitive before encoding, and drop it if its length doesn't match the expected value(s). Change-Id: I258ee9f6d0124b183b1db23a73f1e523fcea89a8 Fixes: OS#3415
Diffstat (limited to 'src/host/trxcon/sched_lchan_tchf.c')
-rw-r--r--src/host/trxcon/sched_lchan_tchf.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/src/host/trxcon/sched_lchan_tchf.c b/src/host/trxcon/sched_lchan_tchf.c
index 80e4d52f..e20b461f 100644
--- a/src/host/trxcon/sched_lchan_tchf.c
+++ b/src/host/trxcon/sched_lchan_tchf.c
@@ -232,9 +232,17 @@ int tx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts,
return -EINVAL;
}
- /* Determine payload length */
- if (lchan->prim->payload_len == GSM_MACBLOCK_LEN)
- l2_len = GSM_MACBLOCK_LEN;
+ /* Determine and check the payload length */
+ if (lchan->prim->payload_len == GSM_MACBLOCK_LEN) {
+ l2_len = GSM_MACBLOCK_LEN; /* FACCH */
+ } else if (lchan->prim->payload_len != l2_len) {
+ LOGP(DSCHD, LOGL_ERROR, "Primitive has odd length %zu "
+ "(expected %zu for TCH or %u for FACCH), so dropping...\n",
+ lchan->prim->payload_len, l2_len, GSM_MACBLOCK_LEN);
+
+ sched_prim_drop(lchan);
+ return -EINVAL;
+ }
/* Shift buffer by 4 bursts back for interleaving */
memcpy(buffer, buffer + 464, 464);