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
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 @@
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 @@
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 @@
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;