diff options
author | Florian Westphal <fw@strlen.de> | 2023-09-14 11:42:15 +0200 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2023-09-29 12:52:13 +0200 |
commit | 149b1c95d129f8ec8a3df16aeca0e9063e8d45bf (patch) | |
tree | 2d49ad0b7d72ad697449fd1d4e1b56c8008674d7 /src/libnftables.c | |
parent | 4e8aa050312822400124260bf6b630c3c05cb04d (diff) |
libnftables: refuse to open onput files other than named pipes or regular files
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>
Diffstat (limited to 'src/libnftables.c')
-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 4b4cf5b6..41f54c0c 100644 --- a/src/libnftables.c +++ b/src/libnftables.c @@ -16,6 +16,7 @@ #include <iface.h> #include <cmd.h> #include <errno.h> +#include <sys/stat.h> static int nft_netlink(struct nft_ctx *nft, struct list_head *cmds, struct list_head *msgs) @@ -660,13 +661,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; |