From c01595508f5228eac0e52e440a504ca8a874feda Mon Sep 17 00:00:00 2001 From: Jeon YoungHo Date: Thu, 7 May 2020 22:27:19 +0900 Subject: [PATCH] Multiple vulnerabilities in handle-vpn-block-networks handler of vpnsvc D-Bus service Change-Id: Iff6033ce86a124f70d9062a6f00928e305763c02 Signed-off-by: Jeon YoungHo --- packaging/net-config.spec | 2 +- src/vpnsvc.c | 143 +++++++++++++++++++++++--------------- 2 files changed, 88 insertions(+), 57 deletions(-) diff --git a/packaging/net-config.spec b/packaging/net-config.spec index 8402b43..e68037b 100755 --- a/packaging/net-config.spec +++ b/packaging/net-config.spec @@ -1,6 +1,6 @@ Name: net-config Summary: TIZEN Network Configuration service -Version: 1.1.154 +Version: 1.1.155 Release: 3 Group: System/Network License: Apache-2.0 diff --git a/src/vpnsvc.c b/src/vpnsvc.c index 8ed0608..04f6ae1 100755 --- a/src/vpnsvc.c +++ b/src/vpnsvc.c @@ -145,6 +145,8 @@ gboolean handle_vpn_down(Vpnsvc *object, return TRUE; } +#define MAX_NUM_ROUTE_RULE 255 + gboolean handle_vpn_block_networks(Vpnsvc *object, GDBusMethodInvocation *invocation, GVariant *arg_nets_vpn, @@ -155,71 +157,100 @@ gboolean handle_vpn_block_networks(Vpnsvc *object, DBG("handle_vpn_block_networks"); int result = VPNSVC_ERROR_NONE; + if (arg_nr_nets_vpn > MAX_NUM_ROUTE_RULE) { + ERR("Number of allowing networks over VPN interface is exceeded %d," + " Limit is %d", arg_nr_nets_vpn, MAX_NUM_ROUTE_RULE); + result = VPNSVC_ERROR_INVALID_PARAMETER; + goto method_complete; + } - char *nets_vpn[arg_nr_nets_vpn]; - int prefix_vpn[arg_nr_nets_vpn]; - - char *nets_orig[arg_nr_nets_vpn]; - int prefix_orig[arg_nr_nets_vpn]; - - int i = 0; - GVariantIter iter; - gchar* route_dest; - gint route_prefix; - - DBG("vpn_block_networks"); - - memset(nets_vpn, 0, sizeof(char *) * arg_nr_nets_vpn); - memset(prefix_vpn, 0, sizeof(int) * arg_nr_nets_vpn); - memset(nets_orig, 0, sizeof(char *) * arg_nr_nets_vpn); - memset(prefix_orig, 0, sizeof(int) * arg_nr_nets_vpn); - - /* arg_nets_vpn check */ - if (arg_nr_nets_vpn > 0) { - if (arg_nets_vpn != NULL) { - GVariant *dict_nets_vpn = g_variant_get_variant(arg_nets_vpn); - g_variant_iter_init(&iter, dict_nets_vpn); - i = 0; - while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) { - int tmp_route_len = strlen(route_dest); - nets_vpn[i] = g_try_malloc0(sizeof(char) * tmp_route_len + 1); - strncpy(nets_vpn[i], route_dest, tmp_route_len); - nets_vpn[i][tmp_route_len] = '\0'; - prefix_vpn[i] = route_prefix; - DBG("nets_vpn[%d] = %s \t", i, (nets_vpn[i] == NULL) ? "" : nets_vpn[i]); - DBG("prefix_vpn[%d] = %d ", i, prefix_vpn[i]); - i++; + if (arg_nr_nets_orig > MAX_NUM_ROUTE_RULE) { + ERR("Number of allowing networks over original interface is exceeded" + " %d, Limit is %d", arg_nr_nets_orig, MAX_NUM_ROUTE_RULE); + result = VPNSVC_ERROR_INVALID_PARAMETER; + goto method_complete; + } + + do { + char *nets_vpn[arg_nr_nets_vpn]; + int prefix_vpn[arg_nr_nets_vpn]; + + char *nets_orig[arg_nr_nets_orig]; + int prefix_orig[arg_nr_nets_orig]; + + int i = 0; + GVariantIter iter; + gchar* route_dest; + gint route_prefix; + + DBG("vpn_block_networks"); + + memset(nets_vpn, 0, sizeof(char *) * arg_nr_nets_vpn); + memset(prefix_vpn, 0, sizeof(int) * arg_nr_nets_vpn); + memset(nets_orig, 0, sizeof(char *) * arg_nr_nets_orig); + memset(prefix_orig, 0, sizeof(int) * arg_nr_nets_orig); + + /* arg_nets_vpn check */ + if (arg_nr_nets_vpn > 0) { + if (arg_nets_vpn != NULL) { + GVariant *dict_nets_vpn = g_variant_get_variant(arg_nets_vpn); + g_variant_iter_init(&iter, dict_nets_vpn); + i = 0; + while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) { + if (i >= arg_nr_nets_vpn) { + WARN("No more space for allowing network over VPN interface." + " next index %d / space size %d", i, arg_nr_nets_vpn); + break; + } + int tmp_route_len = strlen(route_dest); + nets_vpn[i] = g_try_malloc0(sizeof(char) * tmp_route_len + 1); + strncpy(nets_vpn[i], route_dest, tmp_route_len); + nets_vpn[i][tmp_route_len] = '\0'; + prefix_vpn[i] = route_prefix; + DBG("nets_vpn[%d] = %s \t", i, (nets_vpn[i] == NULL) ? "" : nets_vpn[i]); + DBG("prefix_vpn[%d] = %d ", i, prefix_vpn[i]); + i++; + } } } - } - /* arg_nets_orig check */ - if (arg_nr_nets_orig > 0) { - if (arg_nets_orig != NULL) { - GVariant *dict_nets_orig = g_variant_get_variant(arg_nets_orig); - g_variant_iter_init(&iter, dict_nets_orig); - i = 0; - while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) { - int tmp_route_len = strlen(route_dest); - nets_orig[i] = g_try_malloc0(sizeof(char) * tmp_route_len + 1); - strncpy(nets_orig[i], route_dest, tmp_route_len); - nets_orig[i][tmp_route_len] = '\0'; - prefix_orig[i] = route_prefix; - DBG("nets_orig[%d] = %s \t", i, (nets_orig[i] == NULL) ? "" : nets_orig[i]); - DBG("prefix_orig[%d] = %d ", i, prefix_orig[i]); - i++; + /* arg_nets_orig check */ + if (arg_nr_nets_orig > 0) { + if (arg_nets_orig != NULL) { + GVariant *dict_nets_orig = g_variant_get_variant(arg_nets_orig); + g_variant_iter_init(&iter, dict_nets_orig); + i = 0; + while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) { + if (i >= arg_nr_nets_orig) { + WARN("No more space for allowing network over VPN interface." + " next index %d / space size %d", i, arg_nr_nets_orig); + break; + } + int tmp_route_len = strlen(route_dest); + nets_orig[i] = g_try_malloc0(sizeof(char) * tmp_route_len + 1); + strncpy(nets_orig[i], route_dest, tmp_route_len); + nets_orig[i][tmp_route_len] = '\0'; + prefix_orig[i] = route_prefix; + DBG("nets_orig[%d] = %s \t", i, (nets_orig[i] == NULL) ? "" : nets_orig[i]); + DBG("prefix_orig[%d] = %d ", i, prefix_orig[i]); + i++; + } } } - } - /* call function */ - result = vpn_service_block_networks(nets_vpn, prefix_vpn, arg_nr_nets_vpn, nets_orig, prefix_orig, arg_nr_nets_orig); + /* call function */ + result = vpn_service_block_networks(nets_vpn, prefix_vpn, arg_nr_nets_vpn, nets_orig, prefix_orig, arg_nr_nets_orig); - for (i = 0; i < arg_nr_nets_vpn; ++i) { - g_free(nets_orig[i]); - g_free(nets_vpn[i]); - } + for (i = 0; i < arg_nr_nets_vpn; ++i) { + g_free(nets_vpn[i]); + } + + for (i = 0; i < arg_nr_nets_orig; ++i) { + g_free(nets_orig[i]); + } + } while(0); +method_complete: vpnsvc_complete_vpn_block_networks(object, invocation, result); return TRUE; -- 2.34.1