mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
xfrm: add state synchronization after migration
Add xfrm_migrate_sync() to copy curlft and replay state from the old SA to the new one before installation. The function allocates no memory, so it can be called under a spinlock. In preparation for a subsequent patch in this series. A subsequent patch calls this under x->lock, atomically capturing the latest lifetime counters and replay state from the original SA and deleting it in the same critical section to prevent SN/IV reuse for XFRM_MSG_MIGRATE_STATE method. No functional change. Signed-off-by: Antony Antony <antony.antony@secunet.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
parent
b2cb192b95
commit
bac7a60e26
|
|
@ -2024,23 +2024,51 @@ static inline unsigned int xfrm_replay_state_esn_len(struct xfrm_replay_state_es
|
|||
|
||||
#ifdef CONFIG_XFRM_MIGRATE
|
||||
static inline int xfrm_replay_clone(struct xfrm_state *x,
|
||||
struct xfrm_state *orig)
|
||||
const struct xfrm_state *orig)
|
||||
{
|
||||
/* Counters synced later in xfrm_replay_sync() */
|
||||
|
||||
x->replay_esn = kmemdup(orig->replay_esn,
|
||||
x->replay = orig->replay;
|
||||
x->preplay = orig->preplay;
|
||||
|
||||
if (orig->replay_esn) {
|
||||
x->replay_esn = kmemdup(orig->replay_esn,
|
||||
xfrm_replay_state_esn_len(orig->replay_esn),
|
||||
GFP_KERNEL);
|
||||
if (!x->replay_esn)
|
||||
return -ENOMEM;
|
||||
x->preplay_esn = kmemdup(orig->preplay_esn,
|
||||
xfrm_replay_state_esn_len(orig->preplay_esn),
|
||||
GFP_KERNEL);
|
||||
if (!x->preplay_esn)
|
||||
return -ENOMEM;
|
||||
if (!x->replay_esn)
|
||||
return -ENOMEM;
|
||||
x->preplay_esn = kmemdup(orig->preplay_esn,
|
||||
xfrm_replay_state_esn_len(orig->preplay_esn),
|
||||
GFP_KERNEL);
|
||||
if (!x->preplay_esn)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void xfrm_replay_sync(struct xfrm_state *x, const struct xfrm_state *orig)
|
||||
{
|
||||
x->replay = orig->replay;
|
||||
x->preplay = orig->preplay;
|
||||
|
||||
if (orig->replay_esn) {
|
||||
memcpy(x->replay_esn, orig->replay_esn,
|
||||
xfrm_replay_state_esn_len(orig->replay_esn));
|
||||
|
||||
memcpy(x->preplay_esn, orig->preplay_esn,
|
||||
xfrm_replay_state_esn_len(orig->preplay_esn));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void xfrm_migrate_sync(struct xfrm_state *x,
|
||||
const struct xfrm_state *orig)
|
||||
{
|
||||
/* called under lock so no race conditions or mallocs allowed */
|
||||
memcpy(&x->curlft, &orig->curlft, sizeof(x->curlft));
|
||||
xfrm_replay_sync(x, orig);
|
||||
}
|
||||
|
||||
static inline struct xfrm_algo_aead *xfrm_algo_aead_clone(struct xfrm_algo_aead *orig)
|
||||
{
|
||||
return kmemdup(orig, aead_len(orig), GFP_KERNEL);
|
||||
|
|
|
|||
|
|
@ -2027,10 +2027,8 @@ static struct xfrm_state *xfrm_state_clone_and_setup(struct xfrm_state *orig,
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (orig->replay_esn) {
|
||||
if (xfrm_replay_clone(x, orig))
|
||||
goto error;
|
||||
}
|
||||
if (xfrm_replay_clone(x, orig))
|
||||
goto error;
|
||||
|
||||
memcpy(&x->mark, &orig->mark, sizeof(x->mark));
|
||||
memcpy(&x->props.smark, &orig->props.smark, sizeof(x->props.smark));
|
||||
|
|
@ -2043,11 +2041,8 @@ static struct xfrm_state *xfrm_state_clone_and_setup(struct xfrm_state *orig,
|
|||
x->tfcpad = orig->tfcpad;
|
||||
x->replay_maxdiff = orig->replay_maxdiff;
|
||||
x->replay_maxage = orig->replay_maxage;
|
||||
memcpy(&x->curlft, &orig->curlft, sizeof(x->curlft));
|
||||
x->km.state = orig->km.state;
|
||||
x->km.seq = orig->km.seq;
|
||||
x->replay = orig->replay;
|
||||
x->preplay = orig->preplay;
|
||||
x->lastused = orig->lastused;
|
||||
x->new_mapping = 0;
|
||||
x->new_mapping_sport = 0;
|
||||
|
|
@ -2193,6 +2188,8 @@ struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
|
|||
if (!xc)
|
||||
return NULL;
|
||||
|
||||
xfrm_migrate_sync(xc, x);
|
||||
|
||||
if (xfrm_state_migrate_install(x, xc, m, xuo, extack) < 0)
|
||||
return NULL;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user