aboutsummaryrefslogtreecommitdiffstats
path: root/src/subchan_demux.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@osmocom.org>2020-07-04 11:18:26 +0200
committerHarald Welte <laforge@osmocom.org>2020-07-04 11:21:23 +0200
commitbcfd7ea1846bf1c95dff37515773621a8fb13bd7 (patch)
treed418289108bf83008687e8597f035b6d182af8a7 /src/subchan_demux.c
parent96034fcced3f5a93af1a7859a5cc7062390143a0 (diff)
subchan_demux: Fix out-of-bounds write
We cannot blindly append two ubits to the 320-ubit sized buffer. In the end, we may already fill the buffer after the first ubit, causing a buffer overflow with the second ubit. Lets check if the buffer is full after every bit. Avoid copy+pasting but move the code repeated per bit to a new function. Change-Id: I58d946265372278051e4f29301d4f201ab98c0fc Closes: OS#4648
Diffstat (limited to 'src/subchan_demux.c')
-rw-r--r--src/subchan_demux.c48
1 files changed, 25 insertions, 23 deletions
diff --git a/src/subchan_demux.c b/src/subchan_demux.c
index 55503db..a3a44d9 100644
--- a/src/subchan_demux.c
+++ b/src/subchan_demux.c
@@ -92,6 +92,29 @@ int subch_demux_init(struct subch_demux *dmx)
return 0;
}
+static void append_bit_resync_out(struct subch_demux *dmx, int c, ubit_t bit)
+{
+ struct demux_subch *sch = &dmx->subch[c];
+ append_bit(sch, bit);
+
+ if (sync_hdr_complete(sch, bit))
+ resync_to_here(sch);
+
+ /* FIXME: verify the first bit in octet 2, 4, 6, ...
+ * according to TS 08.60 4.8.1 */
+
+ /* once we have reached TRAU_FRAME_BITS, call
+ * the TRAU frame handler callback function */
+ if (sch->out_idx >= TRAU_FRAME_BITS) {
+ if (sch->in_sync) {
+ dmx->out_cb(dmx, c, sch->out_bitbuf,
+ sch->out_idx, dmx->data);
+ sch->in_sync = 0;
+ }
+ sch->out_idx = 0;
+ }
+}
+
/*! \brief Input some data from the 64k full-slot into subchannel demux
* \param[in] dmx subchannel demuxer
* \param[in] data pointer to buffer containing input data
@@ -108,7 +131,6 @@ int subch_demux_in(struct subch_demux *dmx, uint8_t *data, int len)
uint8_t inbyte = data[i];
for (c = 0; c < NR_SUBCH; c++) {
- struct demux_subch *sch = &dmx->subch[c];
uint8_t inbits;
uint8_t bit;
@@ -123,33 +145,13 @@ int subch_demux_in(struct subch_demux *dmx, uint8_t *data, int len)
bit = 1;
else
bit = 0;
- append_bit(sch, bit);
-
- if (sync_hdr_complete(sch, bit))
- resync_to_here(sch);
+ append_bit_resync_out(dmx, c, bit);
if (inbits & 0x02)
bit = 1;
else
bit = 0;
- append_bit(sch, bit);
-
- if (sync_hdr_complete(sch, bit))
- resync_to_here(sch);
-
- /* FIXME: verify the first bit in octet 2, 4, 6, ...
- * according to TS 08.60 4.8.1 */
-
- /* once we have reached TRAU_FRAME_BITS, call
- * the TRAU frame handler callback function */
- if (sch->out_idx >= TRAU_FRAME_BITS) {
- if (sch->in_sync) {
- dmx->out_cb(dmx, c, sch->out_bitbuf,
- sch->out_idx, dmx->data);
- sch->in_sync = 0;
- }
- sch->out_idx = 0;
- }
+ append_bit_resync_out(dmx, c, bit);
}
}
return i;