]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
ast_coredumper: check ast_debug_tools.conf permissions
authorMike Bradeen <mbradeen@sangoma.com>
Thu, 15 Jan 2026 20:52:30 +0000 (13:52 -0700)
committergithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Thu, 5 Feb 2026 15:25:18 +0000 (15:25 +0000)
Prevent ast_coredumper from using ast_debug_tools.conf files that are
not owned by root or are writable by other users or groups.

Prevent ast_logescalator and ast_loggrabber from doing the same if
they are run as root.

Resolves: #GHSA-rvch-3jmx-3jf3

UserNote: ast_debug_tools.conf must be owned by root and not be
writable by other users or groups to be used by ast_coredumper or
by ast_logescalator or ast_loggrabber when run as root.

contrib/scripts/ast_coredumper
contrib/scripts/ast_logescalator
contrib/scripts/ast_loggrabber

index ad752be06883059b9d497bda43915ce0faad20b1..2d8ea76726fa6b0ceed57e851ac516c5d7b1ff4d 100755 (executable)
@@ -42,11 +42,9 @@ COMMANDLINE_COREDUMPS=false
 
 # Read config files from most important to least important.
 # Variables set on the command line or environment always take precedence.
-# shellcheck disable=SC1091
-[ -f ./ast_debug_tools.conf ] && source ./ast_debug_tools.conf
-# shellcheck disable=SC1090
-[ -f ~/ast_debug_tools.conf ] && source ~/ast_debug_tools.conf
-[ -f /etc/asterisk/ast_debug_tools.conf ] && source /etc/asterisk/ast_debug_tools.conf
+safe_source_config ./ast_debug_tools.conf
+safe_source_config ~/ast_debug_tools.conf
+safe_source_config /etc/asterisk/ast_debug_tools.conf
 
 if [ -n "${DATEFORMAT}" ] ; then
        err <<-EOF
@@ -432,6 +430,43 @@ check_gdb() {
        fi
 }
 
