xfrm_resolve_and_create_bundle() assumed that, if policies indicated presence of xfrms, bundle template resolution would always return some xfrms. This is not true for 'use' level policies which can result in no xfrm's being applied if there is no suitable xfrm states. This fixes a crash by this incorrect assumption.
Unified · Split
| @@ -1594,8 +1594,8 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols, · 1593 unmodified lines | |||
| 1594 | 1594 | ||
| 1595 | /* Try to instantiate a bundle */ | 1595 | /* Try to instantiate a bundle */ |
| 1596 | err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family); | 1596 | err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family); |
| 1597 | if (err < 0) { | 1597 | if (err <= 0) { |
| 1598 | if (err != -EAGAIN) | 1598 | if (err != 0 && err != -EAGAIN) |
| 1599 | XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR); | 1599 | XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR); |
| 1600 | return ERR_PTR(err); | 1600 | return ERR_PTR(err); |
| 1601 | } | 1601 | } |
| @@ -1678,6 +1678,13 @@ xfrm_bundle_lookup(struct net *net, struct flowi *fl, u16 family, u8 dir, · 76 unmodified lines | |||
| 1678 | goto make_dummy_bundle; | 1678 | goto make_dummy_bundle; |
| 1679 | dst_hold(&xdst->u.dst); | 1679 | dst_hold(&xdst->u.dst); |
| 1680 | return oldflo; | 1680 | return oldflo; |
| 1681 | } else if (new_xdst == NULL) { | ||
| 1682 | num_xfrms = 0; | ||
| 1683 | if (oldflo == NULL) | ||
| 1684 | goto make_dummy_bundle; | ||
| 1685 | xdst->num_xfrms = 0; | ||
| 1686 | dst_hold(&xdst->u.dst); | ||
| 1687 | return oldflo; | ||
| 1681 | } | 1688 | } |
| 1682 | 1689 | ||
| 1683 | /* Kill the previous bundle */ | 1690 | /* Kill the previous bundle */ |
| @@ -1760,6 +1767,10 @@ restart: · 76 unmodified lines | |||
| 1760 | xfrm_pols_put(pols, num_pols); | 1767 | xfrm_pols_put(pols, num_pols); |
| 1761 | err = PTR_ERR(xdst); | 1768 | err = PTR_ERR(xdst); |
| 1762 | goto dropdst; | 1769 | goto dropdst; |
| 1770 | } else if (xdst == NULL) { | ||
| 1771 | num_xfrms = 0; | ||
| 1772 | drop_pols = num_pols; | ||
| 1773 | goto no_transform; | ||
| 1763 | } | 1774 | } |
| 1764 | 1775 | ||
| 1765 | spin_lock_bh(&xfrm_policy_sk_bundle_lock); | 1776 | spin_lock_bh(&xfrm_policy_sk_bundle_lock); |