aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ceph/auth_x.c64
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
18static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed); 16static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed);
19 17
20static int ceph_x_is_authenticated(struct ceph_auth_client *ac) 18static 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
66static int ceph_x_decrypt(struct ceph_crypto_key *secret, 64static 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
132static int process_one_ticket(struct ceph_auth_client *ac, 136static 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
239out: 248out:
249 kfree(ticket_buf);
250 kfree(dbuf);
240 return ret; 251 return ret;
241 252
242bad: 253bad:
@@ -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;
282out:
283 kfree(ticket_buf);
284out_dbuf:
285 kfree(dbuf);
286 return ret;
287 281
288bad: 282bad:
289 ret = -EINVAL; 283 return -EINVAL;
290 goto out;
291} 284}
292 285
293static int ceph_x_build_authorizer(struct ceph_auth_client *ac, 286static 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))