diff options
author | Daniel Willmann <daniel@totalueberwachung.de> | 2012-12-25 23:15:50 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2012-12-26 10:48:01 +0100 |
commit | e523392c2c091f53c18edf2086d6966eec38561f (patch) | |
tree | c74facf8897c5513adfa95e710d8388cfe170bad /tests/lapd/lapd_test.c | |
parent | 0167596c2bf19102eac8a69f5066eedbae72a167 (diff) |
lapd: Check in rslms_rx_rll() if lapdm context was initialized earlier
This was found while implementing handover on a sysmobts. When we
receive a channel release request for a channel that was never really
activated (set_lapdm_context() was not called) we segfault in
lapd_recv_dlsap().
We now return early with -EINVAL in rslms_rx_rll() if we receive a
message that assumes set_lapdm_context() was already called.
These are:
* RSL_MT_UNIT_DATA_REQ
* RSL_MT_DATA_REQ
* RSL_MT_SUSP_REQ
* RSL_MT_REL_REQ
A test case was added to trigger the issue.
Diffstat (limited to 'tests/lapd/lapd_test.c')
-rw-r--r-- | tests/lapd/lapd_test.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/tests/lapd/lapd_test.c b/tests/lapd/lapd_test.c index d58bec65..2dabbc6d 100644 --- a/tests/lapd/lapd_test.c +++ b/tests/lapd/lapd_test.c @@ -81,6 +81,10 @@ static const uint8_t dummy1[] = { 0xab, 0x03, 0x30, 0x60, 0x06, }; +static const uint8_t rel_req[] = { + 0x02, 0x07, 0x01, 0x0a, 0x02, 0x40, 0x14, 0x01 +}; + static struct msgb *create_cm_serv_req(void) { struct msgb *msg; @@ -122,6 +126,16 @@ static struct msgb *create_dummy_data_req(void) return msg; } +static struct msgb *create_rel_req(void) +{ + struct msgb *msg; + + msg = msgb_from_array(rel_req, sizeof(rel_req)); + msg->l2h = msg->data; + msg->l3h = msg->l2h + sizeof(struct abis_rsl_rll_hdr); + return msg; +} + static int send(struct msgb *in_msg, struct lapdm_channel *chan) { struct osmo_phsap_prim pp; @@ -308,11 +322,40 @@ static void test_lapdm_polling() lapdm_channel_exit(&ms_to_bts_channel); } +static void test_lapdm_early_release() +{ + printf("I test RF channel release of an unestablished channel.\n"); + + int rc; + struct lapdm_polling_state test_state; + + /* Configure LAPDm on both sides */ + struct lapdm_channel bts_to_ms_channel; + memset(&bts_to_ms_channel, 0, sizeof(bts_to_ms_channel)); + + memset(&test_state, 0, sizeof(test_state)); + test_state.bts = &bts_to_ms_channel; + + /* BTS to MS in polling mode */ + lapdm_channel_init(&bts_to_ms_channel, LAPDM_MODE_BTS); + lapdm_channel_set_flags(&bts_to_ms_channel, LAPDM_ENT_F_POLLING_ONLY); + lapdm_channel_set_l1(&bts_to_ms_channel, NULL, &test_state); + lapdm_channel_set_l3(&bts_to_ms_channel, bts_to_ms_tx_cb, &test_state); + + /* Send the release request */ + rc = lapdm_rslms_recvmsg(create_rel_req(), &bts_to_ms_channel); + ASSERT(rc == -EINVAL); + + /* clean up */ + lapdm_channel_exit(&bts_to_ms_channel); +} + int main(int argc, char **argv) { osmo_init_logging(&info); test_lapdm_polling(); + test_lapdm_early_release(); printf("Success.\n"); return 0; |