From 99984eaeb3efca73b7ac877161b5fd96ad2711e3 Mon Sep 17 00:00:00 2001 From: Steven Barth Date: Fri, 17 Oct 2014 06:15:35 +0000 Subject: [PATCH] hostapd: CVE-2014-3686 fixes Signed-off-by: Steven Barth SVN-Revision: 42942 --- package/network/services/hostapd/Makefile | 2 +- ...exec-helper-to-run-external-programs.patch | 110 ++++++++++++++++++ ...-os_exec-for-action-script-execution.patch | 54 +++++++++ ...-os_exec-for-action-script-execution.patch | 54 +++++++++ .../hostapd/patches/120-daemonize_fix.patch | 6 +- .../hostapd/patches/370-ap_sta_support.patch | 2 +- .../patches/450-limit_debug_messages.patch | 2 +- .../patches/470-hostapd_cli_ifdef.patch | 8 +- .../hostapd/patches/490-scan_wait.patch | 2 +- 9 files changed, 229 insertions(+), 11 deletions(-) create mode 100644 package/network/services/hostapd/patches/002-Add-os_exec-helper-to-run-external-programs.patch create mode 100644 package/network/services/hostapd/patches/003-wpa_cli-Use-os_exec-for-action-script-execution.patch create mode 100644 package/network/services/hostapd/patches/004-hostapd_cli-Use-os_exec-for-action-script-execution.patch diff --git a/package/network/services/hostapd/Makefile b/package/network/services/hostapd/Makefile index 6300e0203c..47d808995e 100644 --- a/package/network/services/hostapd/Makefile +++ b/package/network/services/hostapd/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=hostapd -PKG_VERSION:=2014-06-03 +PKG_VERSION:=2014-06-03.1 PKG_RELEASE:=1 PKG_REV:=84df167554569af8c87f0a8ac1fb508192417d8e diff --git a/package/network/services/hostapd/patches/002-Add-os_exec-helper-to-run-external-programs.patch b/package/network/services/hostapd/patches/002-Add-os_exec-helper-to-run-external-programs.patch new file mode 100644 index 0000000000..c1db046410 --- /dev/null +++ b/package/network/services/hostapd/patches/002-Add-os_exec-helper-to-run-external-programs.patch @@ -0,0 +1,110 @@ +From 89de07a9442072f88d49869d8ecd8d42bae050a0 Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Mon, 6 Oct 2014 16:27:44 +0300 +Subject: [PATCH 1/3] Add os_exec() helper to run external programs + +Signed-off-by: Jouni Malinen +--- + src/utils/os.h | 9 +++++++++ + src/utils/os_unix.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + src/utils/os_win32.c | 6 ++++++ + 3 files changed, 70 insertions(+) + +--- a/src/utils/os.h ++++ b/src/utils/os.h +@@ -584,6 +584,15 @@ static inline void os_remove_in_array(vo + */ + size_t os_strlcpy(char *dest, const char *src, size_t siz); + ++/** ++ * os_exec - Execute an external program ++ * @program: Path to the program ++ * @arg: Command line argument string ++ * @wait_completion: Whether to wait until the program execution completes ++ * Returns: 0 on success, -1 on error ++ */ ++int os_exec(const char *program, const char *arg, int wait_completion); ++ + + #ifdef OS_REJECT_C_LIB_FUNCTIONS + #define malloc OS_DO_NOT_USE_malloc +--- a/src/utils/os_unix.c ++++ b/src/utils/os_unix.c +@@ -9,6 +9,7 @@ + #include "includes.h" + + #include ++#include + + #ifdef ANDROID + #include +@@ -540,3 +541,57 @@ char * os_strdup(const char *s) + } + + #endif /* WPA_TRACE */ ++ ++ ++int os_exec(const char *program, const char *arg, int wait_completion) ++{ ++ pid_t pid; ++ int pid_status; ++ ++ pid = fork(); ++ if (pid < 0) { ++ perror("fork"); ++ return -1; ++ } ++ ++ if (pid == 0) { ++ /* run the external command in the child process */ ++ const int MAX_ARG = 30; ++ char *_program, *_arg, *pos; ++ char *argv[MAX_ARG + 1]; ++ int i; ++ ++ _program = os_strdup(program); ++ _arg = os_strdup(arg); ++ ++ argv[0] = _program; ++ ++ i = 1; ++ pos = _arg; ++ while (i < MAX_ARG && pos && *pos) { ++ while (*pos == ' ') ++ pos++; ++ if (*pos == '\0') ++ break; ++ argv[i++] = pos; ++ pos = os_strchr(pos, ' '); ++ if (pos) ++ *pos++ = '\0'; ++ } ++ argv[i] = NULL; ++ ++ execv(program, argv); ++ perror("execv"); ++ os_free(_program); ++ os_free(_arg); ++ exit(0); ++ return -1; ++ } ++ ++ if (wait_completion) { ++ /* wait for the child process to complete in the parent */ ++ waitpid(pid, &pid_status, 0); ++ } ++ ++ return 0; ++} +--- a/src/utils/os_win32.c ++++ b/src/utils/os_win32.c +@@ -244,3 +244,9 @@ size_t os_strlcpy(char *dest, const char + + return s - src - 1; + } ++ ++ ++int os_exec(const char *program, const char *arg, int wait_completion) ++{ ++ return -1; ++} diff --git a/package/network/services/hostapd/patches/003-wpa_cli-Use-os_exec-for-action-script-execution.patch b/package/network/services/hostapd/patches/003-wpa_cli-Use-os_exec-for-action-script-execution.patch new file mode 100644 index 0000000000..7fe44bf907 --- /dev/null +++ b/package/network/services/hostapd/patches/003-wpa_cli-Use-os_exec-for-action-script-execution.patch @@ -0,0 +1,54 @@ +From c5f258de76dbb67fb64beab39a99e5c5711f41fe Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Mon, 6 Oct 2014 17:25:52 +0300 +Subject: [PATCH 2/3] wpa_cli: Use os_exec() for action script execution + +Use os_exec() to run the action script operations to avoid undesired +command line processing for control interface event strings. Previously, +it could have been possible for some of the event strings to include +unsanitized data which is not suitable for system() use. (CVE-2014-3686) + +Signed-off-by: Jouni Malinen +--- + wpa_supplicant/wpa_cli.c | 25 ++++++++----------------- + 1 file changed, 8 insertions(+), 17 deletions(-) + +--- a/wpa_supplicant/wpa_cli.c ++++ b/wpa_supplicant/wpa_cli.c +@@ -3149,28 +3149,19 @@ static int str_match(const char *a, cons + static int wpa_cli_exec(const char *program, const char *arg1, + const char *arg2) + { +- char *cmd; ++ char *arg; + size_t len; + int res; +- int ret = 0; + +- len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3; +- cmd = os_malloc(len); +- if (cmd == NULL) ++ len = os_strlen(arg1) + os_strlen(arg2) + 2; ++ arg = os_malloc(len); ++ if (arg == NULL) + return -1; +- res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2); +- if (res < 0 || (size_t) res >= len) { +- os_free(cmd); +- return -1; +- } +- cmd[len - 1] = '\0'; +-#ifndef _WIN32_WCE +- if (system(cmd) < 0) +- ret = -1; +-#endif /* _WIN32_WCE */ +- os_free(cmd); ++ os_snprintf(arg, len, "%s %s", arg1, arg2); ++ res = os_exec(program, arg, 1); ++ os_free(arg); + +- return ret; ++ return res; + } + + diff --git a/package/network/services/hostapd/patches/004-hostapd_cli-Use-os_exec-for-action-script-execution.patch b/package/network/services/hostapd/patches/004-hostapd_cli-Use-os_exec-for-action-script-execution.patch new file mode 100644 index 0000000000..4f08ee5175 --- /dev/null +++ b/package/network/services/hostapd/patches/004-hostapd_cli-Use-os_exec-for-action-script-execution.patch @@ -0,0 +1,54 @@ +From 5d4fa2a29bef013e61185beb21a3ec110885eb9a Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Mon, 6 Oct 2014 18:49:01 +0300 +Subject: [PATCH 3/3] hostapd_cli: Use os_exec() for action script execution + +Use os_exec() to run the action script operations to avoid undesired +command line processing for control interface event strings. Previously, +it could have been possible for some of the event strings to include +unsanitized data which is not suitable for system() use. (CVE-2014-3686) + +Signed-off-by: Jouni Malinen +--- + hostapd/hostapd_cli.c | 25 ++++++++----------------- + 1 file changed, 8 insertions(+), 17 deletions(-) + +--- a/hostapd/hostapd_cli.c ++++ b/hostapd/hostapd_cli.c +@@ -238,28 +238,19 @@ static int hostapd_cli_cmd_mib(struct wp + static int hostapd_cli_exec(const char *program, const char *arg1, + const char *arg2) + { +- char *cmd; ++ char *arg; + size_t len; + int res; +- int ret = 0; + +- len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3; +- cmd = os_malloc(len); +- if (cmd == NULL) ++ len = os_strlen(arg1) + os_strlen(arg2) + 2; ++ arg = os_malloc(len); ++ if (arg == NULL) + return -1; +- res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2); +- if (res < 0 || (size_t) res >= len) { +- os_free(cmd); +- return -1; +- } +- cmd[len - 1] = '\0'; +-#ifndef _WIN32_WCE +- if (system(cmd) < 0) +- ret = -1; +-#endif /* _WIN32_WCE */ +- os_free(cmd); ++ os_snprintf(arg, len, "%s %s", arg1, arg2); ++ res = os_exec(program, arg, 1); ++ os_free(arg); + +- return ret; ++ return res; + } + + diff --git a/package/network/services/hostapd/patches/120-daemonize_fix.patch b/package/network/services/hostapd/patches/120-daemonize_fix.patch index 20a1eb340b..032e2072a3 100644 --- a/package/network/services/hostapd/patches/120-daemonize_fix.patch +++ b/package/network/services/hostapd/patches/120-daemonize_fix.patch @@ -1,14 +1,14 @@ --- a/src/utils/os_unix.c +++ b/src/utils/os_unix.c -@@ -9,6 +9,7 @@ - #include "includes.h" +@@ -10,6 +10,7 @@ #include + #include +#include #ifdef ANDROID #include -@@ -154,59 +155,46 @@ int os_gmtime(os_time_t t, struct os_tm +@@ -155,59 +156,46 @@ int os_gmtime(os_time_t t, struct os_tm return 0; } diff --git a/package/network/services/hostapd/patches/370-ap_sta_support.patch b/package/network/services/hostapd/patches/370-ap_sta_support.patch index 8a92ead99e..4b1f2abd47 100644 --- a/package/network/services/hostapd/patches/370-ap_sta_support.patch +++ b/package/network/services/hostapd/patches/370-ap_sta_support.patch @@ -157,7 +157,7 @@ #include "drivers/driver.h" #include "wpa_supplicant_i.h" #include "config.h" -@@ -247,6 +248,10 @@ static void calculate_update_time(const +@@ -247,6 +248,10 @@ static void calculate_update_time(const static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src, struct os_reltime *fetch_time) { diff --git a/package/network/services/hostapd/patches/450-limit_debug_messages.patch b/package/network/services/hostapd/patches/450-limit_debug_messages.patch index 08f17dc012..7030ef2bc7 100644 --- a/package/network/services/hostapd/patches/450-limit_debug_messages.patch +++ b/package/network/services/hostapd/patches/450-limit_debug_messages.patch @@ -166,7 +166,7 @@ /** * wpa_hexdump_ascii_key - conditional hex dump, hide keys -@@ -142,8 +177,14 @@ void wpa_hexdump_ascii(int level, const +@@ -142,8 +177,14 @@ void wpa_hexdump_ascii(int level, const * bytes per line will be shown. This works like wpa_hexdump_ascii(), but by * default, does not include secret keys (passwords, etc.) in debug output. */ diff --git a/package/network/services/hostapd/patches/470-hostapd_cli_ifdef.patch b/package/network/services/hostapd/patches/470-hostapd_cli_ifdef.patch index d4a0f1280a..7d670919f5 100644 --- a/package/network/services/hostapd/patches/470-hostapd_cli_ifdef.patch +++ b/package/network/services/hostapd/patches/470-hostapd_cli_ifdef.patch @@ -16,7 +16,7 @@ " get_config show current configuration\n" " help show this usage help\n" " interface [ifname] show interfaces/select interface\n" -@@ -362,7 +360,6 @@ static int hostapd_cli_cmd_sa_query(stru +@@ -353,7 +351,6 @@ static int hostapd_cli_cmd_sa_query(stru #endif /* CONFIG_IEEE80211W */ @@ -24,7 +24,7 @@ static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) { -@@ -588,7 +585,6 @@ static int hostapd_cli_cmd_wps_config(st +@@ -579,7 +576,6 @@ static int hostapd_cli_cmd_wps_config(st ssid_hex, argv[1]); return wpa_ctrl_command(ctrl, buf); } @@ -32,7 +32,7 @@ static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc, -@@ -979,7 +975,6 @@ static struct hostapd_cli_cmd hostapd_cl +@@ -970,7 +966,6 @@ static struct hostapd_cli_cmd hostapd_cl #ifdef CONFIG_IEEE80211W { "sa_query", hostapd_cli_cmd_sa_query }, #endif /* CONFIG_IEEE80211W */ @@ -40,7 +40,7 @@ { "wps_pin", hostapd_cli_cmd_wps_pin }, { "wps_check_pin", hostapd_cli_cmd_wps_check_pin }, { "wps_pbc", hostapd_cli_cmd_wps_pbc }, -@@ -993,7 +988,6 @@ static struct hostapd_cli_cmd hostapd_cl +@@ -984,7 +979,6 @@ static struct hostapd_cli_cmd hostapd_cl { "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin }, { "wps_config", hostapd_cli_cmd_wps_config }, { "wps_get_status", hostapd_cli_cmd_wps_get_status }, diff --git a/package/network/services/hostapd/patches/490-scan_wait.patch b/package/network/services/hostapd/patches/490-scan_wait.patch index 3459a61de8..2c0f284567 100644 --- a/package/network/services/hostapd/patches/490-scan_wait.patch +++ b/package/network/services/hostapd/patches/490-scan_wait.patch @@ -33,7 +33,7 @@ /* Initialize the driver interface */ if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5])) b = NULL; -@@ -372,8 +384,6 @@ static void hostapd_global_deinit(const +@@ -372,8 +384,6 @@ static void hostapd_global_deinit(const #endif /* CONFIG_NATIVE_WINDOWS */ eap_server_unregister_methods(); -- 2.30.2