+# Function to safely source a config file with security checks
+# This prevents privilege escalation by ensuring config files are
+# owned by root and not writable by group or others
+safe_source_config() {
+       local config_file="$1"
+
+       # Return if file doesn't exist
+       [ -f "$config_file" ] || return 0
+
+       # Get the absolute path
+       config_file=$(readlink -f "$config_file")
+
+       # Get file owner UID and permissions
+       local file_stat
+       file_stat=$(stat -c "%u %a" "$config_file" 2>/dev/null) || return 0
+       local owner_uid=${file_stat%% *}
+       local perms=${file_stat##* }
+
+       # File must be owned by root (UID 0)
+       if [ "$owner_uid" -ne 0 ]; then
+               err "Config file $config_file is not owned by root. Skipping for security." >&2
+               return 1
+       fi
+
+       # File must not be writable by group or others (check group-write and other-write bits)
+       # Extract the group and other permission digits
+       local group_perms=$((perms / 10 % 10))
+       local other_perms=$((perms % 10))
+
+       if [ $((group_perms & 2)) -ne 0 ] || [ $((other_perms & 2)) -ne 0 ]; then
+               err "Config file $config_file is writable by group or others. Skipping for security." >&2
+               return 1
+       fi
+
+       source "$config_file"
+}
+
 # shellcheck disable=SC2317
 find_pid() {
        if [ -n "$PID" ] ; then
index b5a44ccefec5a8af3b573af40effc19b4147f924..a4eced8eaee52b8100bf2a69e9aacb77b16a1fbb 100755 (executable)
@@ -127,10 +127,51 @@ declare -A DEBUG_COMMANDS=(
 VERBOSE_LEVELS="NOTICE,WARNING,ERROR,VERBOSE"
 DEBUG_LEVELS="DEBUG"
 
+# Function to safely source a config file with security checks
+# This prevents privilege escalation by ensuring config files are
+# owned by root and not writable by group or others when running as root
+safe_source_config() {
+       local config_file="$1"
+
+       # Return if file doesn't exist
+       [ -f "$config_file" ] || return 0
+
+       # Get the absolute path
+       config_file=$(readlink -f "$config_file")
+
+       # Check if running as root (effective UID is 0)
+       if [ $EUID -eq 0 ]; then
+               # Running as root - apply strict security checks
+               # Get file owner UID and permissions
+               local file_stat
+               file_stat=$(stat -c "%u %a" "$config_file" 2>/dev/null) || return 0
+               local owner_uid=${file_stat%% *}
+               local perms=${file_stat##* }
+
+               # File must be owned by root (UID 0)
+               if [ "$owner_uid" -ne 0 ]; then
+                       echo "WARNING: Config file $config_file is not owned by root. Skipping for security." >&2
+                       return 1
+               fi
+
+               # File must not be writable by group or others (check group-write and other-write bits)
+               # Extract the group and other permission digits
+               local group_perms=$((perms / 10 % 10))
+               local other_perms=$((perms % 10))
+
+               if [ $((group_perms & 2)) -ne 0 ] || [ $((other_perms & 2)) -ne 0 ]; then
+                       echo "WARNING: Config file $config_file is writable by group or others. Skipping for security." >&2
+                       return 1
+               fi
+       fi
+
+       source "$config_file"
+}
+
 # Read config files from least important to most important
-[ -f /etc/asterisk/ast_debug_tools.conf ] && source /etc/asterisk/ast_debug_tools.conf
-[ -f ~/ast_debug_tools.conf ] && source ~/ast_debug_tools.conf
-[ -f ./ast_debug_tools.conf ] && source ./ast_debug_tools.conf
+safe_source_config /etc/asterisk/ast_debug_tools.conf
+safe_source_config ~/ast_debug_tools.conf
+safe_source_config ./ast_debug_tools.conf
 
 DATEFORMAT=${DATEFORMAT:-'date +%FT%H-%M-%S%z'}
 UNIQUEID=$($DATEFORMAT)
index b549ec329aa6bb13e4fbd780326dae846e6c0585..0683dfd9916735bf86050b52be99c16bc5dc3c0d 100755 (executable)
@@ -101,10 +101,51 @@ append_logfiles=false
 declare -a LOGFILES
 declare -a ARGS_LOGFILES
 
+# Function to safely source a config file with security checks
+# This prevents privilege escalation by ensuring config files are
+# owned by root and not writable by group or others when running as root
+safe_source_config() {
+       local config_file="$1"
+
+       # Return if file doesn't exist
+       [ -f "$config_file" ] || return 0
+
+       # Get the absolute path
+       config_file=$(readlink -f "$config_file")
+
+       # Check if running as root (effective UID is 0)
+       if [ $EUID -eq 0 ]; then
+               # Running as root - apply strict security checks
+               # Get file owner UID and permissions
+               local file_stat
+               file_stat=$(stat -c "%u %a" "$config_file" 2>/dev/null) || return 0
+               local owner_uid=${file_stat%% *}
+               local perms=${file_stat##* }
+
+               # File must be owned by root (UID 0)
+               if [ "$owner_uid" -ne 0 ]; then
+                       echo "WARNING: Config file $config_file is not owned by root. Skipping for security." >&2
+                       return 1
+               fi
+
+               # File must not be writable by group or others (check group-write and other-write bits)
+               # Extract the group and other permission digits
+               local group_perms=$((perms / 10 % 10))
+               local other_perms=$((perms % 10))
+
+               if [ $((group_perms & 2)) -ne 0 ] || [ $((other_perms & 2)) -ne 0 ]; then
+                       echo "WARNING: Config file $config_file is writable by group or others. Skipping for security." >&2
+                       return 1
+               fi
+       fi
+
+       source "$config_file"
+}
+
 # Read config files from least important to most important
-[ -f /etc/asterisk/ast_debug_tools.conf ] && source /etc/asterisk/ast_debug_tools.conf
-[ -f ~/ast_debug_tools.conf ] && source ~/ast_debug_tools.conf
-[ -f ./ast_debug_tools.conf ] && source ./ast_debug_tools.conf
+safe_source_config /etc/asterisk/ast_debug_tools.conf
+safe_source_config ~/ast_debug_tools.conf
+safe_source_config ./ast_debug_tools.conf
 
 if [ ${#LOGFILES[@]} -eq 0 ] ; then
        LOGFILES+=(/var/log/asterisk/messages* /var/log/asterisk/queue* \
@@ -178,15 +219,14 @@ df=${tarball_uniqueid:-$(${DATEFORMAT})}
 # Extract the Python timestamp conver script from the end of this
 # script and save it to /tmp/.ast_tsconvert.py
 
-ss=`egrep -n "^#@@@SCRIPTSTART@@@" $0 |cut -f1 -d:`
-tail -n +${ss} $0 >/tmp/.ast_tsconvert.py
+install -m 0600 /dev/stdin /tmp/.ast_tsconvert.py < <(sed '1,/^#@@@SCRIPTSTART@@@/ d' "$0")
 
 tmpdir=$(mktemp -d)
 if [ -z "$tmpdir" ] ; then
        echo "${prog}: Unable to create temporary directory."
        exit 1
 fi
-trap "rm -rf $tmpdir" EXIT
+trap "rm -rf $tmpdir /tmp/.ast_tsconvert.py" EXIT
 tardir=asterisk-${df}.logfiles
 
 # Now iterate over the logfiles