diff options
author | Colin Watson <cjwatson@debian.org> | 2022-01-30 15:03:39 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2022-01-30 15:03:40 +0000 |
commit | 43aa5a2b077fafa7b5239302d6e41f42830bf6ac (patch) | |
tree | ac58ae008d16b9fe9b02bd4b05ec81ca27de26c0 /lib | |
parent | b3f2788945722093b3c9e95eb4905395a634d9f5 (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.am | 2 | ||||
-rw-r--r-- | lib/fatal.c | 48 | ||||
-rw-r--r-- | lib/fatal.h | 26 | ||||
-rw-r--r-- | lib/pathsearch.c | 7 | ||||
-rw-r--r-- | lib/sandbox.c | 13 | ||||
-rw-r--r-- | lib/security.c | 7 | ||||
-rw-r--r-- | lib/xregcomp.c | 4 |
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); } } |