From: Greg Kroah-Hartman Date: Tue, 10 Sep 2019 14:36:52 +0000 (+0100) Subject: 4.4-stable patches X-Git-Tag: v4.4.193~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c980a944e1e92c46cc87bf80bdf26cc66cefd36e;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: xfrm-clean-up-xfrm-protocol-checks.patch --- diff --git a/queue-4.4/series b/queue-4.4/series index ac222d0aa14..f9676ef02c7 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -1,2 +1,3 @@ alsa-hda-fix-potential-endless-loop-at-applying-quirks.patch alsa-hda-realtek-fix-overridden-device-specific-initialization.patch +xfrm-clean-up-xfrm-protocol-checks.patch diff --git a/queue-4.4/xfrm-clean-up-xfrm-protocol-checks.patch b/queue-4.4/xfrm-clean-up-xfrm-protocol-checks.patch new file mode 100644 index 00000000000..18248d5448d --- /dev/null +++ b/queue-4.4/xfrm-clean-up-xfrm-protocol-checks.patch @@ -0,0 +1,116 @@ +From dbb2483b2a46fbaf833cfb5deb5ed9cace9c7399 Mon Sep 17 00:00:00 2001 +From: Cong Wang +Date: Fri, 22 Mar 2019 16:26:19 -0700 +Subject: xfrm: clean up xfrm protocol checks + +From: Cong Wang + +commit dbb2483b2a46fbaf833cfb5deb5ed9cace9c7399 upstream. + +In commit 6a53b7593233 ("xfrm: check id proto in validate_tmpl()") +I introduced a check for xfrm protocol, but according to Herbert +IPSEC_PROTO_ANY should only be used as a wildcard for lookup, so +it should be removed from validate_tmpl(). + +And, IPSEC_PROTO_ANY is expected to only match 3 IPSec-specific +protocols, this is why xfrm_state_flush() could still miss +IPPROTO_ROUTING, which leads that those entries are left in +net->xfrm.state_all before exit net. Fix this by replacing +IPSEC_PROTO_ANY with zero. + +This patch also extracts the check from validate_tmpl() to +xfrm_id_proto_valid() and uses it in parse_ipsecrequest(). +With this, no other protocols should be added into xfrm. + +Fixes: 6a53b7593233 ("xfrm: check id proto in validate_tmpl()") +Reported-by: syzbot+0bf0519d6e0de15914fe@syzkaller.appspotmail.com +Cc: Steffen Klassert +Cc: Herbert Xu +Signed-off-by: Cong Wang +Acked-by: Herbert Xu +Signed-off-by: Steffen Klassert +Signed-off-by: Zubin Mithra +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/xfrm.h | 17 +++++++++++++++++ + net/key/af_key.c | 4 +++- + net/xfrm/xfrm_state.c | 2 +- + net/xfrm/xfrm_user.c | 14 +------------- + 4 files changed, 22 insertions(+), 15 deletions(-) + +--- a/include/net/xfrm.h ++++ b/include/net/xfrm.h +@@ -1301,6 +1301,23 @@ static inline int xfrm_state_kern(const + return atomic_read(&x->tunnel_users); + } + ++static inline bool xfrm_id_proto_valid(u8 proto) ++{ ++ switch (proto) { ++ case IPPROTO_AH: ++ case IPPROTO_ESP: ++ case IPPROTO_COMP: ++#if IS_ENABLED(CONFIG_IPV6) ++ case IPPROTO_ROUTING: ++ case IPPROTO_DSTOPTS: ++#endif ++ return true; ++ default: ++ return false; ++ } ++} ++ ++/* IPSEC_PROTO_ANY only matches 3 IPsec protocols, 0 could match all. */ + static inline int xfrm_id_proto_match(u8 proto, u8 userproto) + { + return (!userproto || proto == userproto || +--- a/net/key/af_key.c ++++ b/net/key/af_key.c +@@ -1969,8 +1969,10 @@ parse_ipsecrequest(struct xfrm_policy *x + + if (rq->sadb_x_ipsecrequest_mode == 0) + return -EINVAL; ++ if (!xfrm_id_proto_valid(rq->sadb_x_ipsecrequest_proto)) ++ return -EINVAL; + +- t->id.proto = rq->sadb_x_ipsecrequest_proto; /* XXX check proto */ ++ t->id.proto = rq->sadb_x_ipsecrequest_proto; + if ((mode = pfkey_mode_to_xfrm(rq->sadb_x_ipsecrequest_mode)) < 0) + return -EINVAL; + t->mode = mode; +--- a/net/xfrm/xfrm_state.c ++++ b/net/xfrm/xfrm_state.c +@@ -2133,7 +2133,7 @@ void xfrm_state_fini(struct net *net) + unsigned int sz; + + flush_work(&net->xfrm.state_hash_work); +- xfrm_state_flush(net, IPSEC_PROTO_ANY, false); ++ xfrm_state_flush(net, 0, false); + flush_work(&net->xfrm.state_gc_work); + + WARN_ON(!list_empty(&net->xfrm.state_all)); +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -1448,20 +1448,8 @@ static int validate_tmpl(int nr, struct + return -EINVAL; + } + +- switch (ut[i].id.proto) { +- case IPPROTO_AH: +- case IPPROTO_ESP: +- case IPPROTO_COMP: +-#if IS_ENABLED(CONFIG_IPV6) +- case IPPROTO_ROUTING: +- case IPPROTO_DSTOPTS: +-#endif +- case IPSEC_PROTO_ANY: +- break; +- default: ++ if (!xfrm_id_proto_valid(ut[i].id.proto)) + return -EINVAL; +- } +- + } + + return 0;