]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - net/key/af_key.c
Merge remote-tracking branches 'regulator/topic/s5m8767', 'regulator/topic/st-pwm...
[karo-tx-linux.git] / net / key / af_key.c
index 545f047868ad86c416f68f468a31d7cc5bd07eb4..79326978517a6842b8538b6a45b95309b8e37d4f 100644 (file)
@@ -433,12 +433,13 @@ static inline int verify_sec_ctx_len(const void *p)
        return 0;
 }
 
-static inline struct xfrm_user_sec_ctx *pfkey_sadb2xfrm_user_sec_ctx(const struct sadb_x_sec_ctx *sec_ctx)
+static inline struct xfrm_user_sec_ctx *pfkey_sadb2xfrm_user_sec_ctx(const struct sadb_x_sec_ctx *sec_ctx,
+                                                                    gfp_t gfp)
 {
        struct xfrm_user_sec_ctx *uctx = NULL;
        int ctx_size = sec_ctx->sadb_x_ctx_len;
 
-       uctx = kmalloc((sizeof(*uctx)+ctx_size), GFP_KERNEL);
+       uctx = kmalloc((sizeof(*uctx)+ctx_size), gfp);
 
        if (!uctx)
                return NULL;
@@ -1124,7 +1125,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
 
        sec_ctx = ext_hdrs[SADB_X_EXT_SEC_CTX - 1];
        if (sec_ctx != NULL) {
-               struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
+               struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx, GFP_KERNEL);
 
                if (!uctx)
                        goto out;
@@ -1340,6 +1341,12 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, const struct sadb_
                max_spi = range->sadb_spirange_max;
        }
 
+       err = verify_spi_info(x->id.proto, min_spi, max_spi);
+       if (err) {
+               xfrm_state_put(x);
+               return err;
+       }
+
        err = xfrm_alloc_spi(x, min_spi, max_spi);
        resp_skb = err ? ERR_PTR(err) : pfkey_xfrm_state2msg(x);
 
@@ -1380,10 +1387,9 @@ static int pfkey_acquire(struct sock *sk, struct sk_buff *skb, const struct sadb
                return 0;
 
        spin_lock_bh(&x->lock);
-       if (x->km.state == XFRM_STATE_ACQ) {
+       if (x->km.state == XFRM_STATE_ACQ)
                x->km.state = XFRM_STATE_ERROR;
-               wake_up(&net->xfrm.km_waitq);
-       }
+
        spin_unlock_bh(&x->lock);
        xfrm_state_put(x);
        return 0;
@@ -1785,7 +1791,9 @@ static int pfkey_dump_sa(struct pfkey_sock *pfk)
 
 static void pfkey_dump_sa_done(struct pfkey_sock *pfk)
 {
-       xfrm_state_walk_done(&pfk->dump.u.state);
+       struct net *net = sock_net(&pfk->sk);
+
+       xfrm_state_walk_done(&pfk->dump.u.state, net);
 }
 
 static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs)
@@ -1861,7 +1869,7 @@ static u32 gen_reqid(struct net *net)
                        reqid = IPSEC_MANUAL_REQID_MAX+1;
                xfrm_policy_walk_init(&walk, XFRM_POLICY_TYPE_MAIN);
                rc = xfrm_policy_walk(net, &walk, check_reqid, (void*)&reqid);
-               xfrm_policy_walk_done(&walk);
+               xfrm_policy_walk_done(&walk, net);
                if (rc != -EEXIST)
                        return reqid;
        } while (reqid != start);
@@ -2224,14 +2232,14 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, const struct sadb_
 
        sec_ctx = ext_hdrs[SADB_X_EXT_SEC_CTX - 1];
        if (sec_ctx != NULL) {
-               struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
+               struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx, GFP_KERNEL);
 
                if (!uctx) {
                        err = -ENOBUFS;
                        goto out;
                }
 
-               err = security_xfrm_policy_alloc(&xp->security, uctx);
+               err = security_xfrm_policy_alloc(&xp->security, uctx, GFP_KERNEL);
                kfree(uctx);
 
                if (err)
@@ -2328,12 +2336,12 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, const struct sa
 
        sec_ctx = ext_hdrs[SADB_X_EXT_SEC_CTX - 1];
        if (sec_ctx != NULL) {
-               struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
+               struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx, GFP_KERNEL);
 
                if (!uctx)
                        return -ENOMEM;
 
-               err = security_xfrm_policy_alloc(&pol_ctx, uctx);
+               err = security_xfrm_policy_alloc(&pol_ctx, uctx, GFP_KERNEL);
                kfree(uctx);
                if (err)
                        return err;
@@ -2485,6 +2493,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,
        struct xfrm_selector sel;
        struct xfrm_migrate m[XFRM_MAX_DEPTH];
        struct xfrm_kmaddress k;
+       struct net *net = sock_net(sk);
 
        if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC - 1],
                                     ext_hdrs[SADB_EXT_ADDRESS_DST - 1]) ||
@@ -2558,7 +2567,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,
        }
 
        return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i,
-                           kma ? &k : NULL);
+                           kma ? &k : NULL, net);
 
  out:
        return err;
@@ -2659,7 +2668,9 @@ static int pfkey_dump_sp(struct pfkey_sock *pfk)
 
 static void pfkey_dump_sp_done(struct pfkey_sock *pfk)
 {
-       xfrm_policy_walk_done(&pfk->dump.u.policy);
+       struct net *net = sock_net((struct sock *)pfk);
+
+       xfrm_policy_walk_done(&pfk->dump.u.policy, net);
 }
 
 static int pfkey_spddump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs)
@@ -3229,8 +3240,8 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt,
                }
                if ((*dir = verify_sec_ctx_len(p)))
                        goto out;
-               uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
-               *dir = security_xfrm_policy_alloc(&xp->security, uctx);
+               uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx, GFP_ATOMIC);
+               *dir = security_xfrm_policy_alloc(&xp->security, uctx, GFP_ATOMIC);
                kfree(uctx);
 
                if (*dir)
@@ -3569,6 +3580,7 @@ static int pfkey_sendmsg(struct kiocb *kiocb,
        struct sk_buff *skb = NULL;
        struct sadb_msg *hdr = NULL;
        int err;
+       struct net *net = sock_net(sk);
 
        err = -EOPNOTSUPP;
        if (msg->msg_flags & MSG_OOB)
@@ -3591,9 +3603,9 @@ static int pfkey_sendmsg(struct kiocb *kiocb,
        if (!hdr)
                goto out;
 
-       mutex_lock(&xfrm_cfg_mutex);
+       mutex_lock(&net->xfrm.xfrm_cfg_mutex);
        err = pfkey_process(sk, skb, hdr);
-       mutex_unlock(&xfrm_cfg_mutex);
+       mutex_unlock(&net->xfrm.xfrm_cfg_mutex);
 
 out:
        if (err && hdr && pfkey_error(hdr, err, sk) == 0)