diff options
author | Harald Welte <laforge@gnumonks.org> | 2018-02-21 16:21:51 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2018-02-21 16:49:28 +0100 |
commit | 4847a1688ba6fee8e5b44c25317c2e221b4b0ae0 (patch) | |
tree | 03d245ff84617378f47f239602294564a3609737 /src/common/rsl.c | |
parent | 5e60186bec02e558a1f08bac1683c73a8f70b6c8 (diff) |
RSL: Ensure we don't accept DCHAN messages for CCHAN
If the Channel Number IE points to a common channel, we cannot
accept such messages in code paths that only process dedicated
channels, such as RLL/DCHAN/IPA.
Related: OS#2972, OS#2971
Change-Id: I43a78bec63aeb36dd67043d237b27fe880209349
Diffstat (limited to 'src/common/rsl.c')
-rw-r--r-- | src/common/rsl.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/common/rsl.c b/src/common/rsl.c index 877f5d82..001d7e07 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -135,6 +135,16 @@ static void lchan_tchmode_from_cmode(struct gsm_lchan *lchan, * support */ +/* Is this channel number for a dedicated channel (true) or not (false) */ +static bool chan_nr_is_dchan(uint8_t chan_nr) +{ + /* See TS 48.058 9.3.1 */ + if (chan_nr & 0x80) + return false; + else + return true; +} + static struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr, const char *log_name) { @@ -2254,6 +2264,9 @@ static int rsl_rx_rll(struct gsm_bts_trx *trx, struct msgb *msg) } msg->l3h = (unsigned char *)rh + sizeof(*rh); + if (!chan_nr_is_dchan(rh->chan_nr)) + return rsl_reject_unknown_lchan(msg); + lchan = lchan_lookup(trx, rh->chan_nr, "RSL rx RLL: "); if (!lchan) { LOGP(DRLL, LOGL_NOTICE, "Rx RLL %s for unknown lchan\n", @@ -2445,6 +2458,9 @@ static int rsl_rx_cchan(struct gsm_bts_trx *trx, struct msgb *msg) } msg->l3h = (unsigned char *)cch + sizeof(*cch); + if (chan_nr_is_dchan(cch->chan_nr)) + return rsl_reject_unknown_lchan(msg); + msg->lchan = lchan_lookup(trx, cch->chan_nr, "RSL rx CCHAN: "); if (!msg->lchan) { LOGP(DRSL, LOGL_ERROR, "Rx RSL %s for unknown lchan\n", @@ -2498,6 +2514,9 @@ static int rsl_rx_dchan(struct gsm_bts_trx *trx, struct msgb *msg) } msg->l3h = (unsigned char *)dch + sizeof(*dch); + if (!chan_nr_is_dchan(dch->chan_nr)) + return rsl_reject_unknown_lchan(msg); + msg->lchan = lchan_lookup(trx, dch->chan_nr, "RSL rx DCHAN: "); if (!msg->lchan) { LOGP(DRSL, LOGL_ERROR, "Rx RSL %s for unknown lchan\n", @@ -2596,6 +2615,9 @@ static int rsl_rx_ipaccess(struct gsm_bts_trx *trx, struct msgb *msg) } msg->l3h = (unsigned char *)dch + sizeof(*dch); + if (!chan_nr_is_dchan(dch->chan_nr)) + return rsl_reject_unknown_lchan(msg); + msg->lchan = lchan_lookup(trx, dch->chan_nr, "RSL rx IPACC: "); if (!msg->lchan) { LOGP(DRSL, LOGL_ERROR, "Rx RSL %s for unknow lchan\n", |