Skip to content

Commit

Permalink
xfrm: Clone states properly on migration
Browse files Browse the repository at this point in the history
We loose a lot of information of the original state if we
clone it with xfrm_state_clone(). In particular, there is
no crypto algorithm attached if the original state uses
an aead algorithm. This patch add the missing information
to the clone state.

Signed-off-by: Steffen Klassert <[email protected]>
  • Loading branch information
klassert committed Feb 20, 2014
1 parent 8c0cba2 commit ee5c231
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 5 deletions.
11 changes: 11 additions & 0 deletions include/net/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1648,6 +1648,11 @@ static inline int xfrm_aevent_is_on(struct net *net)
}
#endif

static inline int aead_len(struct xfrm_algo_aead *alg)
{
return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
}

static inline int xfrm_alg_len(const struct xfrm_algo *alg)
{
return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
Expand Down Expand Up @@ -1686,6 +1691,12 @@ static inline int xfrm_replay_clone(struct xfrm_state *x,
return 0;
}

static inline struct xfrm_algo_aead *xfrm_algo_aead_clone(struct xfrm_algo_aead *orig)
{
return kmemdup(orig, aead_len(orig), GFP_KERNEL);
}


static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig)
{
return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL);
Expand Down
8 changes: 8 additions & 0 deletions net/xfrm/xfrm_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -1159,6 +1159,11 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp)
}
x->props.aalgo = orig->props.aalgo;

if (orig->aead) {
x->aead = xfrm_algo_aead_clone(orig->aead);
if (!x->aead)
goto error;
}
if (orig->ealg) {
x->ealg = xfrm_algo_clone(orig->ealg);
if (!x->ealg)
Expand Down Expand Up @@ -1201,6 +1206,9 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp)
x->props.flags = orig->props.flags;
x->props.extra_flags = orig->props.extra_flags;

x->tfcpad = orig->tfcpad;
x->replay_maxdiff = orig->replay_maxdiff;
x->replay_maxage = orig->replay_maxage;
x->curlft.add_time = orig->curlft.add_time;
x->km.state = orig->km.state;
x->km.seq = orig->km.seq;
Expand Down
5 changes: 0 additions & 5 deletions net/xfrm/xfrm_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,6 @@
#include <linux/in6.h>
#endif

static inline int aead_len(struct xfrm_algo_aead *alg)
{
return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
}

static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type)
{
struct nlattr *rt = attrs[type];
Expand Down

0 comments on commit ee5c231

Please sign in to comment.