summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2022-01-30 15:03:39 +0000
committerColin Watson <cjwatson@debian.org>2022-01-30 15:03:40 +0000
commit43aa5a2b077fafa7b5239302d6e41f42830bf6ac (patch)
treeac58ae008d16b9fe9b02bd4b05ec81ca27de26c0 /lib
parentb3f2788945722093b3c9e95eb4905395a634d9f5 (diff)
Simplify static analysis of fatal errors
The usual idiom for fatal error reporting in man-db is `error (FATAL, ...)` (there are a few cases using different exit codes, but they're less common). Unfortunately, there's no easy way to tell the compiler that this call doesn't return, because `error (0, ...)` *does* return. As a result, some call sites required extra work to give the compiler this information, which can sometimes make a difference to static analysis. To simplify this, add a new `fatal` helper function which always exits `FATAL` (i.e. 2) and never returns. This is declared with `_Noreturn` so that the compiler can straightforwardly know what's going on. * bootstrap.conf (gnulib_modules): Add verror. (XGETTEXT_OPTIONS): Add --flag=fatal:2:c-format. * lib/fatal.c, lib/fatal.h: New files. * lib/Makefile.am (libman_la_SOURCES): Add fatal.c and fatal.h. * src/tests/Makefile.am (AM_CPPFLAGS): Add -I$(top_srcdir)/lib. (get_mtime_LDADD): Add $(top_builddir)/lib/libman.la. * lib/pathsearch.c (pathsearch, directory_on_path): Use fatal. * lib/sandbox.c (can_load_seccomp, make_seccomp_filter, _sandbox_load): Likewise. * lib/security.c (gripe_set_euid): Likewise. * lib/xregcomp.c (xregcomp): Likewise. * libdb/db_lookup.c (gripe_corrupt_data, dblookup_pattern): Likewise. * libdb/db_ver.c (dbver_wr): Likewise. * src/accessdb.c (main): Likewise. * src/catman.c (parse_for_sec): Likewise. * src/check_mandirs.c (chown_if_possible): Likewise. * src/man-recode.c (recode): Likewise. * src/man.c (open_cat_stream, format_display, gripe_converting_name): Likewise. * src/manconv.c (add_output): Likewise. * src/manp.c (add_dir_to_path_list): Likewise. * src/tests/get-mtime.c (main): Likewise. * src/whatis.c (do_apropos): Likewise. * src/zsoelim.l (<so>\"?[^ \t\n\"]+\"?): Likewise. * libdb/db_lookup.c (gripe_corrupt_data, gripe_replace_key): Declare as _Noreturn. * src/accessdb.c (main): Remove now-unnecessary assertion. * src/man.c (gripe_converting_name): Remove now-unnecessary abort.
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/fatal.c48
-rw-r--r--lib/fatal.h26
-rw-r--r--lib/pathsearch.c7
-rw-r--r--lib/sandbox.c13
-rw-r--r--lib/security.c7
-rw-r--r--lib/xregcomp.c4
7 files changed, 92 insertions, 15 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 7ced9a2c..475fea04 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -40,6 +40,8 @@ libman_la_SOURCES = \
debug.h \
encodings.c \
encodings.h \
+ fatal.c \
+ fatal.h \
glcontainers.c \
glcontainers.h \
linelength.c \
diff --git a/lib/fatal.c b/lib/fatal.c
new file mode 100644
index 00000000..b2b78954
--- /dev/null
+++ b/lib/fatal.c
@@ -0,0 +1,48 @@
+/*
+ * fatal.c: fatal error helper
+ *
+ * Copyright (C) 2022 Colin Watson.
+ *
+ * This file is part of man-db.
+ *
+ * man-db is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * man-db is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with man-db; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include "verror.h"
+
+#include "manconfig.h"
+
+#include "fatal.h"
+
+void fatal (int errnum, const char *format, ...)
+{
+ va_list ap;
+
+ va_start (ap, format);
+ verror (FATAL, errnum, format, ap);
+ va_end (ap);
+
+ /* Never reached, because verror exits if given a non-zero status,
+ * but the compiler may not be able to prove that.
+ */
+ abort ();
+}
diff --git a/lib/fatal.h b/lib/fatal.h
new file mode 100644
index 00000000..7cc299e9
--- /dev/null
+++ b/lib/fatal.h
@@ -0,0 +1,26 @@
+/*
+ * fatal.h: interface to fatal error helper
+ *
+ * Copyright (C) 2022 Colin Watson.
+ *
+ * This file is part of man-db.
+ *
+ * man-db is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * man-db is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with man-db; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "attribute.h"
+
+_Noreturn void fatal (int errnum, const char *format, ...)
+ ATTRIBUTE_FORMAT ((__printf__, 2, 3));
diff --git a/lib/pathsearch.c b/lib/pathsearch.c
index 59b8910f..34eac082 100644
--- a/lib/pathsearch.c
+++ b/lib/pathsearch.c
@@ -37,12 +37,13 @@
#include "gettext.h"
#define _(String) gettext (String)
-#include "error.h"
#include "xalloc.h"
#include "xgetcwd.h"
#include "xvasprintf.h"
#include "manconfig.h"
+
+#include "fatal.h"
#include "pathsearch.h"
static bool pathsearch (const char *name, const mode_t bits)
@@ -78,7 +79,7 @@ static bool pathsearch (const char *name, const mode_t bits)
if (!cwd)
cwd = xgetcwd ();
if (!cwd)
- error (FATAL, errno,
+ fatal (errno,
_("can't determine current directory"));
element = cwd;
}
@@ -128,7 +129,7 @@ bool directory_on_path (const char *dir)
if (!cwd)
cwd = xgetcwd ();
if (!cwd)
- error (FATAL, errno,
+ fatal (errno,
_("can't determine current directory"));
element = cwd;
}
diff --git a/lib/sandbox.c b/lib/sandbox.c
index 798e6d77..bfda5e30 100644
--- a/lib/sandbox.c
+++ b/lib/sandbox.c
@@ -64,13 +64,13 @@
#endif /* HAVE_LIBSECCOMP */
#include "attribute.h"
-#include "error.h"
#include "xalloc.h"
#include "xstrndup.h"
#include "manconfig.h"
#include "debug.h"
+#include "fatal.h"
#include "sandbox.h"
struct man_sandbox {
@@ -194,7 +194,7 @@ static bool can_load_seccomp (void)
if (nr == __NR_SCMP_ERROR) \
break; \
if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, nr, 0) < 0) \
- error (FATAL, errno, "can't add seccomp rule"); \
+ fatal (errno, "can't add seccomp rule"); \
} while (0)
#define SC_ALLOW_PERMISSIVE(name) \
@@ -209,7 +209,7 @@ static bool can_load_seccomp (void)
if (nr == __NR_SCMP_ERROR) \
break; \
if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, nr, 1, cmp1) < 0) \
- error (FATAL, errno, "can't add seccomp rule"); \
+ fatal (errno, "can't add seccomp rule"); \
} while (0)
#define SC_ALLOW_ARG_2(name, cmp1, cmp2) \
@@ -219,7 +219,7 @@ static bool can_load_seccomp (void)
break; \
if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, nr, \
2, cmp1, cmp2) < 0) \
- error (FATAL, errno, "can't add seccomp rule"); \
+ fatal (errno, "can't add seccomp rule"); \
} while (0)
/* Create a seccomp filter.
@@ -247,7 +247,7 @@ static scmp_filter_ctx make_seccomp_filter (int permissive)
debug ("initialising seccomp filter (permissive: %d)\n", permissive);
ctx = seccomp_init (SCMP_ACT_ERRNO (ENOSYS));
if (!ctx)
- error (FATAL, errno, "can't initialise seccomp filter");
+ fatal (errno, "can't initialise seccomp filter");
/* Allow sibling architectures for x86, since people sometimes mix
* and match architectures there for performance reasons.
@@ -621,8 +621,7 @@ static void _sandbox_load (man_sandbox *sandbox, int permissive) {
/* Don't try this again. */
seccomp_filter_unavailable = 1;
} else
- error (FATAL, errno,
- "can't load seccomp filter");
+ fatal (errno, "can't load seccomp filter");
}
}
}
diff --git a/lib/security.c b/lib/security.c
index 998edb68..676e6d79 100644
--- a/lib/security.c
+++ b/lib/security.c
@@ -36,16 +36,17 @@
#include <sys/types.h>
#include "attribute.h"
+#include "error.h"
#include "gettext.h"
#define _(String) gettext (String)
#include "manconfig.h"
-#include "error.h"
-#include "cleanup.h"
#include "pipeline.h"
+#include "cleanup.h"
#include "debug.h"
+#include "fatal.h"
#include "security.h"
#ifdef MAN_OWNER
@@ -78,7 +79,7 @@ static int priv_drop_count = 0;
static void gripe_set_euid (void)
{
- error (FATAL, errno, _("can't set effective uid"));
+ fatal (errno, _("can't set effective uid"));
}
#endif /* MAN_OWNER */
diff --git a/lib/xregcomp.c b/lib/xregcomp.c
index 6d215514..d8e1f180 100644
--- a/lib/xregcomp.c
+++ b/lib/xregcomp.c
@@ -34,7 +34,7 @@
#include "manconfig.h"
-#include "error.h"
+#include "fatal.h"
#include "xalloc.h"
#include "xregcomp.h"
@@ -47,6 +47,6 @@ void xregcomp (regex_t *preg, const char *regex, int cflags)
errstrsize = regerror (err, preg, NULL, 0);
errstr = xmalloc (errstrsize);
regerror (err, preg, errstr, errstrsize);
- error (FATAL, 0, _("fatal: regex `%s': %s"), regex, errstr);
+ fatal (0, _("fatal: regex `%s': %s"), regex, errstr);
}
}