aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYossi Kuperman <yossiku@mellanox.com>2018-01-17 08:52:41 -0500
committerSteffen Klassert <steffen.klassert@secunet.com>2018-01-18 05:09:29 -0500
commitcc01572e2fb080e279ca625f239aca61f435ebf3 (patch)
tree93bd94fee95408caeab452c97c90a71b8f49f4d0
parentad9294dbc227cbc8e173b3b963e7dd9af5314f77 (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.c10
-rw-r--r--net/xfrm/xfrm_user.c18
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
2277error: 2275error:
2278 return err; 2276 return err;
2279} 2277}
@@ -2282,7 +2280,13 @@ EXPORT_SYMBOL(__xfrm_init_state);
2282 2280
2283int xfrm_init_state(struct xfrm_state *x) 2281int 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
2288EXPORT_SYMBOL(xfrm_init_state); 2292EXPORT_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
625error: 626error:
@@ -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;