Commit 6610fff2 authored by Ilya Dryomov's avatar Ilya Dryomov

libceph: safer en/decoding of cephx requests and replies

Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent f79e25b0
...@@ -200,7 +200,7 @@ static int process_one_ticket(struct ceph_auth_client *ac, ...@@ -200,7 +200,7 @@ static int process_one_ticket(struct ceph_auth_client *ac,
dout(" decrypted %d bytes\n", ret); dout(" decrypted %d bytes\n", ret);
dend = dp + ret; dend = dp + ret;
tkt_struct_v = ceph_decode_8(&dp); ceph_decode_8_safe(&dp, dend, tkt_struct_v, bad);
if (tkt_struct_v != 1) if (tkt_struct_v != 1)
goto bad; goto bad;
...@@ -208,6 +208,7 @@ static int process_one_ticket(struct ceph_auth_client *ac, ...@@ -208,6 +208,7 @@ static int process_one_ticket(struct ceph_auth_client *ac,
if (ret) if (ret)
goto out; goto out;
ceph_decode_need(&dp, dend, sizeof(struct ceph_timespec), bad);
ceph_decode_timespec64(&validity, dp); ceph_decode_timespec64(&validity, dp);
dp += sizeof(struct ceph_timespec); dp += sizeof(struct ceph_timespec);
new_expires = ktime_get_real_seconds() + validity.tv_sec; new_expires = ktime_get_real_seconds() + validity.tv_sec;
...@@ -491,6 +492,7 @@ static int ceph_x_build_request(struct ceph_auth_client *ac, ...@@ -491,6 +492,7 @@ static int ceph_x_build_request(struct ceph_auth_client *ac,
struct ceph_x_info *xi = ac->private; struct ceph_x_info *xi = ac->private;
int need; int need;
struct ceph_x_request_header *head = buf; struct ceph_x_request_header *head = buf;
void *p;
int ret; int ret;
struct ceph_x_ticket_handler *th = struct ceph_x_ticket_handler *th =
get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH); get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH);
...@@ -504,12 +506,12 @@ static int ceph_x_build_request(struct ceph_auth_client *ac, ...@@ -504,12 +506,12 @@ static int ceph_x_build_request(struct ceph_auth_client *ac,
if (need & CEPH_ENTITY_TYPE_AUTH) { if (need & CEPH_ENTITY_TYPE_AUTH) {
struct ceph_x_authenticate *auth = (void *)(head + 1); struct ceph_x_authenticate *auth = (void *)(head + 1);
void *p = auth + 1;
void *enc_buf = xi->auth_authorizer.enc_buf; void *enc_buf = xi->auth_authorizer.enc_buf;
struct ceph_x_challenge_blob *blob = enc_buf + struct ceph_x_challenge_blob *blob = enc_buf +
ceph_x_encrypt_offset(); ceph_x_encrypt_offset();
u64 *u; u64 *u;
p = auth + 1;
if (p > end) if (p > end)
return -ERANGE; return -ERANGE;
...@@ -542,35 +544,35 @@ static int ceph_x_build_request(struct ceph_auth_client *ac, ...@@ -542,35 +544,35 @@ static int ceph_x_build_request(struct ceph_auth_client *ac,
} }
if (need) { if (need) {
void *p = head + 1; dout(" get_principal_session_key\n");
struct ceph_x_service_ticket_request *req;
if (p > end)
return -ERANGE;
head->op = cpu_to_le16(CEPHX_GET_PRINCIPAL_SESSION_KEY);
ret = ceph_x_build_authorizer(ac, th, &xi->auth_authorizer); ret = ceph_x_build_authorizer(ac, th, &xi->auth_authorizer);
if (ret) if (ret)
return ret; return ret;
ceph_encode_copy(&p, xi->auth_authorizer.buf->vec.iov_base,
xi->auth_authorizer.buf->vec.iov_len);
req = p; p = buf;
req->keys = cpu_to_le32(need); ceph_encode_16_safe(&p, end, CEPHX_GET_PRINCIPAL_SESSION_KEY,
p += sizeof(*req); e_range);
ceph_encode_copy_safe(&p, end,
xi->auth_authorizer.buf->vec.iov_base,
xi->auth_authorizer.buf->vec.iov_len, e_range);
ceph_encode_8_safe(&p, end, 1, e_range);
ceph_encode_32_safe(&p, end, need, e_range);
return p - buf; return p - buf;
} }
return 0; return 0;
e_range:
return -ERANGE;
} }
static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result, static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result,
void *buf, void *end) void *buf, void *end)
{ {
struct ceph_x_info *xi = ac->private; struct ceph_x_info *xi = ac->private;
struct ceph_x_reply_header *head = buf;
struct ceph_x_ticket_handler *th; struct ceph_x_ticket_handler *th;
int len = end - buf; int len = end - buf;
void *p;
int op; int op;
int ret; int ret;
...@@ -591,22 +593,22 @@ static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result, ...@@ -591,22 +593,22 @@ static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result,
return -EAGAIN; return -EAGAIN;
} }
op = le16_to_cpu(head->op); p = buf;
result = le32_to_cpu(head->result); ceph_decode_16_safe(&p, end, op, e_inval);
ceph_decode_32_safe(&p, end, result, e_inval);
dout("handle_reply op %d result %d\n", op, result); dout("handle_reply op %d result %d\n", op, result);
switch (op) { switch (op) {
case CEPHX_GET_AUTH_SESSION_KEY: case CEPHX_GET_AUTH_SESSION_KEY:
/* verify auth key */ /* verify auth key */
ret = ceph_x_proc_ticket_reply(ac, &xi->secret, ret = ceph_x_proc_ticket_reply(ac, &xi->secret, p, end);
buf + sizeof(*head), end);
break; break;
case CEPHX_GET_PRINCIPAL_SESSION_KEY: case CEPHX_GET_PRINCIPAL_SESSION_KEY:
th = get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH); th = get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH);
if (IS_ERR(th)) if (IS_ERR(th))
return PTR_ERR(th); return PTR_ERR(th);
ret = ceph_x_proc_ticket_reply(ac, &th->session_key,
buf + sizeof(*head), end); ret = ceph_x_proc_ticket_reply(ac, &th->session_key, p, end);
break; break;
default: default:
...@@ -617,6 +619,9 @@ static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result, ...@@ -617,6 +619,9 @@ static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result,
if (ac->want_keys == xi->have_keys) if (ac->want_keys == xi->have_keys)
return 0; return 0;
return -EAGAIN; return -EAGAIN;
e_inval:
return -EINVAL;
} }
static void ceph_x_destroy_authorizer(struct ceph_authorizer *a) static void ceph_x_destroy_authorizer(struct ceph_authorizer *a)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment