158 lines
4.0 KiB
Diff
158 lines
4.0 KiB
Diff
|
|
From 649b8ce38fc8d90127e8c3d5d62a494a86fb1a01 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Pablo Neira Ayuso <pablo@netfilter.org>
|
||
|
|
Date: Mon, 18 Jul 2022 16:18:33 +0200
|
||
|
|
Subject: [PATCH] cache: validate handle string length
|
||
|
|
|
||
|
|
Maximum supported string length for handle is NFT_NAME_MAXLEN, report an
|
||
|
|
error if user is exceeding this limit.
|
||
|
|
|
||
|
|
By validating from the cache evaluation phase, input is validated for the
|
||
|
|
native and json parsers.
|
||
|
|
|
||
|
|
Conflict: add struct list_head *msgs;
|
||
|
|
Reference: https://git.netfilter.org/nftables/commit?id=649b8ce38fc8d90127e8c3d5d62a494a86fb1a01
|
||
|
|
|
||
|
|
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||
|
|
---
|
||
|
|
src/cache.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
1 file changed, 108 insertions(+)
|
||
|
|
|
||
|
|
diff --git a/src/cache.c b/src/cache.c
|
||
|
|
index c1f0972..828e4cc 100644
|
||
|
|
--- a/src/cache.c
|
||
|
|
+++ b/src/cache.c
|
||
|
|
@@ -16,6 +16,7 @@
|
||
|
|
#include <mnl.h>
|
||
|
|
#include <libnftnl/chain.h>
|
||
|
|
#include <linux/netfilter.h>
|
||
|
|
+#include <linux/netfilter/nf_tables.h>
|
||
|
|
|
||
|
|
static unsigned int evaluate_cache_add(struct cmd *cmd, unsigned int flags)
|
||
|
|
{
|
||
|
|
@@ -58,6 +59,109 @@ static unsigned int evaluate_cache_add(struct cmd *cmd, unsigned int flags)
|
||
|
|
return flags;
|
||
|
|
}
|
||
|
|
|
||
|
|
+static int nft_handle_validate(const struct cmd *cmd, struct list_head *msgs)
|
||
|
|
+{
|
||
|
|
+ const struct handle *h = &cmd->handle;
|
||
|
|
+ const struct location *loc;
|
||
|
|
+
|
||
|
|
+ switch (cmd->obj) {
|
||
|
|
+ case CMD_OBJ_TABLE:
|
||
|
|
+ if (h->table.name &&
|
||
|
|
+ strlen(h->table.name) > NFT_NAME_MAXLEN) {
|
||
|
|
+ loc = &h->table.location;
|
||
|
|
+ goto err_name_too_long;
|
||
|
|
+ }
|
||
|
|
+ break;
|
||
|
|
+ case CMD_OBJ_RULE:
|
||
|
|
+ case CMD_OBJ_CHAIN:
|
||
|
|
+ case CMD_OBJ_CHAINS:
|
||
|
|
+ if (h->table.name &&
|
||
|
|
+ strlen(h->table.name) > NFT_NAME_MAXLEN) {
|
||
|
|
+ loc = &h->table.location;
|
||
|
|
+ goto err_name_too_long;
|
||
|
|
+ }
|
||
|
|
+ if (h->chain.name &&
|
||
|
|
+ strlen(h->chain.name) > NFT_NAME_MAXLEN) {
|
||
|
|
+ loc = &h->chain.location;
|
||
|
|
+ goto err_name_too_long;
|
||
|
|
+ }
|
||
|
|
+ break;
|
||
|
|
+ case CMD_OBJ_ELEMENTS:
|
||
|
|
+ case CMD_OBJ_SET:
|
||
|
|
+ case CMD_OBJ_SETS:
|
||
|
|
+ case CMD_OBJ_MAP:
|
||
|
|
+ case CMD_OBJ_MAPS:
|
||
|
|
+ case CMD_OBJ_METER:
|
||
|
|
+ case CMD_OBJ_METERS:
|
||
|
|
+ if (h->table.name &&
|
||
|
|
+ strlen(h->table.name) > NFT_NAME_MAXLEN) {
|
||
|
|
+ loc = &h->table.location;
|
||
|
|
+ goto err_name_too_long;
|
||
|
|
+ }
|
||
|
|
+ if (h->set.name &&
|
||
|
|
+ strlen(h->set.name) > NFT_NAME_MAXLEN) {
|
||
|
|
+ loc = &h->set.location;
|
||
|
|
+ goto err_name_too_long;
|
||
|
|
+ }
|
||
|
|
+ break;
|
||
|
|
+ case CMD_OBJ_FLOWTABLE:
|
||
|
|
+ case CMD_OBJ_FLOWTABLES:
|
||
|
|
+ if (h->table.name &&
|
||
|
|
+ strlen(h->table.name) > NFT_NAME_MAXLEN) {
|
||
|
|
+ loc = &h->table.location;
|
||
|
|
+ goto err_name_too_long;
|
||
|
|
+ }
|
||
|
|
+ if (h->flowtable.name &&
|
||
|
|
+ strlen(h->flowtable.name) > NFT_NAME_MAXLEN) {
|
||
|
|
+ loc = &h->flowtable.location;
|
||
|
|
+ goto err_name_too_long;
|
||
|
|
+ }
|
||
|
|
+ break;
|
||
|
|
+ case CMD_OBJ_INVALID:
|
||
|
|
+ case CMD_OBJ_EXPR:
|
||
|
|
+ case CMD_OBJ_RULESET:
|
||
|
|
+ case CMD_OBJ_MARKUP:
|
||
|
|
+ case CMD_OBJ_MONITOR:
|
||
|
|
+ case CMD_OBJ_SETELEMS:
|
||
|
|
+ case CMD_OBJ_HOOKS:
|
||
|
|
+ break;
|
||
|
|
+ case CMD_OBJ_COUNTER:
|
||
|
|
+ case CMD_OBJ_COUNTERS:
|
||
|
|
+ case CMD_OBJ_QUOTA:
|
||
|
|
+ case CMD_OBJ_QUOTAS:
|
||
|
|
+ case CMD_OBJ_LIMIT:
|
||
|
|
+ case CMD_OBJ_LIMITS:
|
||
|
|
+ case CMD_OBJ_SECMARK:
|
||
|
|
+ case CMD_OBJ_SECMARKS:
|
||
|
|
+ case CMD_OBJ_SYNPROXY:
|
||
|
|
+ case CMD_OBJ_SYNPROXYS:
|
||
|
|
+ case CMD_OBJ_CT_HELPER:
|
||
|
|
+ case CMD_OBJ_CT_HELPERS:
|
||
|
|
+ case CMD_OBJ_CT_TIMEOUT:
|
||
|
|
+ case CMD_OBJ_CT_EXPECT:
|
||
|
|
+ if (h->table.name &&
|
||
|
|
+ strlen(h->table.name) > NFT_NAME_MAXLEN) {
|
||
|
|
+ loc = &h->table.location;
|
||
|
|
+ goto err_name_too_long;
|
||
|
|
+ }
|
||
|
|
+ if (h->obj.name &&
|
||
|
|
+ strlen(h->obj.name) > NFT_NAME_MAXLEN) {
|
||
|
|
+ loc = &h->obj.location;
|
||
|
|
+ goto err_name_too_long;
|
||
|
|
+ }
|
||
|
|
+ break;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return 0;
|
||
|
|
+
|
||
|
|
+err_name_too_long:
|
||
|
|
+ erec_queue(error(loc, "name too long, %d characters maximum allowed",
|
||
|
|
+ NFT_NAME_MAXLEN),
|
||
|
|
+ msgs);
|
||
|
|
+ return -1;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+
|
||
|
|
static unsigned int evaluate_cache_del(struct cmd *cmd, unsigned int flags)
|
||
|
|
{
|
||
|
|
switch (cmd->obj) {
|
||
|
|
@@ -121,8 +225,12 @@ unsigned int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds)
|
||
|
|
{
|
||
|
|
unsigned int flags = NFT_CACHE_EMPTY;
|
||
|
|
struct cmd *cmd;
|
||
|
|
+ struct list_head *msgs;
|
||
|
|
|
||
|
|
list_for_each_entry(cmd, cmds, list) {
|
||
|
|
+ if (nft_handle_validate(cmd, msgs) < 0)
|
||
|
|
+ return -1;
|
||
|
|
+
|
||
|
|
switch (cmd->op) {
|
||
|
|
case CMD_ADD:
|
||
|
|
case CMD_INSERT:
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|