Commit 684a165f authored by Terje Rosten's avatar Terje Rosten Committed by Nawaz Nazeer Ahamed

Bug#24464380 PRIVILEGE ESCALATION USING MYSQLD_SAFE

Argument to malloc-lib must be included in restricted list of
directories, symlink guards added, and mysqld and mysqld-version
options restricted to command line only. Don't redirect errors to
stderr.
parent 22eec689
...@@ -102,7 +102,7 @@ start(){ ...@@ -102,7 +102,7 @@ start(){
# alarms, per bug #547485 # alarms, per bug #547485
$exec --datadir="$datadir" --socket="$socketfile" \ $exec --datadir="$datadir" --socket="$socketfile" \
--pid-file="$mypidfile" \ --pid-file="$mypidfile" \
--basedir=/usr --user=mysql >/dev/null 2>&1 & --basedir=/usr --user=mysql >/dev/null &
safe_pid=$! safe_pid=$!
# Spin for a maximum of N seconds waiting for the server to come up; # Spin for a maximum of N seconds waiting for the server to come up;
# exit the loop immediately if mysqld_safe process disappears. # exit the loop immediately if mysqld_safe process disappears.
......
...@@ -137,7 +137,7 @@ start () { ...@@ -137,7 +137,7 @@ start () {
rc_failed 6 ; rc_status -v ; rc_exit rc_failed 6 ; rc_status -v ; rc_exit
fi fi
$PROG --basedir=/usr --datadir="$datadir" --pid-file="$pidfile" >/dev/null 2>&1 & $PROG --basedir=/usr --datadir="$datadir" --pid-file="$pidfile" >/dev/null &
if pinger $! ; then if pinger $! ; then
echo -n "Starting service MySQL:" echo -n "Starting service MySQL:"
touch $lockfile touch $lockfile
......
...@@ -208,8 +208,17 @@ parse_arguments() { ...@@ -208,8 +208,17 @@ parse_arguments() {
--core-file-size=*) core_file_size="$val" ;; --core-file-size=*) core_file_size="$val" ;;
--ledir=*) ledir="$val" ;; --ledir=*) ledir="$val" ;;
--malloc-lib=*) set_malloc_lib "$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=*) --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" if test -n "$val"
then then
MYSQLD="mysqld-$val" MYSQLD="mysqld-$val"
...@@ -297,38 +306,22 @@ mysqld_ld_preload_text() { ...@@ -297,38 +306,22 @@ mysqld_ld_preload_text() {
echo "$text" echo "$text"
} }
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 # set_malloc_lib LIB
# - If LIB is empty, do nothing and return # - If LIB is empty, do nothing and return
# - If LIB is 'tcmalloc', look for tcmalloc shared library in /usr/lib # - If LIB is 'tcmalloc', look for tcmalloc shared library in $malloc_dirs.
# then pkglibdir. tcmalloc is part of the Google perftools project. # tcmalloc is part of the Google perftools project.
# - If LIB is an absolute path, assume it is a malloc shared library # - 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 # Put LIB in mysqld_ld_preload, which will be added to LD_PRELOAD when
# running mysqld. See ld.so for details. # running mysqld. See ld.so for details.
set_malloc_lib() { 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" malloc_lib="$1"
if [ "$malloc_lib" = tcmalloc ]; then if [ "$malloc_lib" = tcmalloc ]; then
pkglibdir=`get_mysql_config --variable=pkglibdir`
malloc_lib= malloc_lib=
# This list is kept intentionally simple. Simply set --malloc-lib for libdir in $(echo $malloc_dirs); do
# to a full path if another location is desired.
for libdir in /usr/lib "$pkglibdir" "$pkglibdir/mysql"; do
for flavor in _minimal '' _and_profiler _debug; do for flavor in _minimal '' _and_profiler _debug; do
tmp="$libdir/libtcmalloc$flavor.so" tmp="$libdir/libtcmalloc$flavor.so"
#log_notice "DEBUG: Checking for malloc lib '$tmp'" #log_notice "DEBUG: Checking for malloc lib '$tmp'"
...@@ -339,7 +332,7 @@ set_malloc_lib() { ...@@ -339,7 +332,7 @@ set_malloc_lib() {
done done
if [ -z "$malloc_lib" ]; then 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 exit 1
fi fi
fi fi
...@@ -350,9 +343,21 @@ set_malloc_lib() { ...@@ -350,9 +343,21 @@ set_malloc_lib() {
case "$malloc_lib" in case "$malloc_lib" in
/*) /*)
if [ ! -r "$malloc_lib" ]; then 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 exit 1
fi 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'; " \ log_error "--malloc-lib must be an absolute path or 'tcmalloc'; " \
...@@ -569,7 +574,7 @@ then ...@@ -569,7 +574,7 @@ then
log_notice "Logging to '$err_log'." log_notice "Logging to '$err_log'."
logging=file 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, touch "$err_log" # we just append. otherwise,
chmod "$fmode" "$err_log" # fix the permissions here! chmod "$fmode" "$err_log" # fix the permissions here!
fi fi
...@@ -594,7 +599,7 @@ then ...@@ -594,7 +599,7 @@ then
USER_OPTION="--user=$user" USER_OPTION="--user=$user"
fi fi
# Change the err log to the right user, if it is in use # 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" touch "$err_log"
chown $user "$err_log" chown $user "$err_log"
fi fi
...@@ -614,9 +619,11 @@ safe_mysql_unix_port=${mysql_unix_port:-${MYSQL_UNIX_PORT:-@MYSQL_UNIX_ADDR@}} ...@@ -614,9 +619,11 @@ safe_mysql_unix_port=${mysql_unix_port:-${MYSQL_UNIX_PORT:-@MYSQL_UNIX_ADDR@}}
mysql_unix_port_dir=`dirname $safe_mysql_unix_port` mysql_unix_port_dir=`dirname $safe_mysql_unix_port`
if [ ! -d $mysql_unix_port_dir ] if [ ! -d $mysql_unix_port_dir ]
then then
if [ ! -h $mysql_unix_port_dir ]; then
mkdir $mysql_unix_port_dir mkdir $mysql_unix_port_dir
chown $user $mysql_unix_port_dir chown $user $mysql_unix_port_dir
chmod 755 $mysql_unix_port_dir chmod 755 $mysql_unix_port_dir
fi
fi fi
# If the user doesn't specify a binary, we assume name "mysqld" # If the user doesn't specify a binary, we assume name "mysqld"
...@@ -728,7 +735,9 @@ then ...@@ -728,7 +735,9 @@ then
exit 1 exit 1
fi fi
fi fi
if [ ! -h "$pid_file" ]; then
rm -f "$pid_file" rm -f "$pid_file"
fi
if test -f "$pid_file" if test -f "$pid_file"
then then
log_error "Fatal error: Can't remove the pid file: log_error "Fatal error: Can't remove the pid file:
...@@ -779,13 +788,19 @@ have_sleep=1 ...@@ -779,13 +788,19 @@ have_sleep=1
while true while true
do 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` start_time=`date +%M%S`
eval_log_error "$cmd" eval_log_error "$cmd"
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 touch "$err_log" # hypothetical: log was renamed but not
chown $user "$err_log" # flushed yet. we'd recreate it with chown $user "$err_log" # flushed yet. we'd recreate it with
chmod "$fmode" "$err_log" # wrong owner next time we log, so set chmod "$fmode" "$err_log" # wrong owner next time we log, so set
......
...@@ -280,7 +280,7 @@ case "$mode" in ...@@ -280,7 +280,7 @@ case "$mode" in
then then
# Give extra arguments to mysqld with the my.cnf file. This script # Give extra arguments to mysqld with the my.cnf file. This script
# may be overwritten at next upgrade. # 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=$? wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$?
# Make lock for RedHat / SuSE # Make lock for RedHat / SuSE
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment