]> review.fuel-infra Code Review - packages/trusty/mysql-wsrep-5.6.git/commitdiff
Fix CVE-2016-6662 72/26772/1
authorAnton Chevychalov <achevychalov@mirantis.com>
Thu, 22 Sep 2016 14:16:17 +0000 (17:16 +0300)
committerAnton Chevychalov <achevychalov@mirantis.com>
Thu, 22 Sep 2016 14:21:00 +0000 (17:21 +0300)
Fix CVE-2016-6662 using debian patch.

Change-Id: I6e362b1f1512bc64ddb37fc4d0e8c3bcde453146
Closes-Bug: #1622767

debian/changelog
debian/patches/debian_patches_CVE-2016-6662.patch [new file with mode: 0644]
debian/patches/series

index e86798b7bb480ffb92c3eac1cb7c4ad8022f4f32..12180b5c6680fd42407609cec88dd0ebe5452050 100644 (file)
@@ -1,3 +1,10 @@
+mysql-wsrep-5.6 (5.6.30-0~u14.04+mos2) mos; urgency=high
+
+  * SECURITY UPDATE: Fix CVE-2016-6662
+    - https://security-tracker.debian.org/tracker/CVE-2016-6662
+
+ -- Anton Chevychalov <mos-maintanance@mirantis.com>  Thu, 22 Sep 2016 17:01:53 +0300
+
 mysql-wsrep-5.6 (5.6.30-0~u14.04+mos1) mos; urgency=high
 
   * SECURITY UPDATE: Update to 5.6.30 to fix security issues (LP: #1572559)
diff --git a/debian/patches/debian_patches_CVE-2016-6662.patch b/debian/patches/debian_patches_CVE-2016-6662.patch
new file mode 100644 (file)
index 0000000..dba4f7d
--- /dev/null
@@ -0,0 +1,403 @@
+--- a/scripts/mysqld_safe.sh
++++ b/scripts/mysqld_safe.sh
+@@ -281,8 +281,17 @@
+       --core-file-size=*) core_file_size="$val" ;;
+       --ledir=*) ledir="$val" ;;
+       --malloc-lib=*) set_malloc_lib "$val" ;;
+-      --mysqld=*) MYSQLD="$val" ;;
++      --mysqld=*)
++        if [ -z "$pick_args" ]; then
++          log_error "--mysqld option can only be used as command line option, found in config file"
++          exit 1
++        fi
++        MYSQLD="$val" ;;
+       --mysqld-version=*)
++        if [ -z "$pick_args" ]; then
++          log_error "--mysqld-version option can only be used as command line option, found in config file"
++          exit 1
++        fi
+         if test -n "$val"
+         then
+           MYSQLD="mysqld-$val"
+@@ -377,37 +386,23 @@
+ }
+-mysql_config=
+-get_mysql_config() {
+-  if [ -z "$mysql_config" ]; then
+-    mysql_config=`echo "$0" | sed 's,/[^/][^/]*$,/mysql_config,'`
+-    if [ ! -x "$mysql_config" ]; then
+-      log_error "Can not run mysql_config $@ from '$mysql_config'"
+-      exit 1
+-    fi
+-  fi
+-
+-  "$mysql_config" "$@"
+-}
+-
+-
+ # set_malloc_lib LIB
+ # - If LIB is empty, do nothing and return
+-# - If LIB is 'tcmalloc', look for tcmalloc shared library in /usr/lib
+-#   then pkglibdir.  tcmalloc is part of the Google perftools project.
++# - If LIB is 'tcmalloc', look for tcmalloc shared library in $malloc_dirs.
++#   tcmalloc is part of the Google perftools project.
+ # - If LIB is an absolute path, assume it is a malloc shared library
+ #
+ # Put LIB in mysqld_ld_preload, which will be added to LD_PRELOAD when
+ # running mysqld.  See ld.so for details.
+ set_malloc_lib() {
++  # This list is kept intentionally simple.
++  malloc_dirs="/usr/lib /usr/lib64 /usr/lib/i386-linux-gnu /usr/lib/x86_64-linux-gnu"
+   malloc_lib="$1"
+   if [ "$malloc_lib" = tcmalloc ]; then
+     pkglibdir=`get_mysql_config --variable=pkglibdir`
+     malloc_lib=
+-    # This list is kept intentionally simple.  Simply set --malloc-lib
+-    # to a full path if another location is desired.
+-    for libdir in /usr/lib "$pkglibdir" "$pkglibdir/mysql"; do
++    for libdir in `echo $malloc_dirs`; do
+       for flavor in _minimal '' _and_profiler _debug; do
+         tmp="$libdir/libtcmalloc$flavor.so"
+         #log_notice "DEBUG: Checking for malloc lib '$tmp'"
+@@ -418,7 +413,7 @@
+     done
+     if [ -z "$malloc_lib" ]; then
+-      log_error "no shared library for --malloc-lib=tcmalloc found in /usr/lib or $pkglibdir"
++      log_error "no shared library for --malloc-lib=tcmalloc found in $malloc_dirs"
+       exit 1
+     fi
+   fi
+@@ -429,9 +424,21 @@
+   case "$malloc_lib" in
+     /*)
+       if [ ! -r "$malloc_lib" ]; then
+-        log_error "--malloc-lib '$malloc_lib' can not be read and will not be used"
++        log_error "--malloc-lib can not be read and will not be used"
+         exit 1
+       fi
++
++      # Restrict to a the list in $malloc_dirs above
++      case "`dirname "$malloc_lib"`" in
++        /usr/lib) ;;
++        /usr/lib64) ;;
++        /usr/lib/i386-linux-gnu) ;;
++        /usr/lib/x86_64-linux-gnu) ;;
++        *)
++          log_error "--malloc-lib must be located in one of the directories: $malloc_dirs"
++          exit 1
++          ;;
++      esac
+       ;;
+     *)
+       log_error "--malloc-lib must be an absolute path or 'tcmalloc'; " \
+@@ -647,7 +654,7 @@
+   log_notice "Logging to '$err_log'."
+   logging=file
+-  if [ ! -f "$err_log" ]; then                  # if error log already exists,
++  if [ ! -f "$err_log" -a ! -h "$err_log" ]; then # if error log already exists,
+     touch "$err_log"                            # we just append. otherwise,
+     chmod "$fmode" "$err_log"                   # fix the permissions here!
+   fi
+@@ -672,7 +679,7 @@
+     USER_OPTION="--user=$user"
+   fi
+   # Change the err log to the right user, if it is in use
+-  if [ $want_syslog -eq 0 ]; then
++  if [ $want_syslog -eq 0 -a ! -h "$err_log" ]; then
+     touch "$err_log"
+     chown $user "$err_log"
+   fi
+@@ -692,9 +699,11 @@
+ mysql_unix_port_dir=`dirname $safe_mysql_unix_port`
+ if [ ! -d $mysql_unix_port_dir ]
+ then
+-  mkdir $mysql_unix_port_dir
+-  chown $user $mysql_unix_port_dir
+-  chmod 755 $mysql_unix_port_dir
++  if [ ! -h $mysql_unix_port_dir ]; then
++    mkdir $mysql_unix_port_dir
++    chown $user $mysql_unix_port_dir
++    chmod 755 $mysql_unix_port_dir
++  fi
+ fi
+ # If the user doesn't specify a binary, we assume name "mysqld"
+@@ -806,7 +815,9 @@
+       exit 1
+     fi
+   fi
+-  rm -f "$pid_file"
++  if [ ! -h "$pid_file" ]; then
++    rm -f "$pid_file"
++  fi
+   if test -f "$pid_file"
+   then
+     log_error "Fatal error: Can't remove the pid file:
+@@ -861,7 +872,13 @@
+ while true
+ do
+-  rm -f $safe_mysql_unix_port "$pid_file"     # Some extra safety
++  # Some extra safety
++  if [ ! -h "$safe_mysql_unix_port" ]; then
++    rm -f "$safe_mysql_unix_port"
++  fi
++  if [ ! -h "$pid_file" ]; then
++    rm -f "$pid_file"
++  fi
+   start_time=`date +%M%S`
+@@ -879,7 +896,7 @@
+     eval_log_error "$cmd $wsrep_start_position_opt --wsrep_cluster_address=$url $nohup_redir"
+   fi
+-  if [ $want_syslog -eq 0 -a ! -f "$err_log" ]; then
++  if [ $want_syslog -eq 0 -a ! -f "$err_log" -a ! -h "$err_log" ]; then
+     touch "$err_log"                    # hypothetical: log was renamed but not
+     chown $user "$err_log"              # flushed yet. we'd recreate it with
+     chmod "$fmode" "$err_log"           # wrong owner next time we log, so set
+--- a/sql/log.cc
++++ b/sql/log.cc
+@@ -1,4 +1,4 @@
+-/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
++/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+@@ -1496,6 +1496,78 @@
+ }
++bool is_valid_log_name(const char *name, size_t len)
++{
++  if (len > 3)
++  {
++    const char *tail= name + len - 4;
++    if (my_strcasecmp(system_charset_info, tail, ".ini") == 0 ||
++        my_strcasecmp(system_charset_info, tail, ".cnf") == 0)
++    {
++      return false;
++    }
++  }
++  return true;
++}
++
++
++/**
++  Get the real log file name, and possibly reopen file.
++
++  Use realpath() to get the path with symbolic links
++  expanded. Then, close the file, and reopen the real path using the
++  O_NOFOLLOW flag. This will reject following symbolic links.
++
++  @param          file                  File descriptor.
++  @param          log_file_key          Key for P_S instrumentation.
++  @param          open_flags            Flags to use for opening the file.
++  @param          opened_file_name      Name of the open fd.
++
++  @retval file descriptor to open file with 'real_file_name', or '-1'
++          in case of errors.
++*/
++
++#ifndef _WIN32
++static File mysql_file_real_name_reopen(File file,
++#ifdef HAVE_PSI_INTERFACE
++                                        PSI_file_key log_file_key,
++#endif
++                                        int open_flags,
++                                        const char *opened_file_name)
++{
++  DBUG_ASSERT(file);
++  DBUG_ASSERT(opened_file_name);
++
++  /* Buffer for realpath must have capacity for PATH_MAX. */
++  char real_file_name[PATH_MAX];
++
++  /* Get realpath, validate, open realpath with O_NOFOLLOW. */
++  if (realpath(opened_file_name, real_file_name) == NULL)
++  {
++    (void) mysql_file_close(file, MYF(0));
++    return -1;
++  }
++
++  if (mysql_file_close(file, MYF(0)))
++    return -1;
++
++  if (strlen(real_file_name) > FN_REFLEN)
++    return -1;
++
++  if (!is_valid_log_name(real_file_name, strlen(real_file_name)))
++  {
++    sql_print_error("Invalid log file name after expanding symlinks: '%s'",
++                    real_file_name);
++    return -1;
++  }
++
++  return mysql_file_open(log_file_key, real_file_name,
++                         open_flags | O_NOFOLLOW,
++                         MYF(MY_WME | ME_WAITTANG));
++}
++#endif // _WIN32
++
++
+ /*
+   Open a (new) log file.
+@@ -1566,6 +1638,18 @@
+                              MYF(MY_WME | ME_WAITTANG))) < 0)
+     goto err;
++#ifndef _WIN32
++  /* Reopen and validate path. */
++  if ((log_type_arg == LOG_UNKNOWN || log_type_arg == LOG_NORMAL) &&
++      (file= mysql_file_real_name_reopen(file,
++#ifdef HAVE_PSI_INTERFACE
++                                         log_file_key,
++#endif
++                                         open_flags,
++                                         log_file_name)) < 0)
++    goto err;
++#endif // _WIN32
++
+   if ((pos= mysql_file_tell(file, MYF(MY_WME))) == MY_FILEPOS_ERROR)
+   {
+     if (my_errno == ESPIPE)
+--- a/sql/log.h
++++ b/sql/log.h
+@@ -610,6 +610,16 @@
+ char *make_log_name(char *buff, const char *name, const char* log_ext);
++/**
++  Check given log name against certain blacklisted names/extensions.
++
++  @param name     Log name to check
++  @param len      Length of log name
++
++  @returns true if name is valid, false otherwise.
++*/
++bool is_valid_log_name(const char *name, size_t len);
++
+ extern LOGGER logger;
+ #endif /* LOG_H */
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -4225,11 +4225,22 @@
+                       "--general-log-file option, log tables are used. "
+                       "To enable logging to files use the --log-output=file option.");
+-  if (opt_slow_log && opt_slow_logname && !(log_output_options & LOG_FILE)
+-      && !(log_output_options & LOG_NONE))
+-    sql_print_warning("Although a path was specified for the "
+-                      "--slow-query-log-file option, log tables are used. "
+-                      "To enable logging to files use the --log-output=file option.");
++  if (opt_logname &&
++      !is_valid_log_name(opt_logname, strlen(opt_logname)))
++  {
++    sql_print_error("Invalid value for --general_log_file: %s",
++                    opt_logname);
++    return 1;
++  }
++
++  if (opt_slow_logname &&
++      !is_valid_log_name(opt_slow_logname, strlen(opt_slow_logname)))
++  {
++    sql_print_error("Invalid value for --slow_query_log_file: %s",
++                    opt_slow_logname);
++    return 1;
++  }
++
+   if (!opt_logname || !*opt_logname)
+     opt_logname= make_default_log_name(logname_path, ".log");
+--- a/sql/sys_vars.cc
++++ b/sql/sys_vars.cc
+@@ -3686,6 +3686,14 @@
+   if (!var->save_result.string_value.str)
+     return true;
++  if (!is_valid_log_name(var->save_result.string_value.str,
++                         var->save_result.string_value.length))
++  {
++    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0),
++             self->name.str, var->save_result.string_value.str);
++    return true;
++  }
++
+   if (var->save_result.string_value.length > FN_REFLEN)
+   { // path is too long
+     my_error(ER_PATH_LENGTH, MYF(0), self->name.str);
+@@ -3732,7 +3740,7 @@
+   return false;
+ }
+ static bool fix_log(char** logname, const char* default_logname,
+-                    const char*ext, bool enabled, void (*reopen)(char*))
++                    const char*ext, bool enabled, bool (*reopen)(char*))
+ {
+   if (!*logname) // SET ... = DEFAULT
+   {
+@@ -3744,16 +3752,17 @@
+   }
+   logger.lock_exclusive();
+   mysql_mutex_unlock(&LOCK_global_system_variables);
++  bool error= false;
+   if (enabled)
+-    reopen(*logname);
++    error= reopen(*logname);
+   logger.unlock();
+   mysql_mutex_lock(&LOCK_global_system_variables);
+-  return false;
++  return error;
+ }
+-static void reopen_general_log(char* name)
++static bool reopen_general_log(char* name)
+ {
+   logger.get_log_file_handler()->close(0);
+-  logger.get_log_file_handler()->open_query_log(name);
++  return logger.get_log_file_handler()->open_query_log(name);
+ }
+ static bool fix_general_log_file(sys_var *self, THD *thd, enum_var_type type)
+ {
+@@ -3766,10 +3775,10 @@
+        IN_FS_CHARSET, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+        ON_CHECK(check_log_path), ON_UPDATE(fix_general_log_file));
+-static void reopen_slow_log(char* name)
++static bool reopen_slow_log(char* name)
+ {
+   logger.get_slow_log_file_handler()->close(0);
+-  logger.get_slow_log_file_handler()->open_slow_log(name);
++  return logger.get_slow_log_file_handler()->open_slow_log(name);
+ }
+ static bool fix_slow_log_file(sys_var *self, THD *thd, enum_var_type type)
+ {
+--- a/support-files/mysql.server.sh
++++ b/support-files/mysql.server.sh
+@@ -255,11 +255,6 @@
+ if test -r "$basedir/my.cnf"
+ then
+   extra_args="-e $basedir/my.cnf"
+-else
+-  if test -r "$datadir/my.cnf"
+-  then
+-    extra_args="-e $datadir/my.cnf"
+-  fi
+ fi
+ parse_server_arguments `$print_defaults $extra_args mysqld server mysql_server mysql.server`
+@@ -289,7 +284,7 @@
+     then
+       # Give extra arguments to mysqld with the my.cnf file. This script
+       # may be overwritten at next upgrade.
+-      $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null 2>&1 &
++      $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null &
+       wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$?
+       # Make lock for RedHat / SuSE
index c92237ffac8888d3283c8ebc30ca0a266628d8de..164bca36e4bc1bc8bf0a935569726695ef899146 100644 (file)
@@ -3,3 +3,4 @@ scripts__mysqld_safe.sh__signals.patch
 fix_standalone_tests.patch
 kfreebsd_tests.patch
 fix-mysqlhotcopy-test-failure.patch
+debian_patches_CVE-2016-6662.patch