@@ -62,10 +62,14 @@ static struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact)
6262 else if (!exact )
6363 match = !strcmp (q -> cra_name , p -> cru_name );
6464
65- if (match ) {
66- alg = q ;
67- break ;
68- }
65+ if (!match )
66+ continue ;
67+
68+ if (unlikely (!crypto_mod_get (q )))
69+ continue ;
70+
71+ alg = q ;
72+ break ;
6973 }
7074
7175 up_read (& crypto_alg_sem );
@@ -205,16 +209,21 @@ static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
205209 if (!alg )
206210 return - ENOENT ;
207211
212+ err = - ENOMEM ;
208213 skb = nlmsg_new (NLMSG_DEFAULT_SIZE , GFP_ATOMIC );
209214 if (!skb )
210- return - ENOMEM ;
215+ goto drop_alg ;
211216
212217 info .in_skb = in_skb ;
213218 info .out_skb = skb ;
214219 info .nlmsg_seq = in_nlh -> nlmsg_seq ;
215220 info .nlmsg_flags = 0 ;
216221
217222 err = crypto_report_alg (alg , & info );
223+
224+ drop_alg :
225+ crypto_mod_put (alg );
226+
218227 if (err )
219228 return err ;
220229
@@ -284,6 +293,7 @@ static int crypto_update_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
284293
285294 up_write (& crypto_alg_sem );
286295
296+ crypto_mod_put (alg );
287297 crypto_remove_final (& list );
288298
289299 return 0 ;
@@ -294,6 +304,7 @@ static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
294304{
295305 struct crypto_alg * alg ;
296306 struct crypto_user_alg * p = nlmsg_data (nlh );
307+ int err ;
297308
298309 if (!netlink_capable (skb , CAP_NET_ADMIN ))
299310 return - EPERM ;
@@ -310,13 +321,19 @@ static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
310321 * if we try to unregister. Unregistering such an algorithm without
311322 * removing the module is not possible, so we restrict to crypto
312323 * instances that are build from templates. */
324+ err = - EINVAL ;
313325 if (!(alg -> cra_flags & CRYPTO_ALG_INSTANCE ))
314- return - EINVAL ;
326+ goto drop_alg ;
315327
316- if (atomic_read (& alg -> cra_refcnt ) != 1 )
317- return - EBUSY ;
328+ err = - EBUSY ;
329+ if (atomic_read (& alg -> cra_refcnt ) > 2 )
330+ goto drop_alg ;
318331
319- return crypto_unregister_instance ((struct crypto_instance * )alg );
332+ err = crypto_unregister_instance ((struct crypto_instance * )alg );
333+
334+ drop_alg :
335+ crypto_mod_put (alg );
336+ return err ;
320337}
321338
322339static 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,
395412 return - EINVAL ;
396413
397414 alg = crypto_alg_match (p , exact );
398- if (alg )
415+ if (alg ) {
416+ crypto_mod_put (alg );
399417 return - EEXIST ;
418+ }
400419
401420 if (strlen (p -> cru_driver_name ))
402421 name = p -> cru_driver_name ;
0 commit comments