Commit 1f93f438 authored by Terje Rosten's avatar Terje Rosten

Bug#24483092 UNSAFE USE OF VARIOUS SHELL UTILITIES

 - Remove use of touch and chmod.
 - Restrict usage of chown to cases where target directory is /var/log.
 - Due to limited feature set in /bin/sh on Solaris, /bin/bash will be
   used on this platform.
 - Give error if directory for UNIX socket file is missing.
 - Privileged user should not log to files owned by different user
   (mysqld will log as before).
parent 65febcce
# Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2006, 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
......@@ -105,7 +105,13 @@ ELSE()
ENDIF()
IF(UNIX)
# FIND_PROC and CHECK_PID are used by mysqld_safe
# SHELL_PATH, FIND_PROC, CHECK_PID are used by mysqld_safe
IF(CMAKE_SYSTEM_NAME MATCHES "SunOS")
SET (SHELL_PATH "/bin/bash")
ELSE()
SET (SHELL_PATH "/bin/sh")
ENDIF()
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
SET (FIND_PROC
"ps wwwp $PID | grep -v mysqld_safe | grep -- $MYSQLD > /dev/null")
......
#!/bin/sh
#!@SHELL_PATH@
# Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
# This file is public domain and comes with NO WARRANTY of any kind
#
......@@ -125,7 +125,13 @@ log_generic () {
echo "$msg"
case $logging in
init) ;; # Just echo the message, don't save it anywhere
file) echo "$msg" >> "$err_log" ;;
file)
if [ -w / -o "$USER" = "root" ]; then
true
else
echo "$msg" >> "$err_log"
fi
;;
syslog) logger -t "$syslog_tag_mysqld_safe" -p "$priority" "$*" ;;
*)
echo "Internal program error (non-fatal):" \
......@@ -145,7 +151,13 @@ log_notice () {
eval_log_error () {
cmd="$1"
case $logging in
file) cmd="$cmd >> "`shell_quote_string "$err_log"`" 2>&1" ;;
file)
if [ -w / -o "$USER" = "root" ]; then
cmd="$cmd > /dev/null 2>&1"
else
cmd="$cmd >> "`shell_quote_string "$err_log"`" 2>&1"
fi
;;
syslog)
# mysqld often prefixes its messages with a timestamp, which is
# redundant when logging to syslog (which adds its own timestamp)
......@@ -571,14 +583,7 @@ then
fi
# Log to err_log file
log_notice "Logging to '$err_log'."
logging=file
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
else
if [ -n "$syslog_tag" ]
then
......@@ -591,6 +596,48 @@ else
logging=syslog
fi
logdir=`dirname "$err_log"`
# Change the err log to the right user, if possible and it is in use
if [ $logging = "file" -o $logging = "both" ]; then
if [ ! -f "$err_log" -a ! -h "$err_log" ]; then
if test -w / -o "$USER" = "root"; then
case $logdir in
/var/log)
(
umask 0137
set -o noclobber
> "$err_log" && chown $user "$err_log"
) ;;
*) ;;
esac
else
(
umask 0137
set -o noclobber
> "$err_log"
)
fi
fi
if [ -f "$err_log" ]; then # Log to err_log file
log_notice "Logging to '$err_log'."
elif [ "x$user" = "xroot" ]; then # running as root, mysqld can create log file; continue
echo "Logging to '$err_log'." >&2
else
case $logdir in
# We can't create $err_log, however mysqld can; continue
/tmp|/var/tmp|/var/log/mysql|$DATADIR)
echo "Logging to '$err_log'." >&2
;;
# We can't create $err_log and don't know if mysqld can; error out
*)
log_error "error: log-error set to '$err_log', however file don't exists. Create writable for user '$user'."
exit 1
;;
esac
fi
fi
USER_OPTION=""
if test -w / -o "$USER" = "root"
then
......@@ -598,11 +645,6 @@ then
then
USER_OPTION="--user=$user"
fi
# Change the err log to the right user, if it is in use
if [ $want_syslog -eq 0 -a ! -h "$err_log" ]; then
touch "$err_log"
chown $user "$err_log"
fi
if test -n "$open_files"
then
ulimit -n $open_files
......@@ -615,15 +657,12 @@ then
fi
safe_mysql_unix_port=${mysql_unix_port:-${MYSQL_UNIX_PORT:-@MYSQL_UNIX_ADDR@}}
# Make sure that directory for $safe_mysql_unix_port exists
# Check that directory for $safe_mysql_unix_port exists
mysql_unix_port_dir=`dirname $safe_mysql_unix_port`
if [ ! -d $mysql_unix_port_dir ]
then
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
log_error "Directory '$mysql_unix_port_dir' for UNIX socket file don't exists."
exit 1
fi
# If the user doesn't specify a binary, we assume name "mysqld"
......@@ -800,11 +839,31 @@ do
eval_log_error "$cmd"
# hypothetical: log was renamed but not
# flushed yet. we'd recreate it with
# wrong owner next time we log, so set
# it up correctly while we can!
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
fi # it up correctly while we can!
if test -w / -o "$USER" = "root"; then
logdir=`dirname "$err_log"`
case $logdir in
/var/log)
(
umask 0137
set -o noclobber
> "$err_log" && chown $user "$err_log"
) ;;
*) ;;
esac
else
(
umask 0137
set -o noclobber
> "$err_log"
)
fi
fi
end_time=`date +%M%S`
......
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