From 1f5834262c91d835414b538857b67e058a1c1dac Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 8 Dec 2008 23:58:31 +0100 Subject: parse: strict attribute size checking This patch adds strict attribute size checking. This is good to detect corrupted or malformed messages. Signed-off-by: Pablo Neira Ayuso --- include/network.h | 2 ++ src/parse.c | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/include/network.h b/include/network.h index 96a0185..9098e5c 100644 --- a/include/network.h +++ b/include/network.h @@ -161,6 +161,8 @@ struct netattr { x->nta_attr = ntohs(x->nta_attr); \ }) +#define NTA_SIZE(len) NTA_ALIGN(sizeof(struct netattr)) + len + #define NTA_DATA(x) \ (void *)(((char *)x) + NTA_ALIGN(sizeof(struct netattr))) diff --git a/src/parse.c b/src/parse.c index 17a0107..75daac1 100644 --- a/src/parse.c +++ b/src/parse.c @@ -33,75 +33,93 @@ static void parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data); struct parser { void (*parse)(struct nf_conntrack *ct, int attr, void *data); int attr; + int size; }; static struct parser h[NTA_MAX] = { [NTA_IPV4] = { .parse = parse_group, .attr = ATTR_GRP_ORIG_IPV4, + .size = NTA_SIZE(sizeof(struct nfct_attr_grp_ipv4)), }, [NTA_IPV6] = { .parse = parse_group, .attr = ATTR_GRP_ORIG_IPV6, + .size = NTA_SIZE(sizeof(struct nfct_attr_grp_ipv6)), }, [NTA_PORT] = { .parse = parse_group, .attr = ATTR_GRP_ORIG_PORT, + .size = NTA_SIZE(sizeof(struct nfct_attr_grp_port)), }, [NTA_L4PROTO] = { .parse = parse_u8, .attr = ATTR_L4PROTO, + .size = NTA_SIZE(sizeof(uint8_t)), }, [NTA_STATE] = { .parse = parse_u8, .attr = ATTR_TCP_STATE, + .size = NTA_SIZE(sizeof(uint8_t)), }, [NTA_STATUS] = { .parse = parse_u32, .attr = ATTR_STATUS, + .size = NTA_SIZE(sizeof(uint32_t)), }, [NTA_MARK] = { .parse = parse_u32, .attr = ATTR_MARK, + .size = NTA_SIZE(sizeof(uint32_t)), }, [NTA_TIMEOUT] = { .parse = parse_u32, .attr = ATTR_TIMEOUT, + .size = NTA_SIZE(sizeof(uint32_t)), }, [NTA_MASTER_IPV4] = { .parse = parse_group, .attr = ATTR_GRP_MASTER_IPV4, + .size = NTA_SIZE(sizeof(struct nfct_attr_grp_ipv4)), }, [NTA_MASTER_IPV6] = { .parse = parse_group, .attr = ATTR_GRP_MASTER_IPV6, + .size = NTA_SIZE(sizeof(struct nfct_attr_grp_ipv6)), }, [NTA_MASTER_L4PROTO] = { .parse = parse_u8, .attr = ATTR_MASTER_L4PROTO, + .size = NTA_SIZE(sizeof(uint8_t)), }, [NTA_MASTER_PORT] = { .parse = parse_group, .attr = ATTR_GRP_MASTER_PORT, + .size = NTA_SIZE(sizeof(struct nfct_attr_grp_port)), }, [NTA_SNAT_IPV4] = { .parse = parse_u32, .attr = ATTR_SNAT_IPV4, + .size = NTA_SIZE(sizeof(uint32_t)), }, [NTA_DNAT_IPV4] = { .parse = parse_u32, .attr = ATTR_DNAT_IPV4, + .size = NTA_SIZE(sizeof(uint32_t)), }, [NTA_SPAT_PORT] = { .parse = parse_u16, .attr = ATTR_SNAT_PORT, + .size = NTA_SIZE(sizeof(uint16_t)), }, [NTA_DPAT_PORT] = { .parse = parse_u16, .attr = ATTR_SNAT_PORT, + .size = NTA_SIZE(sizeof(uint16_t)), }, [NTA_NAT_SEQ_ADJ] = { .parse = parse_nat_seq_adj, + .size = NTA_SIZE(sizeof(struct nta_attr_natseqadj)), }, }; @@ -165,6 +183,8 @@ int parse_payload(struct nf_conntrack *ct, struct nethdr *net, size_t remain) ATTR_NETWORK2HOST(attr); if (attr->nta_len > len) return -1; + if (attr->nta_len != h[attr->nta_attr].size) + return -1; if (h[attr->nta_attr].parse == NULL) { attr = NTA_NEXT(attr, len); continue; -- cgit v1.2.3