From b55717d46ae3b7c3769192a66e565bc7c2d833a1 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 3 May 2021 22:53:09 +0200 Subject: conntrackd: fix endianness bug in IPv4 and IPv6 address Add ct_parse_be32() and ct_parse_be128() and use them to deal with an IP address which is already in network byte order. Reported-by: Tao Gong Signed-off-by: Pablo Neira Ayuso --- src/build.c | 21 ++++++++++++++------- src/parse.c | 20 ++++++++++++++------ 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/build.c b/src/build.c index 4771997..63e47c7 100644 --- a/src/build.c +++ b/src/build.c @@ -66,7 +66,14 @@ ct_build_u32(const struct nf_conntrack *ct, int a, struct nethdr *n, int b) } static inline void -ct_build_u128(const struct nf_conntrack *ct, int a, struct nethdr *n, int b) +ct_build_be32(const struct nf_conntrack *ct, int a, struct nethdr *n, int b) +{ + uint32_t data = nfct_get_attr_u32(ct, a); + addattr(n, b, &data, sizeof(uint32_t)); +} + +static inline void +ct_build_be128(const struct nf_conntrack *ct, int a, struct nethdr *n, int b) { const char *data = nfct_get_attr(ct, a); addattr(n, b, data, sizeof(uint32_t) * 4); @@ -279,18 +286,18 @@ void ct2msg(const struct nf_conntrack *ct, struct nethdr *n) switch (nfct_get_attr_u8(ct, ATTR_ORIG_L3PROTO)) { case AF_INET: if (nfct_getobjopt(ct, NFCT_GOPT_IS_SNAT)) - ct_build_u32(ct, ATTR_REPL_IPV4_DST, n, NTA_SNAT_IPV4); + ct_build_be32(ct, ATTR_REPL_IPV4_DST, n, NTA_SNAT_IPV4); if (nfct_getobjopt(ct, NFCT_GOPT_IS_DNAT)) - ct_build_u32(ct, ATTR_REPL_IPV4_SRC, n, NTA_DNAT_IPV4); + ct_build_be32(ct, ATTR_REPL_IPV4_SRC, n, NTA_DNAT_IPV4); break; case AF_INET6: if (nfct_getobjopt(ct, NFCT_GOPT_IS_SNAT)) { - ct_build_u128(ct, ATTR_REPL_IPV6_DST, n, - NTA_SNAT_IPV6); + ct_build_be128(ct, ATTR_REPL_IPV6_DST, n, + NTA_SNAT_IPV6); } if (nfct_getobjopt(ct, NFCT_GOPT_IS_DNAT)) { - ct_build_u128(ct, ATTR_REPL_IPV6_SRC, n, - NTA_DNAT_IPV6); + ct_build_be128(ct, ATTR_REPL_IPV6_SRC, n, + NTA_DNAT_IPV6); } break; default: diff --git a/src/parse.c b/src/parse.c index e97a721..eedba66 100644 --- a/src/parse.c +++ b/src/parse.c @@ -29,7 +29,8 @@ static void ct_parse_u8(struct nf_conntrack *ct, int attr, void *data); static void ct_parse_u16(struct nf_conntrack *ct, int attr, void *data); static void ct_parse_u32(struct nf_conntrack *ct, int attr, void *data); -static void ct_parse_u128(struct nf_conntrack *ct, int attr, void *data); +static void ct_parse_be32(struct nf_conntrack *ct, int attr, void *data); +static void ct_parse_be128(struct nf_conntrack *ct, int attr, void *data); static void ct_parse_str(struct nf_conntrack *ct, const struct netattr *, void *data); static void ct_parse_group(struct nf_conntrack *ct, int attr, void *data); @@ -108,12 +109,12 @@ static struct ct_parser h[NTA_MAX] = { .size = NTA_SIZE(sizeof(struct nfct_attr_grp_port)), }, [NTA_SNAT_IPV4] = { - .parse = ct_parse_u32, + .parse = ct_parse_be32, .attr = ATTR_SNAT_IPV4, .size = NTA_SIZE(sizeof(uint32_t)), }, [NTA_DNAT_IPV4] = { - .parse = ct_parse_u32, + .parse = ct_parse_be32, .attr = ATTR_DNAT_IPV4, .size = NTA_SIZE(sizeof(uint32_t)), }, @@ -192,12 +193,12 @@ static struct ct_parser h[NTA_MAX] = { .max_size = NTA_SIZE(NTA_LABELS_MAX_SIZE), }, [NTA_SNAT_IPV6] = { - .parse = ct_parse_u128, + .parse = ct_parse_be128, .attr = ATTR_SNAT_IPV6, .size = NTA_SIZE(sizeof(uint32_t) * 4), }, [NTA_DNAT_IPV6] = { - .parse = ct_parse_u128, + .parse = ct_parse_be128, .attr = ATTR_DNAT_IPV6, .size = NTA_SIZE(sizeof(uint32_t) * 4), }, @@ -234,7 +235,14 @@ ct_parse_u32(struct nf_conntrack *ct, int attr, void *data) } static void -ct_parse_u128(struct nf_conntrack *ct, int attr, void *data) +ct_parse_be32(struct nf_conntrack *ct, int attr, void *data) +{ + uint32_t *value = (uint32_t *) data; + nfct_set_attr_u32(ct, h[attr].attr, *value); +} + +static void +ct_parse_be128(struct nf_conntrack *ct, int attr, void *data) { nfct_set_attr(ct, h[attr].attr, data); } -- cgit v1.2.3