From fe9213313219e506d4c0ed538b0b03cd85814b08 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 2 Oct 2014 22:24:47 +0200 Subject: sgsn: Add test that exposes a dangling pointer to the LLME On detach the LLME get's unassigned (and hence destroyed) but the GMM context will still point to that dead structure. --- openbsc/tests/sgsn/sgsn_test.c | 60 +++++++++++++++++++++++++++++++++++++++++ openbsc/tests/sgsn/sgsn_test.ok | 1 + 2 files changed, 61 insertions(+) (limited to 'openbsc/tests') diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c index 6224fd5e1..30ed1d94a 100644 --- a/openbsc/tests/sgsn/sgsn_test.c +++ b/openbsc/tests/sgsn/sgsn_test.c @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -53,6 +54,18 @@ static int count(struct llist_head *head) return count; } +static struct msgb *create_msg(const uint8_t *data, size_t len) +{ + struct msgb *msg = msgb_alloc(len + 8, "test message"); + msg->l1h = msgb_put(msg, 8); + msg->l2h = msgb_put(msg, len); + memcpy(msg->l2h, data, len); + + msgb_bcid(msg) = msg->l1h; + msgb_gmmh(msg) = msg->l2h; + return msg; +} + static void test_llme(void) { struct gprs_llc_lle *lle, *lle_copy; @@ -86,6 +99,52 @@ static void test_llme(void) OSMO_ASSERT(count(gprs_llme_list()) == 0); } +/* + * Test that a GMM Detach will remove the MMCTX and the + * associated LLME. + */ +static void test_gmm_detach(void) +{ + struct gprs_ra_id raid = { 0, }; + struct sgsn_mm_ctx *ctx, *ictx; + struct gprs_llc_lle *lle; + uint32_t local_tlli; + struct msgb *msg; + + printf("Testing GMM detach\n"); + + /* DTAP - Detach Request (MO) */ + /* normal detach, power_off = 0 */ + static const unsigned char detach_req[] = { + 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2, + 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb + }; + + /* Create a conext and search for it */ + OSMO_ASSERT(count(gprs_llme_list()) == 0); + local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL); + lle = gprs_lle_get_or_create(local_tlli, 3); + ctx = sgsn_mm_ctx_alloc(local_tlli, &raid); + ctx->mm_state = GMM_REGISTERED_NORMAL; + ctx->llme = lle->llme; + + ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid); + OSMO_ASSERT(ictx == ctx); + OSMO_ASSERT(count(gprs_llme_list()) == 1); + + /* inject the detach */ + msg = create_msg(detach_req, ARRAY_SIZE(detach_req)); + msgb_tlli(msg) = local_tlli; + gsm0408_gprs_rcvmsg(msg, ctx->llme); + msgb_free(msg); + + /* verify that things are gone */ + OSMO_ASSERT(count(gprs_llme_list()) == 0); + ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid); + /* this is still wrong and needs to be changed */ + OSMO_ASSERT(ictx); + OSMO_ASSERT(ictx->llme == lle->llme); +} static struct log_info_cat gprs_categories[] = { [DMM] = { @@ -149,6 +208,7 @@ int main(int argc, char **argv) tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb"); test_llme(); + test_gmm_detach(); printf("Done\n"); return 0; } diff --git a/openbsc/tests/sgsn/sgsn_test.ok b/openbsc/tests/sgsn/sgsn_test.ok index 045b9e534..57326fab1 100644 --- a/openbsc/tests/sgsn/sgsn_test.ok +++ b/openbsc/tests/sgsn/sgsn_test.ok @@ -1,2 +1,3 @@ Testing LLME allocations +Testing GMM detach Done -- cgit v1.2.3