Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: ctnetlink: fix mark based dump filtering regression

conntrack mark based dump filtering may falsely skip entries if a mask
is given: If the mask-based check does not filter out the entry, the
else-if check is always true and compares the mark without considering
the mask. The if/else-if logic seems wrong.

Given that the mask during filter setup is implicitly set to 0xffffffff
if not specified explicitly, the mark filtering flags seem to just
complicate things. Restore the previously used approach by always
matching against a zero mask is no filter mark is given.

Fixes: cb8aa9a3affb ("netfilter: ctnetlink: add kernel side filtering for dump")
Signed-off-by: Martin Willi <martin@strongswan.org>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Martin Willi and committed by
Pablo Neira Ayuso
6c0d95d1 67cc570e

+3 -16
+3 -16
net/netfilter/nf_conntrack_netlink.c
··· 851 851 } 852 852 853 853 struct ctnetlink_filter { 854 - u_int32_t cta_flags; 855 854 u8 family; 856 855 857 856 u_int32_t orig_flags; ··· 905 906 struct nf_conntrack_zone *zone, 906 907 u_int32_t flags); 907 908 908 - /* applied on filters */ 909 - #define CTA_FILTER_F_CTA_MARK (1 << 0) 910 - #define CTA_FILTER_F_CTA_MARK_MASK (1 << 1) 911 - 912 909 static struct ctnetlink_filter * 913 910 ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family) 914 911 { ··· 925 930 #ifdef CONFIG_NF_CONNTRACK_MARK 926 931 if (cda[CTA_MARK]) { 927 932 filter->mark.val = ntohl(nla_get_be32(cda[CTA_MARK])); 928 - filter->cta_flags |= CTA_FILTER_FLAG(CTA_MARK); 929 - 930 - if (cda[CTA_MARK_MASK]) { 933 + if (cda[CTA_MARK_MASK]) 931 934 filter->mark.mask = ntohl(nla_get_be32(cda[CTA_MARK_MASK])); 932 - filter->cta_flags |= CTA_FILTER_FLAG(CTA_MARK_MASK); 933 - } else { 935 + else 934 936 filter->mark.mask = 0xffffffff; 935 - } 936 937 } else if (cda[CTA_MARK_MASK]) { 937 938 err = -EINVAL; 938 939 goto err_filter; ··· 1108 1117 } 1109 1118 1110 1119 #ifdef CONFIG_NF_CONNTRACK_MARK 1111 - if ((filter->cta_flags & CTA_FILTER_FLAG(CTA_MARK_MASK)) && 1112 - (ct->mark & filter->mark.mask) != filter->mark.val) 1113 - goto ignore_entry; 1114 - else if ((filter->cta_flags & CTA_FILTER_FLAG(CTA_MARK)) && 1115 - ct->mark != filter->mark.val) 1120 + if ((ct->mark & filter->mark.mask) != filter->mark.val) 1116 1121 goto ignore_entry; 1117 1122 #endif 1118 1123