Don't start e.g. parsing a block device. nftables is typically run as privileged user, exit early if we get unexpected input. Only exception: Allow character device if input is /dev/stdin. Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1664 Signed-off-by: Florian Westphal <fw@xxxxxxxxx> --- src/libnftables.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/libnftables.c b/src/libnftables.c index c5f5729409d1..b143c9b562a7 100644 --- a/src/libnftables.c +++ b/src/libnftables.c @@ -17,6 +17,7 @@ #include <cmd.h> #include <errno.h> #include <string.h> +#include <sys/stat.h> static int nft_netlink(struct nft_ctx *nft, struct list_head *cmds, struct list_head *msgs) @@ -673,13 +674,46 @@ retry: return rc; } +/* need to use stat() to, fopen() will block for named fifos and + * libjansson makes no checks before or after open either. + */ +static struct error_record *filename_is_useable(struct nft_ctx *nft, const char *name) +{ + unsigned int type; + struct stat sb; + int err; + + err = stat(name, &sb); + if (err) + return error(&internal_location, "Could not open file \"%s\": %s\n", + name, strerror(errno)); + + type = sb.st_mode & S_IFMT; + + if (type == S_IFREG || type == S_IFIFO) + return NULL; + + if (type == S_IFCHR && 0 == strcmp(name, "/dev/stdin")) + return NULL; + + return error(&internal_location, "Not a regular file: \"%s\"\n", name); +} + static int __nft_run_cmd_from_filename(struct nft_ctx *nft, const char *filename) { + struct error_record *erec; struct cmd *cmd, *next; int rc, parser_rc; LIST_HEAD(msgs); LIST_HEAD(cmds); + erec = filename_is_useable(nft, filename); + if (erec) { + erec_print(&nft->output, erec, nft->debug_mask); + erec_destroy(erec); + return -1; + } + rc = load_cmdline_vars(nft, &msgs); if (rc < 0) goto err; -- 2.41.0