Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 39 additions & 9 deletions shared/templates/rsyslog_logfiles_attributes_modify/bash.template
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ RSYSLOG_ETC_CONFIG="/etc/rsyslog.conf"
# * And also the log file paths listed after rsyslog's $IncludeConfig directive
# (store the result into array for the case there's shell glob used as value of IncludeConfig)
readarray -t OLD_INC < <(grep -e "\$IncludeConfig[[:space:]]\+[^[:space:];]\+" /etc/rsyslog.conf | cut -d ' ' -f 2)
# eval expands globs in $IncludeConfig paths. Acceptable because
# /etc/rsyslog.conf is writable only by root and this script runs as root.
readarray -t RSYSLOG_INCLUDE_CONFIG < <(for INCPATH in "${OLD_INC[@]}"; do eval printf '%s\\n' "${INCPATH}"; done)
readarray -t NEW_INC < <(sed -n '/^\s*include(/,/)/Ip' /etc/rsyslog.conf | sed -n 's@.*file\s*=\s*"\([/[:alnum:][:punct:]]*\)".*@\1@Ip')
# eval expands globs in include() paths. Acceptable because
# /etc/rsyslog.conf is writable only by root and this script runs as root.
readarray -t RSYSLOG_INCLUDE < <(for INCPATH in "${NEW_INC[@]}"; do eval printf '%s\\n' "${INCPATH}"; done)

# Declare an array to hold the final list of different log file paths
Expand All @@ -34,7 +38,23 @@ do
then
RSYSLOG_CONFIG_FILES+=("${ENTRY}")
else
echo "Invalid include object: ${ENTRY}"
# ENTRY may be a glob such as /etc/rsyslog.d/*.conf (not a single path).
# nullglob runs only inside process substitution (subshell), so shopt cannot
# affect the caller if this script were ever sourced.
readarray -t _glob_paths < <(
shopt -s nullglob
for _maybe in ${ENTRY}
do
[[ -f "${_maybe}" ]] && printf '%s\n' "${_maybe}"
done
)
if ((${#_glob_paths[@]}))
then
RSYSLOG_CONFIG_FILES+=("${_glob_paths[@]}")
else
echo "Invalid include object: ${ENTRY}"
fi
unset _glob_paths
fi
done

Expand Down Expand Up @@ -80,10 +100,21 @@ done
# exclude /dev/* paths (e.g., /dev/console)
for LOG_FILE in "${RSYSLOG_CONFIG_FILES[@]}"
do
ACTION_OMFILE_LINES=$(grep -ioPz "action\s*\(\s*type\s*=\s*\"omfile\"[^\)]*\)" "${LOG_FILE}" | tr '\0' '\n')
OMFILE_LINES=$(echo "${ACTION_OMFILE_LINES}"| grep -iaoP "\bFile\s*=\s*\"([/[:alnum:][:punct:]]*)\"")
readarray -t OMFILE_PATHS < <(echo "${OMFILE_LINES}" | grep -oE "\"([/[:alnum:][:punct:]]*)\"" | tr -d '"' | grep -v "^/dev/")
LOG_FILE_PATHS+=("${OMFILE_PATHS[@]}")
[[ -f "${LOG_FILE}" ]] || continue
# Pipe grep -z output directly through tr so NUL delimiters become newlines
# before bash ever stores the data (bash variables cannot hold NUL bytes).
readarray -t _RSYSLOG_OMFILE_PATHS < <(
LC_ALL=C grep -iozP "action\s*\(\s*type\s*=\s*\"omfile\"[^\)]*\)" "${LOG_FILE}" 2>/dev/null \
| tr '\0' '\n' \
| grep -iaoP "\bFile\s*=\s*\"([/[:alnum:][:punct:]]*)\"" \
| grep -oE "\"([/[:alnum:][:punct:]]*)\"" \
| tr -d '"' \
| grep -v '^/dev/' \
| grep -v '^$' \
|| true
)
LOG_FILE_PATHS+=("${_RSYSLOG_OMFILE_PATHS[@]}")
unset _RSYSLOG_OMFILE_PATHS
done

# Ensure the correct attribute if file exists
Expand All @@ -97,11 +128,10 @@ do
then
continue
fi
# Only operate on the file if it exists; non-existent files would cause the command to fail
# with a non-zero exit code, which oscap --remediate interprets as an error, skipping the fix.
if [ ! -f "$LOG_FILE_PATH" ]
# Skip non-files (mis-parsed paths, directories); chmod on missing paths must not abort.
if [[ ! -f "${LOG_FILE_PATH}" ]]
then
continue
fi
$FILE_CMD "{{{ VALUE }}}" "$LOG_FILE_PATH"
$FILE_CMD "{{{ VALUE }}}" "${LOG_FILE_PATH}"
done
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
# real-world default RainerScript rsyslog.conf with multiple action(type="omfile" ...)
# entries, including entries with extra attributes (e.g. sync="on") after the File= field.
#
# Previously, two bugs caused remediation to silently do nothing:
# 1. grep -iozP stored NUL-separated matches in a bash variable, stripping NULs and
# corrupting multi-match output (fixed by piping through tr '\0' '\n').
# 2. The extracted paths were appended as a single newline-joined string instead of
# individual array elements (fixed by using readarray).
# Previously, grep -iozP stored NUL-separated matches in a bash variable via
# command substitution. Bash strips NUL bytes from variables, so the tr '\0'
# '\n' that followed was a no-op and multi-match output was silently corrupted.
# Fixed by keeping the grep -z | tr '\0' '\n' chain inside a pipe (where NULs
# are preserved) and feeding the result directly into readarray.

# Declare variables used for the tests and define the create_rsyslog_test_logs function
source $SHARED/rsyslog_log_utils.sh
Expand Down
Loading