Fix Stack buffer overflow and Path traversal 76/314476/1
authorJaehyun Kim <jeik01.kim@samsung.com>
Thu, 11 Apr 2024 08:34:42 +0000 (17:34 +0900)
committerJaehyun Kim <jeik01.kim@samsung.com>
Fri, 12 Jul 2024 06:28:01 +0000 (15:28 +0900)
Fix security vulnerabilities.
  - Stack buffer overflow issue in __netconfig_trigger_netlink_scan
  - Path traversal issue in DeleteEapConfig method
  - Path traversal issue in CreateEapConfig method

Change-Id: I76ef04f98cdb28926901899f511c80e6162f89ad
Signed-off-by: Jaehyun Kim <jeik01.kim@samsung.com>
include/wifi-config.h
src/wifi-config.c
src/wifi-eap-config.c
src/wifi-netlink-scan.c

index 4f674f6855b827b40c00398f15ebe9ea87a8d9da..df03cb9b1da20cbc281f033aa675d140473aa20b 100755 (executable)
@@ -86,6 +86,7 @@ gboolean wifi_config_get_group_name(const gchar *prefix,
 int __netconfig_hex_str_to_bin(const char *hex, unsigned char *buf, size_t len);
 int __netconfig_hex_to_byte(const char *hex);
 int __netconfig_hex_char_to_num(char c);
+gboolean __netconfig_is_valid_config_id(const gchar *config_id);
 
 gboolean handle_get_config_ids(Wifi *wifi, GDBusMethodInvocation *context,
                        const gchar *ifname);
index e586835f7638b57490ed5a743ae54b004ddf77f2..3ceb2b6d8eb8bbcf71f078f9acbba4aeaef402e0 100755 (executable)
@@ -1221,7 +1221,7 @@ static unsigned char __netconfig_convert_netmask_to_prefixlen(
        return bits;
 }
 
-static gboolean __netconfig_is_valid_config_id(const gchar *config_id)
+gboolean __netconfig_is_valid_config_id(const gchar *config_id)
 {
        int length;
 
@@ -1233,9 +1233,7 @@ static gboolean __netconfig_is_valid_config_id(const gchar *config_id)
                return FALSE;
 
        for (int i = 0; i < length; i++) {
-               if (!(islower(config_id[i])) &&
-                               !(isdigit(config_id[i])) &&
-                               config_id[i] != '_')
+               if (!(isxdigit(config_id[i])) && config_id[i] != '_')
                        return FALSE;
        }
 
index 1791ecfc66ee8e819d4e12f218e4ec285b06c6e3..e92f8cac6f0a1ff37ca8bde4fa1b40e61723a53b 100755 (executable)
@@ -21,6 +21,7 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <sys/stat.h>
+#include <ctype.h>
 
 #include "log.h"
 #include "util.h"
 #define CONNMAN_CONFIG_FIELD_PVT_KEY_PASSPHRASE                "PrivateKeyPassphrase"
 #define CONNMAN_CONFIG_FIELD_KEYMGMT_TYPE                      "KeymgmtType"
 
+static gboolean __netconfig_is_valid_hex(const gchar *str)
+{
+       int length;
+
+       if (!str)
+               return FALSE;
+
+       length = strlen(str);
+       if (length < 1)
+               return FALSE;
+
+       for (int i = 0; i < length; i++) {
+               if (!(isxdigit(str[i])))
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
 static char *__get_encoded_ssid(const char *name)
 {
        char *str = NULL;
@@ -251,7 +271,7 @@ static gboolean __netconfig_create_config(const char *profile, GVariant *fields)
                }
        }
 
-       if (encoded_ssid == NULL) {
+       if (__netconfig_is_valid_hex(encoded_ssid) == FALSE) {
                ERR("Failed to fetch SSID");
                goto out;
        }
@@ -259,6 +279,11 @@ static gboolean __netconfig_create_config(const char *profile, GVariant *fields)
        memcpy(mac_str, &profile[strlen(CONNMAN_WIFI_SERVICE_PROFILE_PREFIX)], 12);
        mac_str[12] = '\0';
 
+       if (__netconfig_is_valid_hex(mac_str) == FALSE) {
+               ERR("Failed to fetch mac_str");
+               goto out;
+       }
+
        /* Create unique service group name */
        group_name = g_strdup_printf("service_%s", encoded_ssid);
        if (group_name == NULL) {
@@ -278,7 +303,7 @@ static gboolean __netconfig_create_config(const char *profile, GVariant *fields)
        while (g_variant_iter_loop(iter, "{ss}", &field, &value)) {
                if (g_strcmp0(field, CONNMAN_CONFIG_FIELD_SSID) == 0 ||
                                g_strcmp0(field, CONNMAN_CONFIG_FIELD_EAP_METHOD) == 0 ||
-                               g_strcmp0(field, CONNMAN_CONFIG_FIELD_PHASE2) ||
+                               g_strcmp0(field, CONNMAN_CONFIG_FIELD_PHASE2) == 0 ||
                                g_strcmp0(field, CONNMAN_CONFIG_FIELD_KEYMGMT_TYPE) == 0) {
                        if (value != NULL)
                                g_key_file_set_string(keyfile, group_name, field, value);
@@ -375,6 +400,12 @@ static gboolean _delete_configuration(const char *interface_name, const char *pr
        }
        ERR("get config_id [%s] from [%s]", config_id, profile);
 
+       if (__netconfig_is_valid_config_id(config_id) == FALSE) {
+               ERR("Invalid config_id [%s]", config_id);
+               g_free(config_id);
+               return ret;
+       }
+
        ret = wifi_config_remove_configuration(interface_name, config_id);
        if (ret != TRUE)
                ERR("Fail to wifi_config_remove_configuration [%s]", config_id);
index 9f4cfd62c21e7cb387bb71c673798ae455f1fca2..b4eb6e3a11c3ea30289a2856bfc7c37bd90f76a3 100755 (executable)
@@ -704,7 +704,8 @@ static int __netconfig_trigger_netlink_scan(struct nl_sock *socket,
                int vsie_len = strlen(vsie);
                DBG("vsie: %s vsie_len: %d", vsie, vsie_len);
                ies_len = (vsie_len % 2) ? ((vsie_len / 2) + 1) : (vsie_len / 2);
-               __netconfig_hex_str_to_bin(vsie, ies, ies_len);
+               if (NETCONFIG_MAX_VSIE_LEN >= ies_len)
+                       __netconfig_hex_str_to_bin(vsie, ies, ies_len);
        }
 
        if (ies[0] == NETCONFIG_VENDOR_SPECIFIC_ID && ies[1] >= 4) {