Skip to content

Commit c9f3f81

Browse files
committed
xfrm: Fix stack-out-of-bounds read in xfrm_state_find.
When we do tunnel or beet mode, we pass saddr and daddr from the template to xfrm_state_find(), this is ok. On transport mode, we pass the addresses from the flowi, assuming that the IP addresses (and address family) don't change during transformation. This assumption is wrong in the IPv4 mapped IPv6 case, packet is IPv4 and template is IPv6. Fix this by using the addresses from the template unconditionally. Signed-off-by: Steffen Klassert <[email protected]>
1 parent cf37966 commit c9f3f81

File tree

1 file changed

+11
-18
lines changed

1 file changed

+11
-18
lines changed

net/xfrm/xfrm_policy.c

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,36 +1361,29 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, const struct flowi *fl,
13611361
struct net *net = xp_net(policy);
13621362
int nx;
13631363
int i, error;
1364-
xfrm_address_t *daddr = xfrm_flowi_daddr(fl, family);
1365-
xfrm_address_t *saddr = xfrm_flowi_saddr(fl, family);
13661364
xfrm_address_t tmp;
13671365

13681366
for (nx = 0, i = 0; i < policy->xfrm_nr; i++) {
13691367
struct xfrm_state *x;
1370-
xfrm_address_t *remote = daddr;
1371-
xfrm_address_t *local = saddr;
1368+
xfrm_address_t *local;
1369+
xfrm_address_t *remote;
13721370
struct xfrm_tmpl *tmpl = &policy->xfrm_vec[i];
13731371

1374-
if (tmpl->mode == XFRM_MODE_TUNNEL ||
1375-
tmpl->mode == XFRM_MODE_BEET) {
1376-
remote = &tmpl->id.daddr;
1377-
local = &tmpl->saddr;
1378-
if (xfrm_addr_any(local, tmpl->encap_family)) {
1379-
error = xfrm_get_saddr(net, fl->flowi_oif,
1380-
&tmp, remote,
1381-
tmpl->encap_family, 0);
1382-
if (error)
1383-
goto fail;
1384-
local = &tmp;
1385-
}
1372+
remote = &tmpl->id.daddr;
1373+
local = &tmpl->saddr;
1374+
if (xfrm_addr_any(local, tmpl->encap_family)) {
1375+
error = xfrm_get_saddr(net, fl->flowi_oif,
1376+
&tmp, remote,
1377+
tmpl->encap_family, 0);
1378+
if (error)
1379+
goto fail;
1380+
local = &tmp;
13861381
}
13871382

13881383
x = xfrm_state_find(remote, local, fl, tmpl, policy, &error, family);
13891384

13901385
if (x && x->km.state == XFRM_STATE_VALID) {
13911386
xfrm[nx++] = x;
1392-
daddr = remote;
1393-
saddr = local;
13941387
continue;
13951388
}
13961389
if (x) {

0 commit comments

Comments
 (0)