Message ID | 20230201132258.37913-2-andrei.gherzan@canonical.com |
---|---|
State | New |
Headers | show |
Series | [1/1] xfrm: xfrm_policy: fix a possible double xfrm_pols_put() in xfrm_bundle_lookup() | expand |
On 23/02/01 01:22PM, Andrei Gherzan wrote: > From: Hangyu Hua <hbh25y@gmail.com> > > xfrm_policy_lookup() will call xfrm_pol_hold_rcu() to get a refcount of > pols[0]. This refcount can be dropped in xfrm_expand_policies() when > xfrm_expand_policies() return error. pols[0]'s refcount is balanced in > here. But xfrm_bundle_lookup() will also call xfrm_pols_put() with > num_pols == 1 to drop this refcount when xfrm_expand_policies() return > error. > > This patch also fix an illegal address access. pols[0] will save a error > point when xfrm_policy_lookup fails. This lead to xfrm_pols_put to resolve > an illegal address in xfrm_bundle_lookup's error path. > > Fix these by setting num_pols = 0 in xfrm_expand_policies()'s error path. > > Fixes: 80c802f3073e ("xfrm: cache bundles instead of policies for outgoing flows") > Signed-off-by: Hangyu Hua <hbh25y@gmail.com> > Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> > CVE-2022-36879 > (cherry picked from commit f85daf0e725358be78dfd208dea5fd665d8cb901) > Signed-off-by: Andrei Gherzan <andrei.gherzan at canonical.com> > --- > net/xfrm/xfrm_policy.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c > index 19aa994f5d2c..96bad1e38f7d 100644 > --- a/net/xfrm/xfrm_policy.c > +++ b/net/xfrm/xfrm_policy.c > @@ -2676,8 +2676,10 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family, > *num_xfrms = 0; > return 0; > } > - if (IS_ERR(pols[0])) > + if (IS_ERR(pols[0])) { > + *num_pols = 0; > return PTR_ERR(pols[0]); > + } > > *num_xfrms = pols[0]->xfrm_nr; > > @@ -2692,6 +2694,7 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family, > if (pols[1]) { > if (IS_ERR(pols[1])) { > xfrm_pols_put(pols, *num_pols); > + *num_pols = 0; > return PTR_ERR(pols[1]); > } > (*num_pols)++; The actual patch didn't end up with the right tags. I can send a v2 for clarity. Otherwise consider the tags from the associated cover letter: [SRU][Jammy/oem-5.17][Focal/oem-5.14][PATCH 1/1]
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 19aa994f5d2c..96bad1e38f7d 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -2676,8 +2676,10 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family, *num_xfrms = 0; return 0; } - if (IS_ERR(pols[0])) + if (IS_ERR(pols[0])) { + *num_pols = 0; return PTR_ERR(pols[0]); + } *num_xfrms = pols[0]->xfrm_nr; @@ -2692,6 +2694,7 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family, if (pols[1]) { if (IS_ERR(pols[1])) { xfrm_pols_put(pols, *num_pols); + *num_pols = 0; return PTR_ERR(pols[1]); } (*num_pols)++;