From 22e116014c8b9fbd07bfb99243dc990b6979c554 Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Tue, 3 Nov 2015 12:46:37 +0100 Subject: [PATCH] proxy.c: fix overflow in linphone_proxy_config_normalize_phone_number API resulting in invalid writes --- coreapi/proxy.c | 12 ++++--- tester/proxy_config_tester.c | 63 ++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 5 deletions(-) diff --git a/coreapi/proxy.c b/coreapi/proxy.c index ae60dd071..918c6d1b8 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -868,15 +868,15 @@ char* linphone_proxy_config_normalize_phone_number(LinphoneProxyConfig *proxy, c if (linphone_proxy_config_is_phone_number(tmpproxy, username)){ dial_plan_t dialplan = {0}; char * flatten=flatten_number(username); - ms_debug("Flattened number is '%s'",flatten); + ms_error("Flattened number is '%s' for '%s'",flatten, username); /*if proxy has a dial prefix, modify phonenumber accordingly*/ if (tmpproxy->dial_prefix!=NULL && tmpproxy->dial_prefix[0]!='\0'){ lookup_dial_plan_by_ccc(tmpproxy->dial_prefix,&dialplan); - ms_debug("Using dial plan '%s'",dialplan.country); + ms_error("Using dial plan '%s'",dialplan.country); /* the number already starts with + or international prefix*/ if (flatten[0]=='+'||strstr(flatten,dialplan.icp)==flatten){ - ms_debug("Prefix already present."); + ms_error("Prefix already present."); if (tmpproxy->dial_escape_plus) { result = replace_plus_with_icp(flatten,dialplan.icp); } else { @@ -884,15 +884,17 @@ char* linphone_proxy_config_normalize_phone_number(LinphoneProxyConfig *proxy, c } }else{ /*0. keep at most national number significant digits */ - char* flatten_start = flatten + MAX(0, strlen(flatten) - dialplan.nnl); + char* flatten_start = flatten + MAX(0, (int)strlen(flatten) - (int)dialplan.nnl); + ms_error("Prefix not present. Keeping at most %d digits: %s", dialplan.nnl, flatten_start); + /*1. First prepend international calling prefix or +*/ /*2. Second add prefix*/ /*3. Finally add user digits */ - result = ms_strdup_printf("%s%s%s" , tmpproxy->dial_escape_plus ? dialplan.icp : "+" , dialplan.ccc , flatten_start); + ms_error("Prepended prefix resulted in %s", result); } } if (result==NULL) { diff --git a/tester/proxy_config_tester.c b/tester/proxy_config_tester.c index ac8e266a5..771403e84 100644 --- a/tester/proxy_config_tester.c +++ b/tester/proxy_config_tester.c @@ -41,6 +41,18 @@ static void phone_normalization_without_proxy(void) { BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "+3301234567891"), "+3301234567891"); BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "+33 01234567891"), "+3301234567891"); BC_ASSERT_PTR_NULL(phone_normalization(NULL, "I_AM_NOT_A_NUMBER")); // invalid phone number + + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "0"), "0"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "01"), "01"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "012"), "012"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "0123"), "0123"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "01234"), "01234"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "012345"), "012345"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "0123456"), "0123456"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "01234567"), "01234567"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "012345678"), "012345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "0123456789"), "0123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "01234567890"), "01234567890"); } static void phone_normalization_with_proxy(void) { @@ -70,8 +82,45 @@ static void phone_normalization_with_proxy(void) { BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0033952636505"), "+33952636505"); BC_ASSERT_PTR_NULL(phone_normalization(proxy, "toto")); + + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0"), "+330"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01"), "+3301"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012"), "+33012"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123"), "+330123"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234"), "+3301234"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012345"), "+33012345"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123456"), "+330123456"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234567"), "+3301234567"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012345678"), "+33012345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123456789"), "+33123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234567890"), "+33234567890"); + + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+330"), "+330"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+3301"), "+3301"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+33012"), "+33012"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+330123"), "+330123"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+3301234"), "+3301234"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+33012345"), "+33012345"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+330123456"), "+330123456"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+3301234567"), "+3301234567"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+33012345678"), "+33012345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+330123456789"), "+330123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+3301234567890"), "+3301234567890"); + + // invalid prefix - use a generic dialplan with 10 max length linphone_proxy_config_set_dial_prefix(proxy, "99"); BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0012345678"), "+12345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0"), "+990"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01"), "+9901"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012"), "+99012"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123"), "+990123"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234"), "+9901234"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012345"), "+99012345"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123456"), "+990123456"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234567"), "+9901234567"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012345678"), "+99012345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123456789"), "+990123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234567890"), "+991234567890"); linphone_proxy_config_destroy(proxy); } @@ -83,6 +132,20 @@ static void phone_normalization_with_dial_escape_plus(void){ BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0033952636505"), "0033952636505"); BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0952636505"), "0033952636505"); BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+34952636505"), "0034952636505"); + + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0"), "00330"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01"), "003301"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012"), "0033012"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123"), "00330123"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234"), "003301234"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012345"), "0033012345"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123456"), "00330123456"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234567"), "003301234567"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012345678"), "0033012345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123456789"), "0033123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234567890"), "0033234567890"); + + linphone_proxy_config_destroy(proxy); }