summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2008-12-08 23:58:31 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2008-12-08 23:58:31 +0100
commit1f5834262c91d835414b538857b67e058a1c1dac (patch)
tree2c399462a8d2f8e4a454a2d11fe50483b6f6f33a
parent63c3ae0f664ea7045446c4117646f767a5ccd647 (diff)
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 <pablo@netfilter.org>
-rw-r--r--include/network.h2
-rw-r--r--src/parse.c20
2 files changed, 22 insertions, 0 deletions
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;