diff options
| -rw-r--r-- | net/ceph/auth_x.c | 64 |
1 files changed, 29 insertions, 35 deletions
diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c index 0eb146dce1aa..de6662b14e1f 100644 --- a/net/ceph/auth_x.c +++ b/net/ceph/auth_x.c | |||
| @@ -13,8 +13,6 @@ | |||
| 13 | #include "auth_x.h" | 13 | #include "auth_x.h" |
| 14 | #include "auth_x_protocol.h" | 14 | #include "auth_x_protocol.h" |
| 15 | 15 | ||
| 16 | #define TEMP_TICKET_BUF_LEN 256 | ||
| 17 | |||
| 18 | static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed); | 16 | static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed); |
| 19 | 17 | ||
| 20 | static int ceph_x_is_authenticated(struct ceph_auth_client *ac) | 18 | static int ceph_x_is_authenticated(struct ceph_auth_client *ac) |
| @@ -64,7 +62,7 @@ static int ceph_x_encrypt(struct ceph_crypto_key *secret, | |||
| 64 | } | 62 | } |
| 65 | 63 | ||
| 66 | static int ceph_x_decrypt(struct ceph_crypto_key *secret, | 64 | static int ceph_x_decrypt(struct ceph_crypto_key *secret, |
| 67 | void **p, void *end, void *obuf, size_t olen) | 65 | void **p, void *end, void **obuf, size_t olen) |
| 68 | { | 66 | { |
| 69 | struct ceph_x_encrypt_header head; | 67 | struct ceph_x_encrypt_header head; |
| 70 | size_t head_len = sizeof(head); | 68 | size_t head_len = sizeof(head); |
| @@ -75,8 +73,14 @@ static int ceph_x_decrypt(struct ceph_crypto_key *secret, | |||
| 75 | return -EINVAL; | 73 | return -EINVAL; |
| 76 | 74 | ||
| 77 | dout("ceph_x_decrypt len %d\n", len); | 75 | dout("ceph_x_decrypt len %d\n", len); |
| 78 | ret = ceph_decrypt2(secret, &head, &head_len, obuf, &olen, | 76 | if (*obuf == NULL) { |
| 79 | *p, len); | 77 | *obuf = kmalloc(len, GFP_NOFS); |
| 78 | if (!*obuf) | ||
| 79 | return -ENOMEM; | ||
| 80 | olen = len; | ||
| 81 | } | ||
| 82 | |||
| 83 | ret = ceph_decrypt2(secret, &head, &head_len, *obuf, &olen, *p, len); | ||
| 80 | if (ret) | 84 | if (ret) |
| 81 | return ret; | 85 | return ret; |
| 82 | if (head.struct_v != 1 || le64_to_cpu(head.magic) != CEPHX_ENC_MAGIC) | 86 | if (head.struct_v != 1 || le64_to_cpu(head.magic) != CEPHX_ENC_MAGIC) |
| @@ -131,18 +135,19 @@ static void remove_ticket_handler(struct ceph_auth_client *ac, | |||
| 131 | 135 | ||
| 132 | static int process_one_ticket(struct ceph_auth_client *ac, | 136 | static int process_one_ticket(struct ceph_auth_client *ac, |
| 133 | struct ceph_crypto_key *secret, | 137 | struct ceph_crypto_key *secret, |
| 134 | void **p, void *end, | 138 | void **p, void *end) |
| 135 | void *dbuf, void *ticket_buf) | ||
| 136 | { | 139 | { |
| 137 | struct ceph_x_info *xi = ac->private; | 140 | struct ceph_x_info *xi = ac->private; |
| 138 | int type; | 141 | int type; |
| 139 | u8 tkt_struct_v, blob_struct_v; | 142 | u8 tkt_struct_v, blob_struct_v; |
| 140 | struct ceph_x_ticket_handler *th; | 143 | struct ceph_x_ticket_handler *th; |
| 144 | void *dbuf = NULL; | ||
| 141 | void *dp, *dend; | 145 | void *dp, *dend; |
| 142 | int dlen; | 146 | int dlen; |
| 143 | char is_enc; | 147 | char is_enc; |
| 144 | struct timespec validity; | 148 | struct timespec validity; |
| 145 | struct ceph_crypto_key old_key; | 149 | struct ceph_crypto_key old_key; |
| 150 | void *ticket_buf = NULL; | ||
| 146 | void *tp, *tpend; | 151 | void *tp, *tpend; |
| 147 | struct ceph_timespec new_validity; | 152 | struct ceph_timespec new_validity; |
| 148 | struct ceph_crypto_key new_session_key; | 153 | struct ceph_crypto_key new_session_key; |
| @@ -167,8 +172,7 @@ static int process_one_ticket(struct ceph_auth_client *ac, | |||
| 167 | } | 172 | } |
| 168 | 173 | ||
| 169 | /* blob for me */ | 174 | /* blob for me */ |
| 170 | dlen = ceph_x_decrypt(secret, p, end, dbuf, | 175 | dlen = ceph_x_decrypt(secret, p, end, &dbuf, 0); |
| 171 | TEMP_TICKET_BUF_LEN); | ||
| 172 | if (dlen <= 0) { | 176 | if (dlen <= 0) { |
| 173 | ret = dlen; | 177 | ret = dlen; |
| 174 | goto out; | 178 | goto out; |
| @@ -195,20 +199,25 @@ static int process_one_ticket(struct ceph_auth_client *ac, | |||
| 195 | 199 | ||
| 196 | /* ticket blob for service */ | 200 | /* ticket blob for service */ |
| 197 | ceph_decode_8_safe(p, end, is_enc, bad); | 201 | ceph_decode_8_safe(p, end, is_enc, bad); |
| 198 | tp = ticket_buf; | ||
| 199 | if (is_enc) { | 202 | if (is_enc) { |
| 200 | /* encrypted */ | 203 | /* encrypted */ |
| 201 | dout(" encrypted ticket\n"); | 204 | dout(" encrypted ticket\n"); |
| 202 | dlen = ceph_x_decrypt(&old_key, p, end, ticket_buf, | 205 | dlen = ceph_x_decrypt(&old_key, p, end, &ticket_buf, 0); |
| 203 | TEMP_TICKET_BUF_LEN); | ||
| 204 | if (dlen < 0) { | 206 | if (dlen < 0) { |
| 205 | ret = dlen; | 207 | ret = dlen; |
| 206 | goto out; | 208 | goto out; |
| 207 | } | 209 | } |
| 210 | tp = ticket_buf; | ||
| 208 | dlen = ceph_decode_32(&tp); | 211 | dlen = ceph_decode_32(&tp); |
| 209 | } else { | 212 | } else { |
| 210 | /* unencrypted */ | 213 | /* unencrypted */ |
| 211 | ceph_decode_32_safe(p, end, dlen, bad); | 214 | ceph_decode_32_safe(p, end, dlen, bad); |
| 215 | ticket_buf = kmalloc(dlen, GFP_NOFS); | ||
| 216 | if (!ticket_buf) { | ||
| 217 | ret = -ENOMEM; | ||
| 218 | goto out; | ||
| 219 | } | ||
| 220 | tp = ticket_buf; | ||
| 212 | ceph_decode_need(p, end, dlen, bad); | 221 | ceph_decode_need(p, end, dlen, bad); |
| 213 | ceph_decode_copy(p, ticket_buf, dlen); | 222 | ceph_decode_copy(p, ticket_buf, dlen); |
| 214 | } | 223 | } |
| @@ -237,6 +246,8 @@ static int process_one_ticket(struct ceph_auth_client *ac, | |||
| 237 | xi->have_keys |= th->service; | 246 | xi->have_keys |= th->service; |
| 238 | 247 | ||
| 239 | out: | 248 | out: |
| 249 | kfree(ticket_buf); | ||
| 250 | kfree(dbuf); | ||
| 240 | return ret; | 251 | return ret; |
| 241 | 252 | ||
| 242 | bad: | 253 | bad: |
| @@ -249,21 +260,10 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, | |||
| 249 | void *buf, void *end) | 260 | void *buf, void *end) |
| 250 | { | 261 | { |
| 251 | void *p = buf; | 262 | void *p = buf; |
| 252 | char *dbuf; | ||
| 253 | char *ticket_buf; | ||
| 254 | u8 reply_struct_v; | 263 | u8 reply_struct_v; |
| 255 | u32 num; | 264 | u32 num; |
| 256 | int ret; | 265 | int ret; |
| 257 | 266 | ||
| 258 | dbuf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS); | ||
| 259 | if (!dbuf) | ||
| 260 | return -ENOMEM; | ||
| 261 | |||
| 262 | ret = -ENOMEM; | ||
| 263 | ticket_buf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS); | ||
| 264 | if (!ticket_buf) | ||
| 265 | goto out_dbuf; | ||
| 266 | |||
| 267 | ceph_decode_8_safe(&p, end, reply_struct_v, bad); | 267 | ceph_decode_8_safe(&p, end, reply_struct_v, bad); |
| 268 | if (reply_struct_v != 1) | 268 | if (reply_struct_v != 1) |
| 269 | return -EINVAL; | 269 | return -EINVAL; |
| @@ -272,22 +272,15 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, | |||
| 272 | dout("%d tickets\n", num); | 272 | dout("%d tickets\n", num); |
| 273 | 273 | ||
| 274 | while (num--) { | 274 | while (num--) { |
| 275 | ret = process_one_ticket(ac, secret, &p, end, | 275 | ret = process_one_ticket(ac, secret, &p, end); |
| 276 | dbuf, ticket_buf); | ||
| 277 | if (ret) | 276 | if (ret) |
| 278 | goto out; | 277 | return ret; |
| 279 | } | 278 | } |
| 280 | 279 | ||
| 281 | ret = 0; | 280 | return 0; |
| 282 | out: | ||
| 283 | kfree(ticket_buf); | ||
| 284 | out_dbuf: | ||
| 285 | kfree(dbuf); | ||
| 286 | return ret; | ||
| 287 | 281 | ||
| 288 | bad: | 282 | bad: |
| 289 | ret = -EINVAL; | 283 | return -EINVAL; |
| 290 | goto out; | ||
| 291 | } | 284 | } |
| 292 | 285 | ||
| 293 | static int ceph_x_build_authorizer(struct ceph_auth_client *ac, | 286 | static int ceph_x_build_authorizer(struct ceph_auth_client *ac, |
| @@ -603,13 +596,14 @@ static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac, | |||
| 603 | struct ceph_x_ticket_handler *th; | 596 | struct ceph_x_ticket_handler *th; |
| 604 | int ret = 0; | 597 | int ret = 0; |
| 605 | struct ceph_x_authorize_reply reply; | 598 | struct ceph_x_authorize_reply reply; |
| 599 | void *preply = &reply; | ||
| 606 | void *p = au->reply_buf; | 600 | void *p = au->reply_buf; |
| 607 | void *end = p + sizeof(au->reply_buf); | 601 | void *end = p + sizeof(au->reply_buf); |
| 608 | 602 | ||
| 609 | th = get_ticket_handler(ac, au->service); | 603 | th = get_ticket_handler(ac, au->service); |
| 610 | if (IS_ERR(th)) | 604 | if (IS_ERR(th)) |
| 611 | return PTR_ERR(th); | 605 | return PTR_ERR(th); |
| 612 | ret = ceph_x_decrypt(&th->session_key, &p, end, &reply, sizeof(reply)); | 606 | ret = ceph_x_decrypt(&th->session_key, &p, end, &preply, sizeof(reply)); |
| 613 | if (ret < 0) | 607 | if (ret < 0) |
| 614 | return ret; | 608 | return ret; |
| 615 | if (ret != sizeof(reply)) | 609 | if (ret != sizeof(reply)) |
