summaryrefslogtreecommitdiff
path: root/scripts/mysqld_safe.sh
diff options
context:
space:
mode:
authorTerje Rosten <terje.rosten@oracle.com>2016-10-06 13:26:16 +0200
committerTerje Rosten <terje.rosten@oracle.com>2016-10-06 13:26:16 +0200
commit1f93f4381b60e3a8012ba36a4dec920416073759 (patch)
tree8eb803e39f255e9acaafd8ec835c04d3b8b6ce97 /scripts/mysqld_safe.sh
parent65febcce97ebe2da0c9723b76a041e249b053a98 (diff)
downloadmariadb-git-1f93f4381b60e3a8012ba36a4dec920416073759.tar.gz
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).
Diffstat (limited to 'scripts/mysqld_safe.sh')
-rw-r--r--scripts/mysqld_safe.sh109
1 files changed, 84 insertions, 25 deletions
diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
index 1b30a3bb15b..4b103817ab6 100644
--- a/scripts/mysqld_safe.sh
+++ b/scripts/mysqld_safe.sh
@@ -1,4 +1,4 @@
-#!/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`