From f864f1d027b8c7af527eb30244f86c1177c67f83 Mon Sep 17 00:00:00 2001
From: chrfranke <chrfranke@4ea69e1a-61f1-4043-bf83-b5c94c648137>
Date: Sat, 6 Aug 2022 16:09:49 +0000
Subject: [PATCH] Detect accidental use of smartd_warning script in '-M exec'.
 smartd.cpp: Set SMARTD_SUBJECT to empty. smartd_warning.sh.in,
 os_win32/smartd_warning.cmd: Abort if SMARTD_SUBJECT is already nonempty.

git-svn-id: https://svn.code.sf.net/p/smartmontools/code/trunk@5403 4ea69e1a-61f1-4043-bf83-b5c94c648137
---
 smartmontools/ChangeLog                   | 5 +++++
 smartmontools/os_win32/smartd_warning.cmd | 8 +++++++-
 smartmontools/smartd.cpp                  | 4 +++-
 smartmontools/smartd_warning.sh.in        | 8 +++++++-
 4 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/smartmontools/ChangeLog b/smartmontools/ChangeLog
index cd35d1f00..12a0b94f1 100644
--- a/smartmontools/ChangeLog
+++ b/smartmontools/ChangeLog
@@ -2,6 +2,11 @@ $Id$
 
 2022-08-06  Christian Franke  <franke@computer.org>
 
+	Detect accidental use of smartd_warning script in '-M exec'.
+	smartd.cpp: Set SMARTD_SUBJECT to empty.
+	smartd_warning.sh.in, os_win32/smartd_warning.cmd: Abort if
+	SMARTD_SUBJECT is already nonempty.
+
 	smartd.cpp, popen_as_ugid.cpp: Don't use 'getdtablesize()'.
 	This function is declared 'legacy' since SUS 1997 and no longer part
 	of POSIX since 2004.  Use 'sysconf(_SC_OPEN_MAX)' instead.
diff --git a/smartmontools/os_win32/smartd_warning.cmd b/smartmontools/os_win32/smartd_warning.cmd
index 91d2694a5..a5a980f9e 100644
--- a/smartmontools/os_win32/smartd_warning.cmd
+++ b/smartmontools/os_win32/smartd_warning.cmd
@@ -4,7 +4,7 @@
 ::
 :: Home page of code is: http://www.smartmontools.org
 ::
-:: Copyright (C) 2012-17 Christian Franke
+:: Copyright (C) 2012-22 Christian Franke
 ::
 :: SPDX-License-Identifier: GPL-2.0-or-later
 ::
@@ -20,6 +20,12 @@ set err=
 cd /d %~dp0
 if errorlevel 1 goto ERROR
 
+:: Detect accidental use of '-M exec /path/to/smartd_warning.cmd'
+if not "!SMARTD_SUBJECT!" == "" (
+  echo smartd_warning.cmd: SMARTD_SUBJECT is already set - possible recursion
+  goto ERROR
+)
+
 :: Parse options
 set dryrun=
 if "%1" == "--dryrun" (
diff --git a/smartmontools/smartd.cpp b/smartmontools/smartd.cpp
index b0150c431..1bacd9c4c 100644
--- a/smartmontools/smartd.cpp
+++ b/smartmontools/smartd.cpp
@@ -1110,7 +1110,7 @@ static void MailWarning(const dev_config & cfg, dev_state & state, int which, co
 
   // Export information in environment variables that will be useful
   // for user scripts
-  static env_buffer env[12];
+  static env_buffer env[13];
   env[0].set("SMARTD_MAILER", executable);
   env[1].set("SMARTD_MESSAGE", message);
   char dates[DATEANDEPOCHLEN];
@@ -1136,6 +1136,8 @@ static void MailWarning(const dev_config & cfg, dev_state & state, int which, co
     case 3: snprintf(dates, sizeof(dates), "%d", (0x01)<<mail->logged);
   }
   env[11].set("SMARTD_NEXTDAYS", dates);
+  // Avoid false positive recursion detection by smartd_warning.{sh,cmd}
+  env[12].set("SMARTD_SUBJECT", "");
 
   // now construct a command to send this as EMAIL
   if (!*executable)
diff --git a/smartmontools/smartd_warning.sh.in b/smartmontools/smartd_warning.sh.in
index a07e6b461..1e06d5578 100644
--- a/smartmontools/smartd_warning.sh.in
+++ b/smartmontools/smartd_warning.sh.in
@@ -4,7 +4,7 @@
 #
 # Home page of code is: https://www.smartmontools.org
 #
-# Copyright (C) 2012-21 Christian Franke
+# Copyright (C) 2012-22 Christian Franke
 #
 # SPDX-License-Identifier: GPL-2.0-or-later
 #
@@ -27,6 +27,12 @@ os_mailer="@os_mailer@"
 # Plugin directory (disabled if empty)
 plugindir="@smartdplugindir@"
 
+# Detect accidental use of '-M exec /path/to/smartd_warning.sh'.
+if [ -n "$SMARTD_SUBJECT" ]; then
+  echo "$0: SMARTD_SUBJECT is already set - possible recursion" >&2
+  exit 1
+fi
+
 # Parse options
 dryrun=
 case $1 in
-- 
GitLab