Adding expectations to unconfirmed conntracks are problematic because of reallocations of the ct extension area can happen while expectations are placed in the ct extension expectation list. NFQA_EXP was added with the purpose of supporting userspace conntrack helpers, which create expectations in the postrouting hook with priority NF_IP_PRI_CONNTRACK_CONFIRM. Restrict this feature to userspace conntrack helpers. Fixes: bd0779370588 ("netfilter: nfnetlink_queue: allow to attach expectations to conntracks") Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nfnetlink_queue.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 5b45d67e71cd..c2237328cca5 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -1758,10 +1758,30 @@ static struct nf_conn *nfqnl_ct_parse(const struct nfnl_ct_hook *nfnl_ct, if (nfnl_ct->parse(nfqa[NFQA_CT], ct) < 0) return NULL; - if (nfqa[NFQA_EXP]) - nfnl_ct->attach_expect(nfqa[NFQA_EXP], ct, - NETLINK_CB(entry->skb).portid, - nlmsg_report(nlh)); + if (nfqa[NFQA_EXP]) { + const struct nf_hook_entries *hooks; + struct nf_hook_ops **ops; + unsigned int i; + + hooks = nf_queue_hook_entries(entry); + if (!hooks) + return NULL; + + ops = nf_hook_entries_get_hook_ops(hooks); + if (!ops) + return NULL; + + i = entry->hook_index; + if (i >= hooks->num_hook_entries) + return NULL; + + if (ops[i]->hooknum == NF_INET_POST_ROUTING && + ops[i]->priority == NF_IP_PRI_CONNTRACK_CONFIRM) { + nfnl_ct->attach_expect(nfqa[NFQA_EXP], ct, + NETLINK_CB(entry->skb).portid, + nlmsg_report(nlh)); + } + } return ct; #else return NULL; -- 2.47.3