Skip to content

Commit 0a990e7

Browse files
committed
ceph: clean up service ticket decoding
Previously we would decode state directly into our current ticket_handler. This is problematic if for some reason we fail to decode, because we end up with half new state and half old state. We are probably already in bad shape if we get an update we can't decode, but we may as well be tidy anyway. Decode into new_* temporaries and update the ticket_handler only on success. Signed-off-by: Sage Weil <sage@newdream.net>
1 parent 5b3dbb4 commit 0a990e7

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

fs/ceph/auth_x.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,11 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
156156
struct timespec validity;
157157
struct ceph_crypto_key old_key;
158158
void *tp, *tpend;
159+
struct ceph_timespec new_validity;
160+
struct ceph_crypto_key new_session_key;
159161
struct ceph_buffer *new_ticket_blob;
162+
unsigned long new_expires, new_renew_after;
163+
u64 new_secret_id;
160164

161165
ceph_decode_need(&p, end, sizeof(u32) + 1, bad);
162166

@@ -189,16 +193,16 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
189193
goto bad;
190194

191195
memcpy(&old_key, &th->session_key, sizeof(old_key));
192-
ret = ceph_crypto_key_decode(&th->session_key, &dp, dend);
196+
ret = ceph_crypto_key_decode(&new_session_key, &dp, dend);
193197
if (ret)
194198
goto out;
195199

196-
ceph_decode_copy(&dp, &th->validity, sizeof(th->validity));
197-
ceph_decode_timespec(&validity, &th->validity);
198-
th->expires = get_seconds() + validity.tv_sec;
199-
th->renew_after = th->expires - (validity.tv_sec / 4);
200-
dout(" expires=%lu renew_after=%lu\n", th->expires,
201-
th->renew_after);
200+
ceph_decode_copy(&dp, &new_validity, sizeof(new_validity));
201+
ceph_decode_timespec(&validity, &new_validity);
202+
new_expires = get_seconds() + validity.tv_sec;
203+
new_renew_after = new_expires - (validity.tv_sec / 4);
204+
dout(" expires=%lu renew_after=%lu\n", new_expires,
205+
new_renew_after);
202206

203207
/* ticket blob for service */
204208
ceph_decode_8_safe(&p, end, is_enc, bad);
@@ -223,13 +227,21 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
223227
dout(" ticket blob is %d bytes\n", dlen);
224228
ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad);
225229
struct_v = ceph_decode_8(&tp);
226-
th->secret_id = ceph_decode_64(&tp);
230+
new_secret_id = ceph_decode_64(&tp);
227231
ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend);
228232
if (ret)
229233
goto out;
234+
235+
/* all is well, update our ticket */
236+
ceph_crypto_key_destroy(&th->session_key);
230237
if (th->ticket_blob)
231238
ceph_buffer_put(th->ticket_blob);
239+
th->session_key = new_session_key;
232240
th->ticket_blob = new_ticket_blob;
241+
th->validity = new_validity;
242+
th->secret_id = new_secret_id;
243+
th->expires = new_expires;
244+
th->renew_after = new_renew_after;
233245
dout(" got ticket service %d (%s) secret_id %lld len %d\n",
234246
type, ceph_entity_type_name(type), th->secret_id,
235247
(int)th->ticket_blob->vec.iov_len);

0 commit comments

Comments
 (0)