[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