aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2015-10-26 06:03:46 -0400
committerIlya Dryomov <idryomov@gmail.com>2015-11-02 17:36:48 -0500
commitcbf99a11fb14db0835acd79ecd7469d37e398660 (patch)
tree6d9b61ad72fd9cecd013e2dd70388d55e6491a9d
parent5e804ac4824302efc3038e086cb21f2e93ab8900 (diff)
libceph: introduce ceph_x_authorizer_cleanup()
Commit ae385eaf24dc ("libceph: store session key in cephx authorizer") introduced ceph_x_authorizer::session_key, but didn't update all the exit/error paths. Introduce ceph_x_authorizer_cleanup() to encapsulate ceph_x_authorizer cleanup and switch to it. This fixes ceph_x_destroy(), which currently always leaks key and ceph_x_build_authorizer() error paths. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Yan, Zheng <zyan@redhat.com>
-rw-r--r--net/ceph/auth_x.c28
-rw-r--r--net/ceph/crypto.h4
2 files changed, 20 insertions, 12 deletions
diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
index ba6eb17226da..65054fd31b97 100644
--- a/net/ceph/auth_x.c
+++ b/net/ceph/auth_x.c
@@ -279,6 +279,15 @@ bad:
279 return -EINVAL; 279 return -EINVAL;
280} 280}
281 281
282static void ceph_x_authorizer_cleanup(struct ceph_x_authorizer *au)
283{
284 ceph_crypto_key_destroy(&au->session_key);
285 if (au->buf) {
286 ceph_buffer_put(au->buf);
287 au->buf = NULL;
288 }
289}
290
282static int ceph_x_build_authorizer(struct ceph_auth_client *ac, 291static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
283 struct ceph_x_ticket_handler *th, 292 struct ceph_x_ticket_handler *th,
284 struct ceph_x_authorizer *au) 293 struct ceph_x_authorizer *au)
@@ -297,7 +306,7 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
297 ceph_crypto_key_destroy(&au->session_key); 306 ceph_crypto_key_destroy(&au->session_key);
298 ret = ceph_crypto_key_clone(&au->session_key, &th->session_key); 307 ret = ceph_crypto_key_clone(&au->session_key, &th->session_key);
299 if (ret) 308 if (ret)
300 return ret; 309 goto out_au;
301 310
302 maxlen = sizeof(*msg_a) + sizeof(msg_b) + 311 maxlen = sizeof(*msg_a) + sizeof(msg_b) +
303 ceph_x_encrypt_buflen(ticket_blob_len); 312 ceph_x_encrypt_buflen(ticket_blob_len);
@@ -309,8 +318,8 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
309 if (!au->buf) { 318 if (!au->buf) {
310 au->buf = ceph_buffer_new(maxlen, GFP_NOFS); 319 au->buf = ceph_buffer_new(maxlen, GFP_NOFS);
311 if (!au->buf) { 320 if (!au->buf) {
312 ceph_crypto_key_destroy(&au->session_key); 321 ret = -ENOMEM;
313 return -ENOMEM; 322 goto out_au;
314 } 323 }
315 } 324 }
316 au->service = th->service; 325 au->service = th->service;
@@ -340,7 +349,7 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
340 ret = ceph_x_encrypt(&au->session_key, &msg_b, sizeof(msg_b), 349 ret = ceph_x_encrypt(&au->session_key, &msg_b, sizeof(msg_b),
341 p, end - p); 350 p, end - p);
342 if (ret < 0) 351 if (ret < 0)
343 goto out_buf; 352 goto out_au;
344 p += ret; 353 p += ret;
345 au->buf->vec.iov_len = p - au->buf->vec.iov_base; 354 au->buf->vec.iov_len = p - au->buf->vec.iov_base;
346 dout(" built authorizer nonce %llx len %d\n", au->nonce, 355 dout(" built authorizer nonce %llx len %d\n", au->nonce,
@@ -348,9 +357,8 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
348 BUG_ON(au->buf->vec.iov_len > maxlen); 357 BUG_ON(au->buf->vec.iov_len > maxlen);
349 return 0; 358 return 0;
350 359
351out_buf: 360out_au:
352 ceph_buffer_put(au->buf); 361 ceph_x_authorizer_cleanup(au);
353 au->buf = NULL;
354 return ret; 362 return ret;
355} 363}
356 364
@@ -624,8 +632,7 @@ static void ceph_x_destroy_authorizer(struct ceph_auth_client *ac,
624{ 632{
625 struct ceph_x_authorizer *au = (void *)a; 633 struct ceph_x_authorizer *au = (void *)a;
626 634
627 ceph_crypto_key_destroy(&au->session_key); 635 ceph_x_authorizer_cleanup(au);
628 ceph_buffer_put(au->buf);
629 kfree(au); 636 kfree(au);
630} 637}
631 638
@@ -653,8 +660,7 @@ static void ceph_x_destroy(struct ceph_auth_client *ac)
653 remove_ticket_handler(ac, th); 660 remove_ticket_handler(ac, th);
654 } 661 }
655 662
656 if (xi->auth_authorizer.buf) 663 ceph_x_authorizer_cleanup(&xi->auth_authorizer);
657 ceph_buffer_put(xi->auth_authorizer.buf);
658 664
659 kfree(ac->private); 665 kfree(ac->private);
660 ac->private = NULL; 666 ac->private = NULL;
diff --git a/net/ceph/crypto.h b/net/ceph/crypto.h
index d1498224c49d..2e9cab09f37b 100644
--- a/net/ceph/crypto.h
+++ b/net/ceph/crypto.h
@@ -16,8 +16,10 @@ struct ceph_crypto_key {
16 16
17static inline void ceph_crypto_key_destroy(struct ceph_crypto_key *key) 17static inline void ceph_crypto_key_destroy(struct ceph_crypto_key *key)
18{ 18{
19 if (key) 19 if (key) {
20 kfree(key->key); 20 kfree(key->key);
21 key->key = NULL;
22 }
21} 23}
22 24
23int ceph_crypto_key_clone(struct ceph_crypto_key *dst, 25int ceph_crypto_key_clone(struct ceph_crypto_key *dst,