diff options
Diffstat (limited to 'net/xfrm')
| -rw-r--r-- | net/xfrm/xfrm_policy.c | 14 | ||||
| -rw-r--r-- | net/xfrm/xfrm_replay.c | 5 | ||||
| -rw-r--r-- | net/xfrm/xfrm_user.c | 3 |
3 files changed, 20 insertions, 2 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 15792d8b6272..b4d745ea8ee1 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -1406,6 +1406,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, | |||
| 1406 | struct net *net = xp_net(policy); | 1406 | struct net *net = xp_net(policy); |
| 1407 | unsigned long now = jiffies; | 1407 | unsigned long now = jiffies; |
| 1408 | struct net_device *dev; | 1408 | struct net_device *dev; |
| 1409 | struct xfrm_mode *inner_mode; | ||
| 1409 | struct dst_entry *dst_prev = NULL; | 1410 | struct dst_entry *dst_prev = NULL; |
| 1410 | struct dst_entry *dst0 = NULL; | 1411 | struct dst_entry *dst0 = NULL; |
| 1411 | int i = 0; | 1412 | int i = 0; |
| @@ -1436,6 +1437,17 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, | |||
| 1436 | goto put_states; | 1437 | goto put_states; |
| 1437 | } | 1438 | } |
| 1438 | 1439 | ||
| 1440 | if (xfrm[i]->sel.family == AF_UNSPEC) { | ||
| 1441 | inner_mode = xfrm_ip2inner_mode(xfrm[i], | ||
| 1442 | xfrm_af2proto(family)); | ||
| 1443 | if (!inner_mode) { | ||
| 1444 | err = -EAFNOSUPPORT; | ||
| 1445 | dst_release(dst); | ||
| 1446 | goto put_states; | ||
| 1447 | } | ||
| 1448 | } else | ||
| 1449 | inner_mode = xfrm[i]->inner_mode; | ||
| 1450 | |||
| 1439 | if (!dst_prev) | 1451 | if (!dst_prev) |
| 1440 | dst0 = dst1; | 1452 | dst0 = dst1; |
| 1441 | else { | 1453 | else { |
| @@ -1464,7 +1476,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, | |||
| 1464 | dst1->lastuse = now; | 1476 | dst1->lastuse = now; |
| 1465 | 1477 | ||
| 1466 | dst1->input = dst_discard; | 1478 | dst1->input = dst_discard; |
| 1467 | dst1->output = xfrm[i]->outer_mode->afinfo->output; | 1479 | dst1->output = inner_mode->afinfo->output; |
| 1468 | 1480 | ||
| 1469 | dst1->next = dst_prev; | 1481 | dst1->next = dst_prev; |
| 1470 | dst_prev = dst1; | 1482 | dst_prev = dst1; |
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c index f218385950ca..47f1b8638df9 100644 --- a/net/xfrm/xfrm_replay.c +++ b/net/xfrm/xfrm_replay.c | |||
| @@ -532,9 +532,12 @@ int xfrm_init_replay(struct xfrm_state *x) | |||
| 532 | 532 | ||
| 533 | if (replay_esn) { | 533 | if (replay_esn) { |
| 534 | if (replay_esn->replay_window > | 534 | if (replay_esn->replay_window > |
| 535 | replay_esn->bmp_len * sizeof(__u32)) | 535 | replay_esn->bmp_len * sizeof(__u32) * 8) |
| 536 | return -EINVAL; | 536 | return -EINVAL; |
| 537 | 537 | ||
| 538 | if ((x->props.flags & XFRM_STATE_ESN) && replay_esn->replay_window == 0) | ||
| 539 | return -EINVAL; | ||
| 540 | |||
| 538 | if ((x->props.flags & XFRM_STATE_ESN) && x->replay_esn) | 541 | if ((x->props.flags & XFRM_STATE_ESN) && x->replay_esn) |
| 539 | x->repl = &xfrm_replay_esn; | 542 | x->repl = &xfrm_replay_esn; |
| 540 | else | 543 | else |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 5d1d60d3ca83..c658cb3bc7c3 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -124,6 +124,9 @@ static inline int verify_replay(struct xfrm_usersa_info *p, | |||
| 124 | { | 124 | { |
| 125 | struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL]; | 125 | struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL]; |
| 126 | 126 | ||
| 127 | if ((p->flags & XFRM_STATE_ESN) && !rt) | ||
| 128 | return -EINVAL; | ||
| 129 | |||
| 127 | if (!rt) | 130 | if (!rt) |
| 128 | return 0; | 131 | return 0; |
| 129 | 132 | ||
