From 242345d61dfd1546a4371d3ddabdf1cb7baa69c2 Mon Sep 17 00:00:00 2001 From: Sunil Kumar Date: Tue, 28 Mar 2017 13:23:31 +0530 Subject: mariadb: Security fix for CVE-2016-6664 Source: https://github.com/MariaDB/server.git MR: 69290 Type: Security Fix Disposition: Backport from mariadb-5.5.54~4 ChangeID: 8fcdd6b0ecbb966f4479856efe93a963a7a422f7 Description: CVE-2016-6664 Signed-off-by: Sunil Kumar Reviewed-by: Armin Kuster Signed-off-by: Armin Kuster Signed-off-by: Armin Kuster --- .../mysql/mariadb/CVE-2016-6664_p1.patch | 277 +++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 meta-oe/recipes-support/mysql/mariadb/CVE-2016-6664_p1.patch (limited to 'meta-oe/recipes-support/mysql/mariadb/CVE-2016-6664_p1.patch') diff --git a/meta-oe/recipes-support/mysql/mariadb/CVE-2016-6664_p1.patch b/meta-oe/recipes-support/mysql/mariadb/CVE-2016-6664_p1.patch new file mode 100644 index 0000000000..e8b0a84ce9 --- /dev/null +++ b/meta-oe/recipes-support/mysql/mariadb/CVE-2016-6664_p1.patch @@ -0,0 +1,277 @@ +From af4f1bd59b38e3172b882107c49b8612537f4f4f Mon Sep 17 00:00:00 2001 +From: Sergei Golubchik +Date: Tue, 20 Dec 2016 15:17:59 +0100 +Subject: [PATCH 1/3] move check_user/set_user from mysqld.cc to mysys + +Upstream-Status: Backport + +CVE: CVE-2016-6664 patch#1 + +Signed-off-by: Sunil Kumar +--- + include/my_sys.h | 4 +++ + mysys/CMakeLists.txt | 4 +-- + mysys/my_setuser.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++ + sql/mysqld.cc | 83 +++++++--------------------------------------------- + 4 files changed, 98 insertions(+), 74 deletions(-) + create mode 100644 mysys/my_setuser.c + +diff --git a/include/my_sys.h b/include/my_sys.h +index 7e37fe598bd..756a40c72f6 100644 +--- a/include/my_sys.h ++++ b/include/my_sys.h +@@ -602,8 +602,12 @@ extern void *my_memmem(const void *haystack, size_t haystacklen, + + #ifdef _WIN32 + extern int my_access(const char *path, int amode); ++#define my_check_user(A,B) (NULL) ++#define my_set_user(A,B,C) (0) + #else + #define my_access access ++struct passwd *my_check_user(const char *user, myf MyFlags); ++int my_set_user(const char *user, struct passwd *user_info, myf MyFlags); + #endif + + extern int check_if_legal_filename(const char *path); +diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt +index 06a811f0994..cb86850c2de 100644 +--- a/mysys/CMakeLists.txt ++++ b/mysys/CMakeLists.txt +@@ -34,7 +34,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c + rijndael.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c + thr_rwlock.c tree.c typelib.c base64.c my_memmem.c my_getpagesize.c + lf_alloc-pin.c lf_dynarray.c lf_hash.c +- safemalloc.c my_new.cc ++ safemalloc.c my_new.cc + my_atomic.c my_getncpus.c my_safehash.c my_chmod.c my_rnd.c + my_uuid.c wqueue.c waiting_threads.c ma_dyncol.c + my_rdtsc.c my_context.c file_logger.c) +@@ -44,7 +44,7 @@ IF (WIN32) + ENDIF() + + IF(UNIX) +- SET (MYSYS_SOURCES ${MYSYS_SOURCES} my_addr_resolve.c) ++ SET (MYSYS_SOURCES ${MYSYS_SOURCES} my_addr_resolve.c my_setuser.c) + ENDIF() + + IF(HAVE_ALARM) +diff --git a/mysys/my_setuser.c b/mysys/my_setuser.c +new file mode 100644 +index 00000000000..1f3e7770d4c +--- /dev/null ++++ b/mysys/my_setuser.c +@@ -0,0 +1,81 @@ ++#include ++#include ++#include ++#include ++#ifdef HAVE_PWD_H ++#include ++#endif ++#ifdef HAVE_GRP_H ++#include ++#endif ++ ++struct passwd *my_check_user(const char *user, myf MyFlags) ++{ ++ struct passwd *user_info; ++ uid_t user_id= geteuid(); ++ DBUG_ENTER("my_check_user"); ++ ++ // Don't bother if we aren't superuser ++ if (user_id) ++ { ++ if (user) ++ { ++ /* Don't give a warning, if real user is same as given with --user */ ++ user_info= getpwnam(user); ++ if (!user_info || user_id != user_info->pw_uid) ++ { ++ my_errno= EPERM; ++ if (MyFlags & MY_WME) ++ my_printf_error(my_errno, "One can only use the --user switch if " ++ "running as root", MYF(ME_JUST_WARNING|ME_NOREFRESH)); ++ } ++ } ++ DBUG_RETURN(NULL); ++ } ++ if (!user) ++ { ++ if (MyFlags & MY_FAE) ++ { ++ my_errno= EINVAL; ++ my_printf_error(my_errno, "Please consult the Knowledge Base to find " ++ "out how to run mysqld as root!", MYF(ME_NOREFRESH)); ++ } ++ DBUG_RETURN(NULL); ++ } ++ if (!strcmp(user,"root")) ++ DBUG_RETURN(NULL); ++ ++ if (!(user_info= getpwnam(user))) ++ { ++ // Allow a numeric uid to be used ++ int err= 0; ++ user_id= my_strtoll10(user, NULL, &err); ++ if (err || !(user_info= getpwuid(user_id))) ++ { ++ my_errno= EINVAL; ++ my_printf_error(my_errno, "Can't change to run as user '%s'. Please " ++ "check that the user exists!", MYF(ME_NOREFRESH), user); ++ DBUG_RETURN(NULL); ++ } ++ } ++ DBUG_ASSERT(user_info); ++ DBUG_RETURN(user_info); ++} ++ ++int my_set_user(const char *user, struct passwd *user_info, myf MyFlags) ++{ ++ DBUG_ENTER("my_set_user"); ++ ++ DBUG_ASSERT(user_info != 0); ++#ifdef HAVE_INITGROUPS ++ initgroups(user, user_info->pw_gid); ++#endif ++ if (setgid(user_info->pw_gid) == -1 || setuid(user_info->pw_uid) == -1) ++ { ++ my_errno= errno; ++ if (MyFlags & MY_WME) ++ my_error(my_errno, MYF(ME_NOREFRESH)); ++ DBUG_RETURN(my_errno); ++ } ++ DBUG_RETURN(0); ++} +diff --git a/sql/mysqld.cc b/sql/mysqld.cc +index 3ad7b84829d..dd961ec20f0 100644 +--- a/sql/mysqld.cc ++++ b/sql/mysqld.cc +@@ -121,10 +121,7 @@ extern "C" { // Because of SCO 3.2V4.2 + #include + #endif + #ifdef HAVE_PWD_H +-#include // For getpwent +-#endif +-#ifdef HAVE_GRP_H +-#include ++#include // For struct passwd + #endif + #include + +@@ -455,9 +452,7 @@ ulong opt_binlog_rows_event_max_size; + my_bool opt_master_verify_checksum= 0; + my_bool opt_slave_sql_verify_checksum= 1; + const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS}; +-#ifdef HAVE_INITGROUPS + volatile sig_atomic_t calling_initgroups= 0; /**< Used in SIGSEGV handler. */ +-#endif + uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options; + uint mysqld_extra_port; + uint mysqld_port_timeout; +@@ -2007,59 +2002,18 @@ static void set_ports() + + static struct passwd *check_user(const char *user) + { +-#if !defined(__WIN__) +- struct passwd *tmp_user_info; +- uid_t user_id= geteuid(); ++ myf flags= 0; ++ if (global_system_variables.log_warnings) ++ flags|= MY_WME; ++ if (!opt_bootstrap && !opt_help) ++ flags|= MY_FAE; + +- // Don't bother if we aren't superuser +- if (user_id) +- { +- if (user) +- { +- /* Don't give a warning, if real user is same as given with --user */ +- /* purecov: begin tested */ +- tmp_user_info= getpwnam(user); +- if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) && +- global_system_variables.log_warnings) +- sql_print_warning( +- "One can only use the --user switch if running as root\n"); +- /* purecov: end */ +- } +- return NULL; +- } +- if (!user) +- { +- if (!opt_bootstrap && !opt_help) +- { +- sql_print_error("Fatal error: Please consult the Knowledge Base " +- "to find out how to run mysqld as root!\n"); +- unireg_abort(1); +- } +- return NULL; +- } +- /* purecov: begin tested */ +- if (!strcmp(user,"root")) +- return NULL; // Avoid problem with dynamic libraries ++ struct passwd *tmp_user_info= my_check_user(user, MYF(flags)); + +- if (!(tmp_user_info= getpwnam(user))) +- { +- // Allow a numeric uid to be used +- const char *pos; +- for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ; +- if (*pos) // Not numeric id +- goto err; +- if (!(tmp_user_info= getpwuid(atoi(user)))) +- goto err; +- } ++ if (!tmp_user_info && my_errno==EINVAL && (flags & MY_FAE)) ++ unireg_abort(1); + + return tmp_user_info; +- /* purecov: end */ +- +-err: +- sql_print_error("Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user); +- unireg_abort(1); +-#endif +- return NULL; + } + + static inline void allow_coredumps() +@@ -2076,10 +2030,6 @@ static inline void allow_coredumps() + + static void set_user(const char *user, struct passwd *user_info_arg) + { +- /* purecov: begin tested */ +-#if !defined(__WIN__) +- DBUG_ASSERT(user_info_arg != 0); +-#ifdef HAVE_INITGROUPS + /* + We can get a SIGSEGV when calling initgroups() on some systems when NSS + is configured to use LDAP and the server is statically linked. We set +@@ -2087,22 +2037,11 @@ static void set_user(const char *user, struct passwd *user_info_arg) + output a specific message to help the user resolve this problem. + */ + calling_initgroups= 1; +- initgroups((char*) user, user_info_arg->pw_gid); ++ int res= my_set_user(user, user_info_arg, MYF(MY_WME)); + calling_initgroups= 0; +-#endif +- if (setgid(user_info_arg->pw_gid) == -1) +- { +- sql_perror("setgid"); +- unireg_abort(1); +- } +- if (setuid(user_info_arg->pw_uid) == -1) +- { +- sql_perror("setuid"); ++ if (res) + unireg_abort(1); +- } + allow_coredumps(); +-#endif +- /* purecov: end */ + } + + +-- +2.11.1 + -- cgit 1.2.3-korg