From: Antony Antony <antony.ant...@secunet.com>

[ Upstream commit 7aa05d304785204703a67a6aa7f1db402889a172 ]

XFRMA_SEC_CTX was not cloned from the old to the new.
Migrate this attribute during XFRMA_MSG_MIGRATE

v1->v2:
 - return -ENOMEM on error
v2->v3:
 - fix return type to int

Fixes: 80c9abaabf42 ("[XFRM]: Extension for dynamic update of endpoint 
address(es)")
Signed-off-by: Antony Antony <antony.ant...@secunet.com>
Signed-off-by: Steffen Klassert <steffen.klass...@secunet.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 net/xfrm/xfrm_state.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 8ec3a6a12dd34..3a2c1f15d31dd 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1441,6 +1441,30 @@ out:
 EXPORT_SYMBOL(xfrm_state_add);
 
 #ifdef CONFIG_XFRM_MIGRATE
+static inline int clone_security(struct xfrm_state *x, struct xfrm_sec_ctx 
*security)
+{
+       struct xfrm_user_sec_ctx *uctx;
+       int size = sizeof(*uctx) + security->ctx_len;
+       int err;
+
+       uctx = kmalloc(size, GFP_KERNEL);
+       if (!uctx)
+               return -ENOMEM;
+
+       uctx->exttype = XFRMA_SEC_CTX;
+       uctx->len = size;
+       uctx->ctx_doi = security->ctx_doi;
+       uctx->ctx_alg = security->ctx_alg;
+       uctx->ctx_len = security->ctx_len;
+       memcpy(uctx + 1, security->ctx_str, security->ctx_len);
+       err = security_xfrm_state_alloc(x, uctx);
+       kfree(uctx);
+       if (err)
+               return err;
+
+       return 0;
+}
+
 static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
                                           struct xfrm_encap_tmpl *encap)
 {
@@ -1497,6 +1521,10 @@ static struct xfrm_state *xfrm_state_clone(struct 
xfrm_state *orig,
                        goto error;
        }
 
+       if (orig->security)
+               if (clone_security(x, orig->security))
+                       goto error;
+
        if (orig->coaddr) {
                x->coaddr = kmemdup(orig->coaddr, sizeof(*x->coaddr),
                                    GFP_KERNEL);
-- 
2.25.1



Reply via email to