Просмотр исходного кода

Don't use "[ -r FILE ]" to check for readability in check_log.

On recent Linux systems, it is possible to grant the nrpe daemon
additional capabilities, such as CAP_DAC_READ_SEARCH (bypass file read
permission checks and directory read and execute permission checks),
even though the nrpe daemon typically does not run as root.

But by design, when a non-root process calls access(2) or similar
permission checks, the kernel answers using an empty set of
capabilities.  Quoting the access(2) man page verbatim:

"This allows set-user-ID programs and capability-endowed programs to
easily determine the invoking user's authority.  In other words,
access() does not answer the "can I read/write/execute this file?"
question.  It answers a slightly different question: "(assuming I'm a
setuid binary) can the user who invoked me read/write/execute this
file?", which gives set-user-ID programs the possibility to prevent
malicious users from causing them to read files which users shouldn't
be able to read.

What this means is that under Linux, perhaps non-intuitively, you must
not rely on access(2) or stat(2) (or any higher-level test that
ultimately uses these system calls) to determine whether the *current
process* can read a file.  E.g.: access(2) may return -1 when in fact
opening the file in question would succeed because the process holds
the CAP_DAC_READ_SEARCH capability.

Therefore, instead of using "[ -r FILE ]" to check whether the log
file is readable, use dd to read 0 bytes from the log file.  This will
cause dd to call open(2) on the log file, which will only succeed if
in fact the log file is readable.
James Ralston 4 лет назад
Родитель
Сommit
825aad37d8
1 измененных файлов с 9 добавлено и 2 удалено
  1. 9 2
      plugins-scripts/check_log.sh

+ 9 - 2
plugins-scripts/check_log.sh

@@ -178,12 +178,19 @@ if [ $rc -eq 0 ]; then
 	exit "$STATE_UNKNOWN"
 fi
 
-# If the source log file doesn't exist, exit
+# If the source log file doesn't exist or isn't readable, exit.
+#
+# Note that we deliberately use "dd" to check for read access instead
+# of "[ -r $logfile ]", as the latter can return false-negatives on
+# Linux if the check_log plugin is being run via nrpe with additional
+# capabilities (e.g., CAP_DAC_READ_SEARCH).  In contrast, "dd"
+# actually attempts to open the file, which is a true test of whether
+# the file is readable.
 
 if [ ! -e "$logfile" ]; then
     echo "Log check error: Log file $logfile does not exist!"
     exit "$STATE_UNKNOWN"
-elif [ ! -r "$logfile" ] ; then
+elif ! dd if="$logfile" count=0 1>/dev/null 2>&1; then
     echo "Log check error: Log file $logfile is not readable!"
     exit "$STATE_UNKNOWN"
 fi