hostapd: CVE-2014-3686 fixes
authorSteven Barth <cyrus@openwrt.org>
Fri, 17 Oct 2014 06:16:07 +0000 (06:16 +0000)
committerSteven Barth <cyrus@openwrt.org>
Fri, 17 Oct 2014 06:16:07 +0000 (06:16 +0000)
Signed-off-by: Steven Barth <steven@midlink.org>
SVN-Revision: 42943

package/network/services/hostapd/Makefile
package/network/services/hostapd/patches/002-Add-os_exec-helper-to-run-external-programs.patch [new file with mode: 0644]
package/network/services/hostapd/patches/003-wpa_cli-Use-os_exec-for-action-script-execution.patch [new file with mode: 0644]
package/network/services/hostapd/patches/004-hostapd_cli-Use-os_exec-for-action-script-execution.patch [new file with mode: 0644]
package/network/services/hostapd/patches/120-daemonize_fix.patch
package/network/services/hostapd/patches/370-ap_sta_support.patch
package/network/services/hostapd/patches/450-limit_debug_messages.patch
package/network/services/hostapd/patches/470-hostapd_cli_ifdef.patch
package/network/services/hostapd/patches/490-scan_wait.patch

index f8c76cae12150a7b9cff0450d2d6c437c86271af..7237c654f7e92e604432bf94428776f0803f4704 100644 (file)
@@ -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 (file)
index 0000000..c1db046
--- /dev/null
@@ -0,0 +1,110 @@
+From 89de07a9442072f88d49869d8ecd8d42bae050a0 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni@qca.qualcomm.com>
+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 <jouni@qca.qualcomm.com>
+---
+ 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 <time.h>
++#include <sys/wait.h>
+ #ifdef ANDROID
+ #include <sys/capability.h>
+@@ -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 (file)
index 0000000..7fe44bf
--- /dev/null
@@ -0,0 +1,54 @@
+From c5f258de76dbb67fb64beab39a99e5c5711f41fe Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni@qca.qualcomm.com>
+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 <jouni@qca.qualcomm.com>
+---
+ 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 (file)
index 0000000..4f08ee5
--- /dev/null
@@ -0,0 +1,54 @@
+From 5d4fa2a29bef013e61185beb21a3ec110885eb9a Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni@qca.qualcomm.com>
+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 <jouni@qca.qualcomm.com>
+---
+ 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;
+ }
index 20a1eb340b658f50623bec3beb4d2cb866edceca..032e2072a35770628f96831ab3b6c4bbebdb7cf2 100644 (file)
@@ -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 <time.h>
+ #include <sys/wait.h>
 +#include <fcntl.h>
  
  #ifdef ANDROID
  #include <sys/capability.h>
-@@ -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;
  }
  
index 8a92ead99e784bc6923909b5c719f473aab3d228..4b1f2abd47002e18d4aa26cb7231af362225d9dd 100644 (file)
  #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)
  {
index 08f17dc01240eeb5d50ccebb77672d8af5f699df..7030ef2bc722218a29945dcd01c3cfd6dbebd236 100644 (file)
  
  /**
   * 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.
   */
index d4a0f1280a57f02d2d0151d1a95447187f968614..7d670919f5578ab43163f21da8cac38fdeb974da 100644 (file)
@@ -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 },
index 3459a61de8373dacfd4301ed2f52ba37c9377bdf..2c0f284567e614531ec29b6181df92bb84cb83c7 100644 (file)
@@ -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();