diff options
author | Harald Welte <laforge@osmocom.org> | 2020-07-04 11:18:26 +0200 |
---|---|---|
committer | Harald Welte <laforge@osmocom.org> | 2020-07-04 11:21:23 +0200 |
commit | bcfd7ea1846bf1c95dff37515773621a8fb13bd7 (patch) | |
tree | d418289108bf83008687e8597f035b6d182af8a7 /src/subchan_demux.c | |
parent | 96034fcced3f5a93af1a7859a5cc7062390143a0 (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.c | 48 |
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; |