diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2015-10-26 06:03:46 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2015-11-02 17:36:48 -0500 |
commit | cbf99a11fb14db0835acd79ecd7469d37e398660 (patch) | |
tree | 6d9b61ad72fd9cecd013e2dd70388d55e6491a9d | |
parent | 5e804ac4824302efc3038e086cb21f2e93ab8900 (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.c | 28 | ||||
-rw-r--r-- | net/ceph/crypto.h | 4 |
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 | ||
282 | static 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 | |||
282 | static int ceph_x_build_authorizer(struct ceph_auth_client *ac, | 291 | static 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 | ||
351 | out_buf: | 360 | out_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 | ||
17 | static inline void ceph_crypto_key_destroy(struct ceph_crypto_key *key) | 17 | static 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 | ||
23 | int ceph_crypto_key_clone(struct ceph_crypto_key *dst, | 25 | int ceph_crypto_key_clone(struct ceph_crypto_key *dst, |