mirror of
https://github.com/pi-hole/pi-hole.git
synced 2026-11-01 15:11:11 +01:00
`/run/pihole-FTL.pid` is owned by the `pihole` user, but root reads it. `getFTLPID()` only rejected values starting with a non-digit, so `1+a[$(cmd)]` passed and was executed by the arithmetic `[[ ... -eq ... ]]` checks in `pihole`. The logrotate `postrotate` sent `kill -USR2` to whatever the file contained, including `-1`. 1. `getFTLPID()` accepts only a plain number whose `/proc/<pid>/comm` is `pihole-FTL`. 2. The logrotate `postrotate` uses `getFTLPID()`. The installer swaps this line in existing files, which are otherwise never replaced. Signed-off-by: DL6ER <dl6er@dl6er.de>
152 lines
4.9 KiB
Bash
Executable File
152 lines
4.9 KiB
Bash
Executable File
#!/usr/bin/env sh
|
|
|
|
# Pi-hole: A black hole for Internet advertisements
|
|
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
|
|
# Network-wide ad blocking via your own hardware.
|
|
#
|
|
# Script to hold utility functions for use in other scripts
|
|
#
|
|
# This file is copyright under the latest version of the EUPL.
|
|
# Please see LICENSE file for your rights under this license.
|
|
|
|
# Basic Housekeeping rules
|
|
# - Functions must be self contained
|
|
# - Functions should be grouped with other similar functions
|
|
# - Functions must be documented
|
|
# - New functions must have a test added for them in test/test_any_utils.py
|
|
|
|
#######################
|
|
# Takes Three arguments: file, key, and value.
|
|
#
|
|
# Checks the target file for the existence of the key
|
|
# - If it exists, it changes the value
|
|
# - If it does not exist, it adds the value
|
|
#
|
|
# Example usage:
|
|
# addOrEditKeyValPair "/etc/pihole/setupVars.conf" "BLOCKING_ENABLED" "true"
|
|
#######################
|
|
addOrEditKeyValPair() {
|
|
local file="${1}"
|
|
local key="${2}"
|
|
local value="${3}"
|
|
|
|
if grep -q "^${key}=" "${file}"; then
|
|
# Key already exists in file, modify the value
|
|
sed -i "/^${key}=/c\\${key}=${value}" "${file}"
|
|
else
|
|
# Key does not already exist, add it and it's value
|
|
echo "${key}=${value}" >> "${file}"
|
|
fi
|
|
}
|
|
|
|
#######################
|
|
# Safely loads key=value pairs from the Pi-hole versions cache file.
|
|
# Unlike `source`, this function never executes file content as shell code.
|
|
# Only known keys are assigned, and values are validated against a strict
|
|
# character allowlist to prevent shell injection.
|
|
#
|
|
# Takes one argument: path to the versions file
|
|
# Returns 0 in all cases (compatible with set -e)
|
|
# Example loadVersionFile "/etc/pihole/versions"
|
|
#######################
|
|
loadVersionFile() {
|
|
local file="${1}"
|
|
local line key value
|
|
|
|
[ -f "${file}" ] || return 0
|
|
|
|
while IFS= read -r line || [ -n "${line}" ]; do
|
|
# Skip blank lines and comments
|
|
case "${line}" in
|
|
''|\#*) continue ;;
|
|
esac
|
|
|
|
# Require KEY=VALUE format (key must be non-empty)
|
|
key="${line%%=*}"
|
|
value="${line#*=}"
|
|
[ -z "${key}" ] && continue
|
|
[ "${key}" = "${line}" ] && continue # no '=' found
|
|
|
|
# Allowlist: only assign known version-file keys
|
|
case "${key}" in
|
|
CORE_VERSION|CORE_BRANCH|CORE_HASH|\
|
|
GITHUB_CORE_VERSION|GITHUB_CORE_HASH|\
|
|
WEB_VERSION|WEB_BRANCH|WEB_HASH|\
|
|
GITHUB_WEB_VERSION|GITHUB_WEB_HASH|\
|
|
FTL_VERSION|FTL_BRANCH|FTL_HASH|\
|
|
GITHUB_FTL_VERSION|GITHUB_FTL_HASH|\
|
|
DOCKER_VERSION|GITHUB_DOCKER_VERSION) ;;
|
|
*) continue ;;
|
|
esac
|
|
|
|
# Validate value: allow only characters safe in version strings and branch names.
|
|
# Permits: letters, digits, dot, hyphen, underscore, slash, plus sign, and empty string.
|
|
case "${value}" in
|
|
*[!a-zA-Z0-9._/+\-]*) continue ;;
|
|
esac
|
|
|
|
# Safe to assign: key is from the allowlist, value contains no shell metacharacters
|
|
eval "${key}=\${value}"
|
|
done < "${file}"
|
|
}
|
|
|
|
#######################
|
|
# returns FTL's PID based on the content of the pihole-FTL.pid file
|
|
#######################
|
|
getFTLPID() {
|
|
local FTL_PID_FILE="/run/pihole-FTL.pid" # hardcoded — see GHSA-6w8x-p785-6pm4
|
|
local FTL_PID
|
|
|
|
if [ -s "${FTL_PID_FILE}" ]; then
|
|
# -s: FILE exists and has a size greater than zero
|
|
FTL_PID="$(cat "${FTL_PID_FILE}")"
|
|
# The pihole user owns this file, so only accept a plain number naming a running pihole-FTL
|
|
case "${FTL_PID}" in
|
|
''|*[!0-9]*) unset FTL_PID ;;
|
|
*) [ "$(cat "/proc/${FTL_PID}/comm" 2>/dev/null)" = "pihole-FTL" ] || unset FTL_PID ;;
|
|
esac
|
|
fi
|
|
|
|
# If FTL is not running, or the PID file contains malicious stuff, substitute
|
|
# negative PID to signal this
|
|
FTL_PID=${FTL_PID:=-1}
|
|
echo "${FTL_PID}"
|
|
}
|
|
|
|
#######################
|
|
# returns value from FTLs config file using pihole-FTL --config
|
|
#
|
|
# Takes one argument: key
|
|
# Example getFTLConfigValue dns.piholePTR
|
|
#######################
|
|
getFTLConfigValue(){
|
|
# Pipe to cat to avoid pihole-FTL assuming this is an interactive command
|
|
# returning colored output.
|
|
pihole-FTL --config -q "${1}" | cat
|
|
}
|
|
|
|
#######################
|
|
# sets value in FTLs config file using pihole-FTL --config
|
|
#
|
|
# Takes two arguments: key and value
|
|
# Example setFTLConfigValue dns.piholePTR PI.HOLE
|
|
#
|
|
# Note, for complex values such as dns.upstreams, you should wrap the value in single quotes:
|
|
# setFTLConfigValue dns.upstreams '[ "8.8.8.8" , "8.8.4.4" ]'
|
|
#######################
|
|
setFTLConfigValue(){
|
|
local err
|
|
{ pihole-FTL --config "${1}" "${2}" >/dev/null; err="$?"; } || true
|
|
|
|
case $err in
|
|
0) ;;
|
|
5)
|
|
# FTL returns 5 if the value was set by an environment variable and is therefore read-only
|
|
printf " %s %s set by environment variable. Please unset it to use this function\n" "${CROSS}" "${1}";
|
|
exit 5;;
|
|
*)
|
|
printf " %s Failed to set %s. Try with sudo power\n" "${CROSS}" "${1}"
|
|
exit 1
|
|
esac
|
|
}
|