Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

libceph: safer en/decoding of cephx requests and replies

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>

+26 -21
+26 -21
net/ceph/auth_x.c
··· 200 200 dout(" decrypted %d bytes\n", ret); 201 201 dend = dp + ret; 202 202 203 - tkt_struct_v = ceph_decode_8(&dp); 203 + ceph_decode_8_safe(&dp, dend, tkt_struct_v, bad); 204 204 if (tkt_struct_v != 1) 205 205 goto bad; 206 206 ··· 208 208 if (ret) 209 209 goto out; 210 210 211 + ceph_decode_need(&dp, dend, sizeof(struct ceph_timespec), bad); 211 212 ceph_decode_timespec64(&validity, dp); 212 213 dp += sizeof(struct ceph_timespec); 213 214 new_expires = ktime_get_real_seconds() + validity.tv_sec; ··· 492 491 struct ceph_x_info *xi = ac->private; 493 492 int need; 494 493 struct ceph_x_request_header *head = buf; 494 + void *p; 495 495 int ret; 496 496 struct ceph_x_ticket_handler *th = 497 497 get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH); ··· 506 504 507 505 if (need & CEPH_ENTITY_TYPE_AUTH) { 508 506 struct ceph_x_authenticate *auth = (void *)(head + 1); 509 - void *p = auth + 1; 510 507 void *enc_buf = xi->auth_authorizer.enc_buf; 511 508 struct ceph_x_challenge_blob *blob = enc_buf + 512 509 ceph_x_encrypt_offset(); 513 510 u64 *u; 514 511 512 + p = auth + 1; 515 513 if (p > end) 516 514 return -ERANGE; 517 515 ··· 544 542 } 545 543 546 544 if (need) { 547 - void *p = head + 1; 548 - struct ceph_x_service_ticket_request *req; 549 - 550 - if (p > end) 551 - return -ERANGE; 552 - head->op = cpu_to_le16(CEPHX_GET_PRINCIPAL_SESSION_KEY); 553 - 545 + dout(" get_principal_session_key\n"); 554 546 ret = ceph_x_build_authorizer(ac, th, &xi->auth_authorizer); 555 547 if (ret) 556 548 return ret; 557 - ceph_encode_copy(&p, xi->auth_authorizer.buf->vec.iov_base, 558 - xi->auth_authorizer.buf->vec.iov_len); 559 549 560 - req = p; 561 - req->keys = cpu_to_le32(need); 562 - p += sizeof(*req); 550 + p = buf; 551 + ceph_encode_16_safe(&p, end, CEPHX_GET_PRINCIPAL_SESSION_KEY, 552 + e_range); 553 + ceph_encode_copy_safe(&p, end, 554 + xi->auth_authorizer.buf->vec.iov_base, 555 + xi->auth_authorizer.buf->vec.iov_len, e_range); 556 + ceph_encode_8_safe(&p, end, 1, e_range); 557 + ceph_encode_32_safe(&p, end, need, e_range); 563 558 return p - buf; 564 559 } 565 560 566 561 return 0; 562 + 563 + e_range: 564 + return -ERANGE; 567 565 } 568 566 569 567 static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result, 570 568 void *buf, void *end) 571 569 { 572 570 struct ceph_x_info *xi = ac->private; 573 - struct ceph_x_reply_header *head = buf; 574 571 struct ceph_x_ticket_handler *th; 575 572 int len = end - buf; 573 + void *p; 576 574 int op; 577 575 int ret; 578 576 ··· 593 591 return -EAGAIN; 594 592 } 595 593 596 - op = le16_to_cpu(head->op); 597 - result = le32_to_cpu(head->result); 594 + p = buf; 595 + ceph_decode_16_safe(&p, end, op, e_inval); 596 + ceph_decode_32_safe(&p, end, result, e_inval); 598 597 dout("handle_reply op %d result %d\n", op, result); 599 598 switch (op) { 600 599 case CEPHX_GET_AUTH_SESSION_KEY: 601 600 /* verify auth key */ 602 - ret = ceph_x_proc_ticket_reply(ac, &xi->secret, 603 - buf + sizeof(*head), end); 601 + ret = ceph_x_proc_ticket_reply(ac, &xi->secret, p, end); 604 602 break; 605 603 606 604 case CEPHX_GET_PRINCIPAL_SESSION_KEY: 607 605 th = get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH); 608 606 if (IS_ERR(th)) 609 607 return PTR_ERR(th); 610 - ret = ceph_x_proc_ticket_reply(ac, &th->session_key, 611 - buf + sizeof(*head), end); 608 + 609 + ret = ceph_x_proc_ticket_reply(ac, &th->session_key, p, end); 612 610 break; 613 611 614 612 default: ··· 619 617 if (ac->want_keys == xi->have_keys) 620 618 return 0; 621 619 return -EAGAIN; 620 + 621 + e_inval: 622 + return -EINVAL; 622 623 } 623 624 624 625 static void ceph_x_destroy_authorizer(struct ceph_authorizer *a)