[PATCH nf-next] netfilter: x_tables: reject missing '-p' flag and check for INV flag
Florian Westphal <[email protected]>
| Newsgroups | gmane.comp.security.firewalls.netfilter.devel |
|---|---|
| Message-ID | <[email protected]> |
ip6tables traverser doesn't walk ipv6 extension headers unless the PROTO flag is set, so direct sockopt-users can bypass the check (ip6tables always sets it if '-p' flag is given. This is a cleanup patch, it doesn't fix any real bug. Reported-by: Zhiling Zou <[email protected]> Fixes: 74f77a6b2b1c ("netfilter: introduce l2tp match extension") Fixes: af0d29cd2a73 ("netfilter: xtables: add an IPv6 capable version of the ECN match") Fixes: a89ecb6a2ef7 ("[NETFILTER]: x_tables: unify IPv4/IPv6 multiport match") Signed-off-by: Florian Westphal <[email protected]> --- Can also be applied to nf, but I don't think this one is urgent. net/netfilter/xt_ecn.c | 3 ++- net/netfilter/xt_l2tp.c | 11 +++++++---- net/netfilter/xt_multiport.c | 3 +++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/net/netfilter/xt_ecn.c b/net/netfilter/xt_ecn.c index a8503f5d26bf..008e7fcbeb22 100644 --- a/net/netfilter/xt_ecn.c +++ b/net/netfilter/xt_ecn.c @@ -139,7 +139,8 @@ static int ecn_mt_check6(const struct xt_mtchk_param *par) return -EINVAL; if (info->operation & (XT_ECN_OP_MATCH_ECE | XT_ECN_OP_MATCH_CWR) && - (ip->proto != IPPROTO_TCP || ip->invflags & IP6T_INV_PROTO)) { + (!(ip->flags & IP6T_F_PROTO) || + ip->proto != IPPROTO_TCP || ip->invflags & IP6T_INV_PROTO)) { pr_info_ratelimited("cannot match TCP bits for non-tcp packets\n"); return -EINVAL; } diff --git a/net/netfilter/xt_l2tp.c b/net/netfilter/xt_l2tp.c index a61eb81e9f49..ad2d559caa99 100644 --- a/net/netfilter/xt_l2tp.c +++ b/net/netfilter/xt_l2tp.c @@ -267,8 +267,9 @@ static int l2tp_mt_check4(const struct xt_mtchk_param *par) if (ret != 0) return ret; - if ((ip->proto != IPPROTO_UDP) && - (ip->proto != IPPROTO_L2TP)) { + if (ip->invflags & IPT_INV_PROTO || + (ip->proto != IPPROTO_UDP && + ip->proto != IPPROTO_L2TP)) { pr_info_ratelimited("missing protocol rule (udp|l2tpip)\n"); return -EINVAL; } @@ -294,8 +295,10 @@ static int l2tp_mt_check6(const struct xt_mtchk_param *par) if (ret != 0) return ret; - if ((ip->proto != IPPROTO_UDP) && - (ip->proto != IPPROTO_L2TP)) { + if (((ip->flags & IP6T_F_PROTO) == 0 || + ip->invflags & IP6T_INV_PROTO || + (ip->proto != IPPROTO_UDP && + ip->proto != IPPROTO_L2TP))) { pr_info_ratelimited("missing protocol rule (udp|l2tpip)\n"); return -EINVAL; } diff --git a/net/netfilter/xt_multiport.c b/net/netfilter/xt_multiport.c index a1691ff405d3..48aa25749063 100644 --- a/net/netfilter/xt_multiport.c +++ b/net/netfilter/xt_multiport.c @@ -160,6 +160,9 @@ static int multiport_mt6_check(const struct xt_mtchk_param *par) const struct ip6t_ip6 *ip = par->entryinfo; const struct xt_multiport_v1 *multiinfo = par->matchinfo; + if (!(ip->flags & IP6T_F_PROTO)) + return -EINVAL; + if (!check(ip->proto, ip->invflags, multiinfo->flags, multiinfo->count)) return -EINVAL; -- 2.54.0