diff options
author | Dave Airlie <airlied@redhat.com> | 2015-04-20 11:32:26 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-04-20 13:05:20 +1000 |
commit | 2c33ce009ca2389dbf0535d0672214d09738e35e (patch) | |
tree | 6186a6458c3c160385d794a23eaf07c786a9e61b /crypto/crypto_user.c | |
parent | cec32a47010647e8b0603726ebb75b990a4057a4 (diff) | |
parent | 09d51602cf84a1264946711dd4ea0dddbac599a1 (diff) | |
download | linux-stable-2c33ce009ca2389dbf0535d0672214d09738e35e.tar.gz linux-stable-2c33ce009ca2389dbf0535d0672214d09738e35e.tar.bz2 linux-stable-2c33ce009ca2389dbf0535d0672214d09738e35e.zip |
Merge Linus master into drm-next
The merge is clean, but the arm build fails afterwards,
due to API changes in the regulator tree.
I've included the patch into the merge to fix the build.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'crypto/crypto_user.c')
-rw-r--r-- | crypto/crypto_user.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c index c5148a35ae0a..41dfe762b7fb 100644 --- a/crypto/crypto_user.c +++ b/crypto/crypto_user.c @@ -62,10 +62,14 @@ static struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact) else if (!exact) match = !strcmp(q->cra_name, p->cru_name); - if (match) { - alg = q; - break; - } + if (!match) + continue; + + if (unlikely(!crypto_mod_get(q))) + continue; + + alg = q; + break; } up_read(&crypto_alg_sem); @@ -205,9 +209,10 @@ static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh, if (!alg) return -ENOENT; + err = -ENOMEM; skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); if (!skb) - return -ENOMEM; + goto drop_alg; info.in_skb = in_skb; info.out_skb = skb; @@ -215,6 +220,10 @@ static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh, info.nlmsg_flags = 0; err = crypto_report_alg(alg, &info); + +drop_alg: + crypto_mod_put(alg); + if (err) return err; @@ -284,6 +293,7 @@ static int crypto_update_alg(struct sk_buff *skb, struct nlmsghdr *nlh, up_write(&crypto_alg_sem); + crypto_mod_put(alg); crypto_remove_final(&list); return 0; @@ -294,6 +304,7 @@ static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh, { struct crypto_alg *alg; struct crypto_user_alg *p = nlmsg_data(nlh); + int err; if (!netlink_capable(skb, CAP_NET_ADMIN)) return -EPERM; @@ -310,13 +321,19 @@ static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh, * if we try to unregister. Unregistering such an algorithm without * removing the module is not possible, so we restrict to crypto * instances that are build from templates. */ + err = -EINVAL; if (!(alg->cra_flags & CRYPTO_ALG_INSTANCE)) - return -EINVAL; + goto drop_alg; - if (atomic_read(&alg->cra_refcnt) != 1) - return -EBUSY; + err = -EBUSY; + if (atomic_read(&alg->cra_refcnt) > 2) + goto drop_alg; - return crypto_unregister_instance(alg); + err = crypto_unregister_instance((struct crypto_instance *)alg); + +drop_alg: + crypto_mod_put(alg); + return err; } static struct crypto_alg *crypto_user_skcipher_alg(const char *name, u32 type, @@ -395,8 +412,10 @@ static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh, return -EINVAL; alg = crypto_alg_match(p, exact); - if (alg) + if (alg) { + crypto_mod_put(alg); return -EEXIST; + } if (strlen(p->cru_driver_name)) name = p->cru_driver_name; |