Преглед изворни кода

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 година
родитељ
комит
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