falconia has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bts/+/38555?usp=email )
Change subject: CSD RTP: verify alignment of V.110 frames ......................................................................
CSD RTP: verify alignment of V.110 frames
Since the beginning of CSD implementation, OsmoBTS has operated with an implicit (unstated) policy that V.110 frames must be perfectly aligned within received clearmode RTP packets - a requirement which is NOT set anywhere in TS 48.103 or any of the other specs it references. This design policy is sensible from the standpoint of implementation complexity (both OsmoBTS and osmo_trau2rtp emit such perfectly aligned packets; if someone is building a gateway between an Osmocom GSM network and ISDN-style external networks, that gateway can act as the aligner), but it should be explicit rather than implicit.
Check V.110 frame alignment in received clearmode RTP packets, and reject packets that fail this alignment check.
Change-Id: Icd704dc7fa02e60074efc8a29ad7e42ebdf63783 --- M src/common/csd_v110.c 1 file changed, 21 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/55/38555/1
diff --git a/src/common/csd_v110.c b/src/common/csd_v110.c index cbbb83b..edd051e 100644 --- a/src/common/csd_v110.c +++ b/src/common/csd_v110.c @@ -20,6 +20,7 @@ */
#include <stdint.h> +#include <stdbool.h> #include <errno.h>
#include <osmocom/core/bits.h> @@ -150,6 +151,21 @@ return RFC4040_RTP_PLEN; }
+static bool check_v110_align(const ubit_t *ra_bits) +{ + int i; + + for (i = 0; i < 8; i++) { + if (ra_bits[i]) + return false; + } + for (i = 1; i < 10; i++) { + if (!ra_bits[i * 8]) + return false; + } + return true; +} + int csd_v110_rtp_decode(const struct gsm_lchan *lchan, uint8_t *data, const uint8_t *rtp, size_t rtp_len) { @@ -181,6 +197,11 @@ for (unsigned int i = 0; i < desc->num_blocks; i++) { struct osmo_v110_decoded_frame df;
+ /* We require our RTP input to consist of aligned V.110 + * frames. If we get misaligned input, let's catch it + * explicitly, rather than send garbage downstream. */ + if (!check_v110_align(&ra_bits[i * 80])) + return -EINVAL; /* convert a V.110 80-bit frame to a V.110 36-/60-bit frame */ osmo_v110_decode_frame(&df, &ra_bits[i * 80], 80); if (desc->num_bits == 60)