From 649b8ce38fc8d90127e8c3d5d62a494a86fb1a01 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 18 Jul 2022 16:18:33 +0200 Subject: 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. Signed-off-by: Pablo Neira Ayuso --- src/cache.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) (limited to 'src') diff --git a/src/cache.c b/src/cache.c index 9e2fe950..b61710b2 100644 --- a/src/cache.c +++ b/src/cache.c @@ -16,6 +16,7 @@ #include #include #include +#include static unsigned int evaluate_cache_add(struct cmd *cmd, unsigned int flags) { @@ -262,6 +263,108 @@ static unsigned int evaluate_cache_list(struct nft_ctx *nft, struct cmd *cmd, 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; +} + int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds, struct list_head *msgs, struct nft_cache_filter *filter, unsigned int *pflags) @@ -270,6 +373,9 @@ int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds, struct cmd *cmd; list_for_each_entry(cmd, cmds, list) { + if (nft_handle_validate(cmd, msgs) < 0) + return -1; + if (filter->list.table && cmd->op != CMD_LIST) memset(&filter->list, 0, sizeof(filter->list)); -- cgit v1.2.3