From: Seonah Moon Date: Tue, 18 Apr 2017 11:11:52 +0000 (+0900) Subject: [WGID-200328, 200330, 200606] Fixed some codes for secure coding X-Git-Tag: accepted/tizen/unified/20170421.115034~1^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fconnectivity%2Fnet-config.git;a=commitdiff_plain;h=ae84ddfec8846b077c365a44b058ba309202471c [WGID-200328, 200330, 200606] Fixed some codes for secure coding - Replaced sscanf() with strtol() - Replaced popen() with execv() Change-Id: I522835540c7834e8528bead0ab50c042b2eba1ee Signed-off-by: Seonah Moon --- diff --git a/include/util.h b/include/util.h index 2cce5ee..3070cf4 100755 --- a/include/util.h +++ b/include/util.h @@ -29,7 +29,7 @@ extern "C" { #include "wifi.h" #include "plugin.h" -#define NETCONFIG_TIZEN_SYSTEM_ENV "/run/tizen-system-env" +#define NETCONFIG_TIZEN_SYSTEM_ENV "/run/tizen-system-env" #define MAX_SIZE_ERROR_BUFFER 256 @@ -52,6 +52,7 @@ gboolean netconfig_is_wifi_tethering_on(void); gboolean netconfig_interface_up(const char *ifname); gboolean netconfig_interface_down(const char *ifname); +int netconfig_execute_cmd(const char *cmd); int netconfig_execute_file(const char *file_path, char *const args[], char *const env[]); int netconfig_execute_clatd(const char *file_path, char *const args[]); int netconfig_add_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, unsigned char prefix_len); diff --git a/packaging/net-config.spec b/packaging/net-config.spec index 4b722a6..d473173 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.108 +Version: 1.1.109 Release: 2 Group: System/Network License: Apache-2.0 diff --git a/src/utils/util.c b/src/utils/util.c index 6efd972..495567d 100755 --- a/src/utils/util.c +++ b/src/utils/util.c @@ -419,6 +419,58 @@ int netconfig_execute_file(const char *file_path, return -EIO; } +int netconfig_execute_cmd(const char *cmd) +{ + if (cmd == NULL) + return -EIO; + + pid_t pid = 0; + int status = 0; + int rv = 0; + errno = 0; + char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, }; + gchar **args = NULL; + + DBG("command: %s", cmd); + + args = g_strsplit_set(cmd, " ", -1); + + if (!(pid = fork())) { + DBG("pid(%d), ppid (%d)", getpid(), getppid()); + + errno = 0; + if (execv(args[0], args) == -1) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("Fail to execute command (%s)", error_buf); + g_strfreev(args); + exit(1); + } + } else if (pid > 0) { + if (waitpid(pid, &status, 0) == -1) + DBG("wait pid (%u) status (%d)", pid, status); + + if (WIFEXITED(status)) { + rv = WEXITSTATUS(status); + DBG("exited, status=%d", rv); + } else if (WIFSIGNALED(status)) { + DBG("killed by signal %d", WTERMSIG(status)); + } else if (WIFSTOPPED(status)) { + DBG("stopped by signal %d", WSTOPSIG(status)); + } else if (WIFCONTINUED(status)) { + DBG("continued"); + } + + g_strfreev(args); + return rv; + } + + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("failed to fork(%s)", error_buf); + g_strfreev(args); + + return -EIO; +} + static void on_clat_handler() { pid_t clat_pid = 0; diff --git a/src/vpnsvc-internal.c b/src/vpnsvc-internal.c index 1ccfcbf..f0b4d88 100755 --- a/src/vpnsvc-internal.c +++ b/src/vpnsvc-internal.c @@ -35,7 +35,9 @@ #include "vpnsvc-internal.h" #include "log.h" +#include "util.h" +#define BUF_SIZE_FOR_CMD 1024 #define BUF_SIZE_FOR_ERR 100 #define CONNMAN_SERVICE "net.connman" @@ -49,19 +51,23 @@ static char iptables_filter_prefix[] = "CAPI_VPN_SERVICE_"; static char iptables_filter_out[] = "OUTPUT"; static char iptables_filter_in[] = "INPUT"; static char iptables_filter_interface_wlan[] = "wlan0"; -/* static char iptables_register_fmt[] = "%s -N %s%s -w;" "%s -F %s%s -w;" "%s -A %s%s -j RETURN -w;" "%s -I %s -j %s%s -w;"; */ -static char iptables_register_fmt[] = "%s -N %s%s -w;" "%s -F %s%s -w;" "%s -A %s%s -j DROP -w;" "%s -A %s%s -j RETURN -w;" "%s -I %s -j %s%s -w;"; -static char iptables_unregister_fmt[] = "%s -D %s -j %s%s -w;" "%s -F %s%s -w;" "%s -X %s%s -w;"; -static char iptables_rule_fmt[] = "%s -%c %s%s -%c %s/%d -j ACCEPT -w;"; -static char iptables_rule_with_interface_fmt[] = "%s -%c %s%s -%c %s -%c %s/%d -j ACCEPT -w;"; +static char iptables_nat_chain_name[] = "CAPI_VPN_SERVICE_NAT_OUTPUT"; + +#define IPTABLES_FMT_CREATE_CHAIN "%s -N %s%s -w" +#define IPTABLES_FMT_APPEND_DROP_RULE "%s -A %s%s -j DROP -w" +#define IPTABLES_FMT_APPEND_RETURN_RULE "%s -A %s%s -j RETURN -w" +#define IPTABLES_FMT_INSERT_RULE "%s -I %s -j %s%s -w" +#define IPTABLES_FMT_DEL_RULE "%s -D %s -j %s%s -w" +#define IPTABLES_FMT_FLUSH_CHAIN "%s -F %s%s -w" +#define IPTABLES_FMT_DEL_CHAIN "%s -X %s%s -w" +#define IPTABLES_FMT_APPEND_ACCEPT_RULE "%s -%c %s%s -%c %s/%d -j ACCEPT -w" +#define IPTABLES_FMT_APPEND_ACCEPT_RULE_WITH_INTF "%s -%c %s%s -%c %s -%c %s/%d -j ACCEPT -w" +#define IPTABLES_FMT_DEL_RULE_FROM_NAT "%s -t nat -D %s -j %s -w" +#define IPTABLES_FMT_FLUSH_CHAIN_FROM_NAT "%s -t nat -F %s -w" +#define IPTABLES_FMT_DEL_CHAIN_FROM_NAT "%s -t nat -X %s -w" + /*static char iptables_usage_fmt[] = "%s -L %s%s -n -v -w;";*/ /* iptables -t nat -A CAPI_VPN_SERVICE_OUTPUT -p udp -d --dport 53 -j DNAT --to */ -static char iptables_nat_chain_name[] = "CAPI_VPN_SERVICE_NAT_OUTPUT"; -#if 0 -static char iptables_nat_register_init_fmt[] = "%s -t nat -N %s -w;" "%s -t nat -F %s -w;" "%s -t nat -I %s -j %s -w;"; -static char iptables_nat_register_rule_fmt[] = "%s -t nat -A %s -p udp -d %s --dport 53 -j DNAT --to %s:53 -w;"; -#endif -static char iptables_nat_unregister_fmt[] = "%s -t nat -D %s -j %s -w;" "%s -t nat -F %s -w;" "%s -t nat -X %s -w;"; typedef unsigned long int ipv4; /* Declare variable type for ipv4 net address. */ @@ -472,15 +478,26 @@ static int del_dns_suffix() return VPNSVC_ERROR_NONE; } - -static void iptables_exec(char *cmdline) +static int _check_config_str(void) { - FILE *fp = NULL; + char *buf = NULL; + size_t len; - fp = popen(cmdline, "r"); + len = confstr(_CS_PATH, NULL, 0); + if (len == 0) + return -1; - if (fp != NULL) - pclose(fp); + if ((buf = malloc(len)) == NULL) + return -1; + + if (confstr(_CS_PATH, buf, len) == 0) { + free(buf); + return -1; + } + + free(buf); + + return 0; } #if 0 @@ -507,92 +524,170 @@ static void dns_nat_register(char **vpn_dns_address, size_t nr_dns, char *vpn_de static void dns_nat_unregister(void) { - int size = 0; - char buf[8192]; + char buf[BUF_SIZE_FOR_CMD]; - snprintf(buf + size, sizeof(buf) - size, iptables_nat_unregister_fmt, - iptables_cmd, iptables_filter_out, iptables_nat_chain_name, - iptables_cmd, iptables_nat_chain_name, + snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_RULE_FROM_NAT, + iptables_cmd, iptables_filter_out, iptables_nat_chain_name); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); + + memset(buf, '0', sizeof(buf)); + snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN_FROM_NAT, iptables_cmd, iptables_nat_chain_name); - size = strlen(buf); - DBG("iptable dns nat unreg cmd : %s", buf); - iptables_exec(buf); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); + + memset(buf, '0', sizeof(buf)); + snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_CHAIN_FROM_NAT, + iptables_cmd, iptables_nat_chain_name); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); } static void iptables_register(void) { - int size = 0; - char buf[8192], *filter; + char buf[BUF_SIZE_FOR_CMD] = {0, }; + char *filter; filter = iptables_filter_out; - snprintf(buf + size, sizeof(buf) - size, iptables_register_fmt, - iptables_cmd, iptables_filter_prefix, filter, - iptables_cmd, iptables_filter_prefix, filter, - iptables_cmd, iptables_filter_prefix, filter, - iptables_cmd, iptables_filter_prefix, filter, - iptables_cmd, filter, iptables_filter_prefix, filter); - size = strlen(buf); + + snprintf(buf, sizeof(buf), IPTABLES_FMT_CREATE_CHAIN, + iptables_cmd, iptables_filter_prefix, filter); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); + + memset(buf, '0', sizeof(buf)); + snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN, + iptables_cmd, iptables_filter_prefix, filter); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); + + memset(buf, '0', sizeof(buf)); + snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_DROP_RULE, + iptables_cmd, iptables_filter_prefix, filter); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); + + memset(buf, '0', sizeof(buf)); + snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_RETURN_RULE, + iptables_cmd, iptables_filter_prefix, filter); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); + + memset(buf, '0', sizeof(buf)); + snprintf(buf, sizeof(buf), IPTABLES_FMT_INSERT_RULE, + iptables_cmd, filter, iptables_filter_prefix, filter); + filter = iptables_filter_in; - snprintf(buf + size, sizeof(buf) - size, iptables_register_fmt, - iptables_cmd, iptables_filter_prefix, filter, - iptables_cmd, iptables_filter_prefix, filter, - iptables_cmd, iptables_filter_prefix, filter, - iptables_cmd, iptables_filter_prefix, filter, - iptables_cmd, filter, iptables_filter_prefix, filter); - DBG("iptable reg cmd : %s", buf); - iptables_exec(buf); + + memset(buf, '0', sizeof(buf)); + snprintf(buf, sizeof(buf), IPTABLES_FMT_CREATE_CHAIN, + iptables_cmd, iptables_filter_prefix, filter); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); + + memset(buf, '0', sizeof(buf)); + snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN, + iptables_cmd, iptables_filter_prefix, filter); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); + + memset(buf, '0', sizeof(buf)); + snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_DROP_RULE, + iptables_cmd, iptables_filter_prefix, filter); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); + + memset(buf, '0', sizeof(buf)); + snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_RETURN_RULE, + iptables_cmd, iptables_filter_prefix, filter); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); + + memset(buf, '0', sizeof(buf)); + snprintf(buf, sizeof(buf), IPTABLES_FMT_INSERT_RULE, + iptables_cmd, filter, iptables_filter_prefix, filter); } static void iptables_unregister(void) { - int size = 0; - char buf[8192], *filter; + char buf[BUF_SIZE_FOR_CMD] = {0, }; + char *filter; filter = iptables_filter_out; - snprintf(buf + size, sizeof(buf) - size, iptables_unregister_fmt, - iptables_cmd, filter, iptables_filter_prefix, filter, - iptables_cmd, iptables_filter_prefix, filter, - iptables_cmd, iptables_filter_prefix, filter); - size = strlen(buf); + + snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_RULE, + iptables_cmd, filter, iptables_filter_prefix, filter); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); + + memset(buf, '0', sizeof(buf)); + snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN, + iptables_cmd, iptables_filter_prefix, filter); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); + + memset(buf, '0', sizeof(buf)); + snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_CHAIN, + iptables_cmd, iptables_filter_prefix, filter); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); + filter = iptables_filter_in; - snprintf(buf + size, sizeof(buf) - size, iptables_unregister_fmt, - iptables_cmd, filter, iptables_filter_prefix, filter, - iptables_cmd, iptables_filter_prefix, filter, - iptables_cmd, iptables_filter_prefix, filter); - DBG("iptable unreg cmd : %s", buf); - iptables_exec(buf); + + memset(buf, '0', sizeof(buf)); + snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_RULE, + iptables_cmd, filter, iptables_filter_prefix, filter); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); + + memset(buf, '0', sizeof(buf)); + snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN, + iptables_cmd, iptables_filter_prefix, filter); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); + + memset(buf, '0', sizeof(buf)); + snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_CHAIN, + iptables_cmd, iptables_filter_prefix, filter); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); } static void iptables_rule(const char c, const char *addr, const int mask) { - int size = 0; - char buf[4096]; - - snprintf(buf + size, sizeof(buf) - size, iptables_rule_fmt, iptables_cmd, c, - iptables_filter_prefix, iptables_filter_out, 'd', addr, mask); - size = strlen(buf); - snprintf(buf + size, sizeof(buf) - size, iptables_rule_fmt, iptables_cmd, c, - iptables_filter_prefix, iptables_filter_in, 's', addr, mask); - DBG("iptable cmd : %s", buf); - iptables_exec(buf); + char buf[BUF_SIZE_FOR_CMD]; + + snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_ACCEPT_RULE, + iptables_cmd, c, iptables_filter_prefix, + iptables_filter_out, 'd', addr, mask); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); + + memset(buf, '0', sizeof(buf)); + snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_ACCEPT_RULE, + iptables_cmd, c, iptables_filter_prefix, + iptables_filter_in, 's', addr, mask); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); } static void iptables_rule_interface(const char c, const char *addr, const int mask, const char *interface) { - int size = 0; - char buf[4096]; + char buf[BUF_SIZE_FOR_CMD]; - snprintf(buf + size, sizeof(buf) - size, - iptables_rule_with_interface_fmt, iptables_cmd, - c, iptables_filter_prefix, iptables_filter_out, + snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_ACCEPT_RULE_WITH_INTF, + iptables_cmd, c, iptables_filter_prefix, iptables_filter_out, 'o', interface, 'd', addr, mask); - size = strlen(buf); - snprintf(buf + size, sizeof(buf) - size, - iptables_rule_with_interface_fmt, iptables_cmd, - c, iptables_filter_prefix, iptables_filter_in, + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); + + memset(buf, '0', sizeof(buf)); + snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_ACCEPT_RULE_WITH_INTF, + iptables_cmd, c, iptables_filter_prefix, iptables_filter_in, 'i', interface, 's', addr, mask); - DBG("iptable cmd : %s", buf); - iptables_exec(buf); + if (netconfig_execute_cmd(buf)) + ERR("Failed to execute command: %s", buf); } void iptables_add_orig(const char *addr, const int mask) @@ -734,13 +829,24 @@ int vpn_service_init(const char* iface_name, size_t iface_name_len, int fd, vpns int vpn_service_deinit(const char* dev_name) { - char buf[100]; + char buf[100], *cmd; FILE *fp = NULL; + if (_check_config_str() != 0) { + ERR("Failed to get configuration string"); + return VPNSVC_ERROR_IO_ERROR; + } + snprintf(buf, sizeof(buf), "/usr/sbin/ip link del %s", dev_name); - DBG("link delete cmd : %s", buf); - fp = popen(buf, "r"); + cmd = g_try_malloc0(strlen(buf) + 1); + strncpy(cmd, buf, strlen(buf)); + + DBG("link delete cmd : %s", cmd); + + fp = popen(cmd, "r"); + g_free(cmd); + if (fp != NULL) { pclose(fp); return VPNSVC_ERROR_NONE; diff --git a/src/wifi-config.c b/src/wifi-config.c index bd1c112..2023fd9 100755 --- a/src/wifi-config.c +++ b/src/wifi-config.c @@ -218,9 +218,8 @@ static GKeyFile *__get_configuration_keyfile(const gchar *group_name) path = g_strdup_printf(CONNMAN_STORAGE "/%s/settings", group_name); keyfile = netconfig_keyfile_load(path); - if (keyfile == NULL) { + if (keyfile == NULL) ERR("keyfile[%s] is NULL", path); - } g_free(path); diff --git a/src/wifi-indicator.c b/src/wifi-indicator.c index 12372c2..36cf86e 100755 --- a/src/wifi-indicator.c +++ b/src/wifi-indicator.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -82,8 +83,9 @@ static int __netconfig_wifi_update_and_get_rssi(void) goto endline; while (fgets(buf, sizeof(buf), fp)) { - unsigned int status; - int link, noise; + unsigned int status = 0; + int link = 0; + int noise = 0; /* No need to read */ /* unsigned long nwid, crypt, frag, retry, misc, missed; @@ -101,18 +103,32 @@ static int __netconfig_wifi_update_and_get_rssi(void) /* read wireless status */ char *saveptr; - p_entry = strtok_r(p_entry, " .", &saveptr); /* status "%x" */ + p_entry = strtok_r(p_entry, " .", &saveptr); + + /* status "%x" */ if (p_entry != NULL) - sscanf(p_entry, "%x", &status); - p_entry = strtok_r(NULL, " .", &saveptr); /* Quality link "%d" */ + status = (int)strtol(p_entry, NULL, 16); + + p_entry = strtok_r(NULL, " .", &saveptr); + + /* Quality link "%d" */ if (p_entry != NULL) - sscanf(p_entry, "%d", &link); - p_entry = strtok_r(NULL, " .", &saveptr); /* Quality level "%d" */ + link = (int)strtol(p_entry, NULL, 10); + + p_entry = strtok_r(NULL, " .", &saveptr); + + /* Quality level "%d" */ if (p_entry != NULL) - sscanf(p_entry, "%d", &rssi_dbm); - p_entry = strtok_r(NULL, " .", &saveptr); /* Quality noise "%d" */ + rssi_dbm = (int)strtol(p_entry, NULL, 10); + + p_entry = strtok_r(NULL, " .", &saveptr); + + /* Quality noise "%d" */ if (p_entry != NULL) - sscanf(p_entry, "%d", &noise); + noise = (int)strtol(p_entry, NULL, 10); + + DBG("status(%x) link(%d) rssi_dbm(%d) noise(%d)", + status, link, rssi_dbm, noise); /* No need to read */ /*