diff options
author | Florian Westphal <fw@strlen.de> | 2023-09-14 11:42:15 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2023-11-03 12:23:37 +0100 |
commit | 53e5126309eed8fa3154d5424fe5cd6fd7b8c567 (patch) | |
tree | 5f4e92b2c147aa40cd8c0e2169e0e6552652d9b1 | |
parent | 10f6bbbc59e98e8f61e96fa29eaaf48e87b221b8 (diff) |
libnftables: refuse to open onput files other than named pipes or regular files
commit 149b1c95d129f8ec8a3df16aeca0e9063e8d45bf upstream backport.
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@strlen.de>
-rw-r--r-- | src/libnftables.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/libnftables.c b/src/libnftables.c index 58098906..8537d700 100644 --- a/src/libnftables.c +++ b/src/libnftables.c @@ -16,6 +16,7 @@ #include <errno.h> #include <stdlib.h> #include <string.h> +#include <sys/stat.h> static int nft_netlink(struct nft_ctx *nft, struct list_head *cmds, struct list_head *msgs, @@ -657,13 +658,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; |