[monitoring-plugins] OpenBSD Hardening: Check System Calls and Fixes ...

GitHub git at monitoring-plugins.org
Mon Oct 19 12:20:13 CEST 2026


    Module: monitoring-plugins
    Branch: master
    Commit: 2943bd4406ea9278d498c535c1f33ade66111012
    Author: Alvar <post at 0x21.biz>
 Committer: GitHub <noreply at github.com>
      Date: Mon Oct 19 10:15:59 2026 +0000
       URL: https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=2943bd44

OpenBSD Hardening: Check System Calls and Fixes (#2368)

Start by checking the return values of pledge(2) and unveil(2) to ensure
no future breakage. Furthermore, mitigate a theoretical off-by-one error
for the command paths used for unveil(2). The buffer has the length of
the complete ping, ping6, or ps command including arguments, but misses
one byte for the final \0.

---

 plugins-root/check_icmp.c | 12 +++++++++---
 plugins/check_curl.c      |  8 ++++++--
 plugins/check_disk.c      |  4 +++-
 plugins/check_load.c      | 30 ++++++++++++++++++++++--------
 plugins/check_ntp_time.c  |  8 ++++++--
 plugins/check_ping.c      | 32 +++++++++++++++++++++++---------
 plugins/check_procs.c     | 26 +++++++++++++++++++-------
 plugins/check_smtp.c      |  8 ++++++--
 plugins/check_ssh.c       |  8 ++++++--
 plugins/check_swap.c      | 12 +++++++++---
 plugins/check_tcp.c       |  8 ++++++--
 11 files changed, 115 insertions(+), 41 deletions(-)

diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c
index e497572b..4b1e5003 100644
--- a/plugins-root/check_icmp.c
+++ b/plugins-root/check_icmp.c
@@ -842,7 +842,9 @@ int main(int argc, char **argv) {
 	 * - dns is required for name lookups (given up later)
 	 * - id is required for temporary privilege drops in configparsing and for
 	 *   permanent privilege dropping after opening the socket (given up later) */
-	pledge("stdio rpath inet dns id", NULL);
+	if (pledge("stdio rpath inet dns id", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	setlocale(LC_ALL, "");
@@ -870,7 +872,9 @@ int main(int argc, char **argv) {
 	}
 
 #ifdef __OpenBSD__
-	pledge("stdio inet dns id", NULL);
+	if (pledge("stdio inet dns id", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	const check_icmp_config config = tmp_config.config;
@@ -948,7 +952,9 @@ int main(int argc, char **argv) {
 	}
 
 #ifdef __OpenBSD__
-	pledge("stdio inet", NULL);
+	if (pledge("stdio inet", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	/* make sure we don't wait any longer than necessary */
diff --git a/plugins/check_curl.c b/plugins/check_curl.c
index 2607fce1..61a651d8 100644
--- a/plugins/check_curl.c
+++ b/plugins/check_curl.c
@@ -125,7 +125,9 @@ int main(int argc, char **argv) {
 	 * - wpath is required to write --cookie-jar (possibly given up later)
 	 * - inet is required for sockets
 	 * - dns is required for name lookups */
-	pledge("stdio rpath wpath inet dns", NULL);
+	if (pledge("stdio rpath wpath inet dns", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	setlocale(LC_ALL, "");
@@ -148,7 +150,9 @@ int main(int argc, char **argv) {
 		if (verbose >= 2) {
 			printf(_("* No \"--cookie-jar\" is used, giving up \"wpath\" pledge(2)\n"));
 		}
-		pledge("stdio rpath inet dns", NULL);
+		if (pledge("stdio rpath inet dns", NULL)) {
+			die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+		}
 	}
 #endif // __OpenBSD__
 
diff --git a/plugins/check_disk.c b/plugins/check_disk.c
index 5a9ffee1..03034cdf 100644
--- a/plugins/check_disk.c
+++ b/plugins/check_disk.c
@@ -117,7 +117,9 @@ const byte_unit ExaBytes_factor = 1000000000000000000;
 int main(int argc, char **argv) {
 #ifdef __OpenBSD__
 	/* - rpath is required to read --extra-opts and the partitions */
-	pledge("stdio rpath", NULL);
+	if (pledge("stdio rpath", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	setlocale(LC_ALL, "");
diff --git a/plugins/check_load.c b/plugins/check_load.c
index 5444c1cb..12427e7b 100644
--- a/plugins/check_load.c
+++ b/plugins/check_load.c
@@ -121,21 +121,31 @@ int main(int argc, char **argv) {
 	/* Restrict program execution to the ps binary. Continue allow reading all
 	 * files since arguments were not parsed at this point. */
 	char *ps_command, *ps_binary;
-	ps_command = malloc(strnlen(PS_COMMAND, BUFSIZ));
+	if (!(ps_command = malloc(strnlen(PS_COMMAND, BUFSIZ) + 1))) {
+		die(STATE_UNKNOWN, "malloc: %s", strerror(errno));
+	}
 
-	(void)strlcpy(ps_command, PS_COMMAND, strnlen(PS_COMMAND, BUFSIZ));
+	(void)strlcpy(ps_command, PS_COMMAND, strnlen(PS_COMMAND, BUFSIZ) + 1);
 	if (!(ps_binary = strtok(ps_command, " "))) {
 		die(STATE_UNKNOWN, "Cannot extract binary from %s", PS_COMMAND);
 	}
-	unveil(ps_binary, "rx");
+	if (unveil(ps_binary, "rx")) {
+		die(STATE_UNKNOWN, "unveil: %s", strerror(errno));
+	}
 	free(ps_command);
 
-	unveil("/", "r");
-	unveil(NULL, NULL);
+	if (unveil("/", "r")) {
+		die(STATE_UNKNOWN, "unveil: %s", strerror(errno));
+	}
+	if (unveil(NULL, NULL)) {
+		die(STATE_UNKNOWN, "locking unveil: %s", strerror(errno));
+	}
 
 	/* - rpath is required to read --extra-opts (given up later)
 	 * - proc and exec are used to fork and exec (given up later) */
-	pledge("stdio rpath proc exec", NULL);
+	if (pledge("stdio rpath proc exec", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	setlocale(LC_ALL, "");
@@ -155,7 +165,9 @@ int main(int argc, char **argv) {
 
 #ifdef __OpenBSD__
 	if (config.n_procs_to_show == 0) {
-		pledge("stdio", NULL);
+		if (pledge("stdio", NULL)) {
+			die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+		}
 	}
 #endif // __OpenBSD__
 
@@ -301,7 +313,9 @@ int main(int argc, char **argv) {
 		mp_add_subcheck_to_check(&overall, top_proc_sc);
 
 #ifdef __OpenBSD__
-		pledge("stdio", NULL);
+		if (pledge("stdio", NULL)) {
+			die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+		}
 #endif // __OpenBSD__
 	}
 
diff --git a/plugins/check_ntp_time.c b/plugins/check_ntp_time.c
index b082b04a..60c24d31 100644
--- a/plugins/check_ntp_time.c
+++ b/plugins/check_ntp_time.c
@@ -699,7 +699,9 @@ int main(int argc, char *argv[]) {
 	 * - inet is required for sockets
 	 * - unix is required for Unix domain sockets
 	 * - dns is required for name lookups */
-	pledge("stdio rpath inet unix dns", NULL);
+	if (pledge("stdio rpath inet unix dns", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	setlocale(LC_ALL, "");
@@ -716,7 +718,9 @@ int main(int argc, char *argv[]) {
 	}
 
 #ifdef __OpenBSD__
-	pledge("stdio inet unix dns", NULL);
+	if (pledge("stdio inet unix dns", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	const check_ntp_time_config config = tmp_config.config;
diff --git a/plugins/check_ping.c b/plugins/check_ping.c
index 6b71b860..ef70ec5f 100644
--- a/plugins/check_ping.c
+++ b/plugins/check_ping.c
@@ -72,29 +72,41 @@ int main(int argc, char **argv) {
 	/* Restrict program execution to the ping{,6} binaries. Continue allow
 	 * reading all files since arguments were not parsed at this point. */
 	char *ping_command, *ping_binary;
-	ping_command = malloc(strnlen(PING6_COMMAND, BUFSIZ));
+	if (!(ping_command = malloc(strnlen(PING6_COMMAND, BUFSIZ) + 1))) {
+		die(STATE_UNKNOWN, "malloc: %s", strerror(errno));
+	}
 
-	(void)strlcpy(ping_command, PING_COMMAND, strnlen(PING_COMMAND, BUFSIZ));
+	(void)strlcpy(ping_command, PING_COMMAND, strnlen(PING6_COMMAND, BUFSIZ) + 1);
 	if (!(ping_binary = strtok(ping_command, " "))) {
 		die(STATE_UNKNOWN, "Cannot extract binary from %s", PING_COMMAND);
 	}
-	unveil(ping_binary, "rx");
+	if (unveil(ping_binary, "rx")) {
+		die(STATE_UNKNOWN, "unveil: %s", strerror(errno));
+	}
 
-	(void)strlcpy(ping_command, PING6_COMMAND, strnlen(PING6_COMMAND, BUFSIZ));
+	(void)strlcpy(ping_command, PING6_COMMAND, strnlen(PING6_COMMAND, BUFSIZ) + 1);
 	if (!(ping_binary = strtok(ping_command, " "))) {
 		die(STATE_UNKNOWN, "Cannot extract binary from %s", PING6_COMMAND);
 	}
-	unveil(ping_binary, "rx");
+	if (unveil(ping_binary, "rx")) {
+		die(STATE_UNKNOWN, "unveil: %s", strerror(errno));
+	}
 
 	free(ping_command);
 
-	unveil("/", "r");
-	unveil(NULL, NULL);
+	if (unveil("/", "r")) {
+		die(STATE_UNKNOWN, "unveil: %s", strerror(errno));
+	}
+	if (unveil(NULL, NULL)) {
+		die(STATE_UNKNOWN, "locking unveil: %s", strerror(errno));
+	}
 
 	/* - rpath is required to read --extra-opts (given up later)
 	 * - dns for hostname resolution via mopl_net_is_{host,inet6_addr} (given up later)
 	 * - proc and exec are used to fork and exec (given up later) */
-	pledge("stdio rpath dns proc exec", NULL);
+	if (pledge("stdio rpath dns proc exec", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	setlocale(LC_ALL, "");
@@ -157,7 +169,9 @@ int main(int argc, char **argv) {
 	ping_result pinged = run_ping(cmd, config.address, config.crta);
 
 #ifdef __OpenBSD__
-	pledge("stdio", NULL);
+	if (pledge("stdio", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	if (pinged.packet_loss == UNKNOWN_PACKET_LOSS || pinged.round_trip_average < 0.0) {
diff --git a/plugins/check_procs.c b/plugins/check_procs.c
index de42b687..b132f0e9 100644
--- a/plugins/check_procs.c
+++ b/plugins/check_procs.c
@@ -100,21 +100,31 @@ int main(int argc, char **argv) {
 	/* Restrict program execution to the ps binary. Continue allow reading all
 	 * files since arguments were not parsed at this point. */
 	char *ps_command, *ps_binary;
-	ps_command = malloc(strnlen(PS_COMMAND, BUFSIZ));
+	if (!(ps_command = malloc(strnlen(PS_COMMAND, BUFSIZ) + 1))) {
+		die(STATE_UNKNOWN, "malloc: %s", strerror(errno));
+	}
 
-	(void)strlcpy(ps_command, PS_COMMAND, strnlen(PS_COMMAND, BUFSIZ));
+	(void)strlcpy(ps_command, PS_COMMAND, strnlen(PS_COMMAND, BUFSIZ) + 1);
 	if (!(ps_binary = strtok(ps_command, " "))) {
 		die(STATE_UNKNOWN, "Cannot extract binary from %s", PS_COMMAND);
 	}
-	unveil(ps_binary, "rx");
+	if (unveil(ps_binary, "rx")) {
+		die(STATE_UNKNOWN, "unveil: %s", strerror(errno));
+	}
 	free(ps_command);
 
-	unveil("/", "r");
-	unveil(NULL, NULL);
+	if (unveil("/", "r")) {
+		die(STATE_UNKNOWN, "unveil: %s", strerror(errno));
+	}
+	if (unveil(NULL, NULL)) {
+		die(STATE_UNKNOWN, "locking unveil: %s", strerror(errno));
+	}
 
 	/* - rpath is required to read --input-path, --extra-opts (given up later)
 	 * - proc and exec are used to fork and exec (given up later) */
-	pledge("stdio rpath proc exec", NULL);
+	if (pledge("stdio rpath proc exec", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	setlocale(LC_ALL, "");
@@ -171,7 +181,9 @@ int main(int argc, char **argv) {
 	}
 
 #ifdef __OpenBSD__
-	pledge("stdio", NULL);
+	if (pledge("stdio", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	int pos; /* number of spaces before 'args' in `ps` output */
diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c
index 94a0d52d..bdee7414 100644
--- a/plugins/check_smtp.c
+++ b/plugins/check_smtp.c
@@ -105,7 +105,9 @@ int main(int argc, char **argv) {
 	 * - inet is required for sockets
 	 * - unix is required for Unix domain sockets
 	 * - dns is required for name lookups */
-	pledge("stdio rpath inet unix dns", NULL);
+	if (pledge("stdio rpath inet unix dns", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	setlocale(LC_ALL, "");
@@ -122,7 +124,9 @@ int main(int argc, char **argv) {
 	}
 
 #ifdef __OpenBSD__
-	pledge("stdio inet unix dns", NULL);
+	if (pledge("stdio inet unix dns", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	const check_smtp_config config = tmp_config.config;
diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c
index 0d7bc64c..3e9630b6 100644
--- a/plugins/check_ssh.c
+++ b/plugins/check_ssh.c
@@ -66,7 +66,9 @@ int main(int argc, char **argv) {
 	 * - inet is required for sockets
 	 * - unix is required for Unix domain sockets
 	 * - dns is required for name lookups */
-	pledge("stdio rpath inet unix dns", NULL);
+	if (pledge("stdio rpath inet unix dns", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	setlocale(LC_ALL, "");
@@ -83,7 +85,9 @@ int main(int argc, char **argv) {
 	}
 
 #ifdef __OpenBSD__
-	pledge("stdio inet unix dns", NULL);
+	if (pledge("stdio inet unix dns", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	check_ssh_config config = tmp_config.config;
diff --git a/plugins/check_swap.c b/plugins/check_swap.c
index 7fdffc6f..ecfab95e 100644
--- a/plugins/check_swap.c
+++ b/plugins/check_swap.c
@@ -71,7 +71,9 @@ int main(int argc, char **argv) {
 #ifdef __OpenBSD__
 	/* - rpath is required to read --extra-opts (given up later)
 	 * - vminfo is required for swapctl(2) (given up later) */
-	pledge("stdio rpath vminfo", NULL);
+	if (pledge("stdio rpath vminfo", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	setlocale(LC_ALL, "");
@@ -88,7 +90,9 @@ int main(int argc, char **argv) {
 	}
 
 #ifdef __OpenBSD__
-	pledge("stdio vminfo", NULL);
+	if (pledge("stdio vminfo", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	swap_config config = tmp.config;
@@ -101,7 +105,9 @@ int main(int argc, char **argv) {
 	}
 
 #ifdef __OpenBSD__
-	pledge("stdio", NULL);
+	if (pledge("stdio", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	if (verbose) {
diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c
index 3315dcac..82a84ba4 100644
--- a/plugins/check_tcp.c
+++ b/plugins/check_tcp.c
@@ -94,7 +94,9 @@ int main(int argc, char **argv) {
 	 * - inet is required for sockets
 	 * - unix is required for Unix domain sockets
 	 * - dns is required for name lookups */
-	pledge("stdio rpath inet unix dns", NULL);
+	if (pledge("stdio rpath inet unix dns", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	setlocale(LC_ALL, "");
@@ -225,7 +227,9 @@ int main(int argc, char **argv) {
 	}
 
 #ifdef __OpenBSD__
-	pledge("stdio inet unix dns", NULL);
+	if (pledge("stdio inet unix dns", NULL)) {
+		die(STATE_UNKNOWN, "pledge: %s", strerror(errno));
+	}
 #endif // __OpenBSD__
 
 	config = paw.config;



More information about the Commits mailing list