From 03f24fa207f9fbd8f9c5fa9d0cc5ca4d5739a0c5 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy Date: Tue, 23 Jul 2019 07:06:08 +0700 Subject: S1AP: HACK: initial fuzzing test case for S1AP_SetupReq Change-Id: Ib6c8d87a1118a99075d3f2a498f3af4bdc65e6ec --- library/s1ap/S1AP_EncDec.cc | 21 ++++++++++++++++++ library/s1ap/S1AP_Templates.ttcn | 31 ++++++++++++++++++++++++++ mme/MME_Tests.ttcn | 47 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 98 insertions(+), 1 deletion(-) diff --git a/library/s1ap/S1AP_EncDec.cc b/library/s1ap/S1AP_EncDec.cc index a17f20ec..7fa869d0 100644 --- a/library/s1ap/S1AP_EncDec.cc +++ b/library/s1ap/S1AP_EncDec.cc @@ -1,3 +1,5 @@ +#include +#include #include #include @@ -13,6 +15,7 @@ TTCN_Module S1AP__EncDec("S1AP_EncDec", __DATE__, __TIME__); OCTETSTRING enc__S1AP__PDU(const S1AP__PDU__Descriptions::S1AP__PDU &pdu) { + static unsigned long count = 0; uint8_t *aper_buf; int aper_buf_len; TTCN_Buffer TTCN_buf; @@ -27,6 +30,18 @@ OCTETSTRING enc__S1AP__PDU(const S1AP__PDU__Descriptions::S1AP__PDU &pdu) TTCN_error("fftranscode failed."); } + /* Observed srsEPC segfaults with: + * idx=1 && mask=0x1d + * idx=5 && mask=any */ + if (count++ % 2 == 0) { + int idx = rand() % aper_buf_len; + uint8_t mask = (uint8_t) rand(); + + /* TUWAT! Mangle a random byte. */ + printf("=== TUWAT: mangling octet %d with mask 0x%02x\n", idx, mask); + aper_buf[idx] ^= mask; + } + /* make octetstring from output buffer */ OCTETSTRING ret_val(aper_buf_len, aper_buf); @@ -62,3 +77,9 @@ S1AP__PDU__Descriptions::S1AP__PDU dec__S1AP__PDU(const OCTETSTRING &stream) } } + +static __attribute__((constructor)) void on_dso_load(void) +{ + /* Use a static seed for reproduceable results */ + srand(10000); +} diff --git a/library/s1ap/S1AP_Templates.ttcn b/library/s1ap/S1AP_Templates.ttcn index 6c5dbce6..8ea16682 100644 --- a/library/s1ap/S1AP_Templates.ttcn +++ b/library/s1ap/S1AP_Templates.ttcn @@ -25,6 +25,37 @@ import from S1AP_PDU_Descriptions all; * 9.1.8 Management Messages *********************************************************************************/ +/* 9.1.8.4 S1 SETUP REQUEST */ +template (value) S1AP_PDU +ts_S1AP_SetupReq_fuzz(template (value) Global_ENB_ID p_global_ENB_ID, + template (value) SupportedTAs p_supportedTAs, + template (value) PagingDRX p_pagingDRXs, + template (value) integer id := S1AP_Constants.id_SupportedTAs) := { + initiatingMessage := { + procedureCode := id_S1Setup, + criticality := reject, + value_ := { + S1SetupRequest := { + protocolIEs := { + { + id := S1AP_Constants.id_Global_ENB_ID, + criticality := reject, + value_ := { Global_ENB_ID := p_global_ENB_ID } + }, { + id := S1AP_Constants.id_SupportedTAs, + criticality := reject, + value_ := {SupportedTAs := p_supportedTAs} + }, { + id := S1AP_Constants.id_pagingDRX, + criticality := ignore, + value_ := {PagingDRX := p_pagingDRXs} + } + } + } + } + } +} + /* 9.1.8.4 S1 SETUP REQUEST */ template (value) S1AP_PDU ts_S1AP_SetupReq(template (value) Global_ENB_ID p_global_ENB_ID, diff --git a/mme/MME_Tests.ttcn b/mme/MME_Tests.ttcn index da45485d..6402021b 100644 --- a/mme/MME_Tests.ttcn +++ b/mme/MME_Tests.ttcn @@ -308,7 +308,8 @@ friend function f_init_handler(ConnHdlrPars pars, float t_guard := 30.0) runs on friend function f_s1ap_setup(integer idx := 0, template Cause cause := omit) runs on MTC_CT { var template (present) Cause exp_cause; var boolean exp_fail := false; - timer T := 5.0; + timer T := 2.0; + if (not istemplatekind(cause, "omit")) { exp_fail := true; exp_cause := cause; @@ -323,12 +324,15 @@ friend function f_s1ap_setup(integer idx := 0, template Cause cause := omit) run } [not exp_fail] S1AP_UNIT[idx].receive(tr_S1AP_SetupResp) { setverdict(pass); + mtc.stop; } [] S1AP_UNIT[idx].receive { setverdict(fail, "Received unexpected S1AP"); + mtc.stop; } [] T.timeout { setverdict(fail, "Timeout waiting for S1AP Setup result"); + mtc.stop; } } } @@ -561,11 +565,52 @@ testcase TC_s1ap_attach() runs on MTC_CT { vc_conn.done; } +friend function f_s1ap_setup_fuzz(integer idx := 0, integer id) runs on MTC_CT { + var boolean exp_fail := false; + timer T := 0.5; + + S1AP_UNIT[idx].send(ts_S1AP_SetupReq_fuzz(g_enb_pars[idx].global_enb_id, + g_enb_pars[idx].supported_tas, v32, id)); + T.start; + alt { + [] S1AP_UNIT[idx].receive(tr_S1AP_SetupFail) { + setverdict(pass); + } + [] S1AP_UNIT[idx].receive { + setverdict(fail, "Received unexpected S1AP"); + mtc.stop; + } + [] T.timeout { + setverdict(fail, "Timeout waiting for S1AP Setup result"); + log("Attempt #", id); + } + } +} + +/* S1 Setup Request fuzzing */ +testcase TC_s1ap_setup_fuzz() runs on MTC_CT { + var charstring id := testcasename(); + var integer i; + + f_init_s1ap(id, 1); + g_enb_pars[0].global_enb_id.pLMNidentity := '62F224'O; + + for (i := 0; i < 10000; i := i + 1) { + f_s1ap_setup_fuzz(0, i); + f_s1ap_setup(0, { misc := unknown_PLMN }); + } +} + + + control { execute( TC_s1ap_setup_wrong_plmn() ); execute( TC_s1ap_setup_wrong_tac() ); execute( TC_s1ap_setup() ); execute( TC_s1ap_attach() ); + + /* Fuzzing tests */ + execute( TC_s1ap_setup_fuzz() ); } -- cgit v1.2.3