--- a/net/netfilter/nf_nat_proto_common.c +++ b/net/netfilter/nf_nat_proto_common.c @@ -41,7 +41,7 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto, const struct nf_conn *ct, u16 *rover) { - unsigned int range_size, min, i; + unsigned int range_size, min, max, i; __be16 *portptr; u_int16_t off; @@ -70,8 +70,11 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto, range_size = 65535 - 1024 + 1; } } else { - min = ntohs(range->min_proto.all); - range_size = ntohs(range->max_proto.all) - min + 1; + min = ntohs(READ_ONCE(range->min_proto.all)); + max = ntohs(READ_ONCE(range->max_proto.all)); + if (unlikely(max < min)) + swap(min, max); + range_size = max - min + 1; } if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) {