diff options
author | Yossi Kuperman <yossiku@mellanox.com> | 2018-01-17 08:52:41 -0500 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2018-01-18 05:09:29 -0500 |
commit | cc01572e2fb080e279ca625f239aca61f435ebf3 (patch) | |
tree | 93bd94fee95408caeab452c97c90a71b8f49f4d0 | |
parent | ad9294dbc227cbc8e173b3b963e7dd9af5314f77 (diff) |
xfrm: Add SA to hardware at the end of xfrm_state_construct()
Current code configures the hardware with a new SA before the state has been
fully initialized. During this time interval, an incoming ESP packet can cause
a crash due to a NULL dereference. More specifically, xfrm_input() considers
the packet as valid, and yet, anti-replay mechanism is not initialized.
Move hardware configuration to the end of xfrm_state_construct(), and mark
the state as valid once the SA is fully initialized.
Fixes: d77e38e612a0 ("xfrm: Add an IPsec hardware offloading API")
Signed-off-by: Aviad Yehezkel <aviadye@mellnaox.com>
Signed-off-by: Aviv Heller <avivh@mellanox.com>
Signed-off-by: Yossi Kuperman <yossiku@mellanox.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
-rw-r--r-- | net/xfrm/xfrm_state.c | 10 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 18 |
2 files changed, 18 insertions, 10 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 429957412633..2d486492acdb 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -2272,8 +2272,6 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) | |||
2272 | goto error; | 2272 | goto error; |
2273 | } | 2273 | } |
2274 | 2274 | ||
2275 | x->km.state = XFRM_STATE_VALID; | ||
2276 | |||
2277 | error: | 2275 | error: |
2278 | return err; | 2276 | return err; |
2279 | } | 2277 | } |
@@ -2282,7 +2280,13 @@ EXPORT_SYMBOL(__xfrm_init_state); | |||
2282 | 2280 | ||
2283 | int xfrm_init_state(struct xfrm_state *x) | 2281 | int xfrm_init_state(struct xfrm_state *x) |
2284 | { | 2282 | { |
2285 | return __xfrm_init_state(x, true, false); | 2283 | int err; |
2284 | |||
2285 | err = __xfrm_init_state(x, true, false); | ||
2286 | if (!err) | ||
2287 | x->km.state = XFRM_STATE_VALID; | ||
2288 | |||
2289 | return err; | ||
2286 | } | 2290 | } |
2287 | 2291 | ||
2288 | EXPORT_SYMBOL(xfrm_init_state); | 2292 | EXPORT_SYMBOL(xfrm_init_state); |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index bdb48e5dba04..7f52b8eb177d 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -598,13 +598,6 @@ static struct xfrm_state *xfrm_state_construct(struct net *net, | |||
598 | goto error; | 598 | goto error; |
599 | } | 599 | } |
600 | 600 | ||
601 | if (attrs[XFRMA_OFFLOAD_DEV]) { | ||
602 | err = xfrm_dev_state_add(net, x, | ||
603 | nla_data(attrs[XFRMA_OFFLOAD_DEV])); | ||
604 | if (err) | ||
605 | goto error; | ||
606 | } | ||
607 | |||
608 | if ((err = xfrm_alloc_replay_state_esn(&x->replay_esn, &x->preplay_esn, | 601 | if ((err = xfrm_alloc_replay_state_esn(&x->replay_esn, &x->preplay_esn, |
609 | attrs[XFRMA_REPLAY_ESN_VAL]))) | 602 | attrs[XFRMA_REPLAY_ESN_VAL]))) |
610 | goto error; | 603 | goto error; |
@@ -620,6 +613,14 @@ static struct xfrm_state *xfrm_state_construct(struct net *net, | |||
620 | /* override default values from above */ | 613 | /* override default values from above */ |
621 | xfrm_update_ae_params(x, attrs, 0); | 614 | xfrm_update_ae_params(x, attrs, 0); |
622 | 615 | ||
616 | /* configure the hardware if offload is requested */ | ||
617 | if (attrs[XFRMA_OFFLOAD_DEV]) { | ||
618 | err = xfrm_dev_state_add(net, x, | ||
619 | nla_data(attrs[XFRMA_OFFLOAD_DEV])); | ||
620 | if (err) | ||
621 | goto error; | ||
622 | } | ||
623 | |||
623 | return x; | 624 | return x; |
624 | 625 | ||
625 | error: | 626 | error: |
@@ -662,6 +663,9 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
662 | goto out; | 663 | goto out; |
663 | } | 664 | } |
664 | 665 | ||
666 | if (x->km.state == XFRM_STATE_VOID) | ||
667 | x->km.state = XFRM_STATE_VALID; | ||
668 | |||
665 | c.seq = nlh->nlmsg_seq; | 669 | c.seq = nlh->nlmsg_seq; |
666 | c.portid = nlh->nlmsg_pid; | 670 | c.portid = nlh->nlmsg_pid; |
667 | c.event = nlh->nlmsg_type; | 671 | c.event = nlh->nlmsg_type; |