Skip to content

Commit cd1a677

Browse files
committed
libceph, ceph: implement msgr2.1 protocol (crc and secure modes)
Implement msgr2.1 wire protocol, available since nautilus 14.2.11 and octopus 15.2.5. msgr2.0 wire protocol is not implemented -- it has several security, integrity and robustness issues and therefore considered deprecated. Signed-off-by: Ilya Dryomov <[email protected]>
1 parent 00498b9 commit cd1a677

File tree

15 files changed

+4356
-31
lines changed

15 files changed

+4356
-31
lines changed

fs/ceph/mds_client.c

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5014,7 +5014,7 @@ void ceph_mdsc_handle_mdsmap(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
50145014
return;
50155015
}
50165016

5017-
newmap = ceph_mdsmap_decode(&p, end, false);
5017+
newmap = ceph_mdsmap_decode(&p, end, ceph_msgr2(mdsc->fsc->client));
50185018
if (IS_ERR(newmap)) {
50195019
err = PTR_ERR(newmap);
50205020
goto bad_unlock;
@@ -5196,6 +5196,80 @@ static int invalidate_authorizer(struct ceph_connection *con)
51965196
return ceph_monc_validate_auth(&mdsc->fsc->client->monc);
51975197
}
51985198

5199+
static int mds_get_auth_request(struct ceph_connection *con,
5200+
void *buf, int *buf_len,
5201+
void **authorizer, int *authorizer_len)
5202+
{
5203+
struct ceph_mds_session *s = con->private;
5204+
struct ceph_auth_client *ac = s->s_mdsc->fsc->client->monc.auth;
5205+
struct ceph_auth_handshake *auth = &s->s_auth;
5206+
int ret;
5207+
5208+
ret = ceph_auth_get_authorizer(ac, auth, CEPH_ENTITY_TYPE_MDS,
5209+
buf, buf_len);
5210+
if (ret)
5211+
return ret;
5212+
5213+
*authorizer = auth->authorizer_buf;
5214+
*authorizer_len = auth->authorizer_buf_len;
5215+
return 0;
5216+
}
5217+
5218+
static int mds_handle_auth_reply_more(struct ceph_connection *con,
5219+
void *reply, int reply_len,
5220+
void *buf, int *buf_len,
5221+
void **authorizer, int *authorizer_len)
5222+
{
5223+
struct ceph_mds_session *s = con->private;
5224+
struct ceph_auth_client *ac = s->s_mdsc->fsc->client->monc.auth;
5225+
struct ceph_auth_handshake *auth = &s->s_auth;
5226+
int ret;
5227+
5228+
ret = ceph_auth_handle_svc_reply_more(ac, auth, reply, reply_len,
5229+
buf, buf_len);
5230+
if (ret)
5231+
return ret;
5232+
5233+
*authorizer = auth->authorizer_buf;
5234+
*authorizer_len = auth->authorizer_buf_len;
5235+
return 0;
5236+
}
5237+
5238+
static int mds_handle_auth_done(struct ceph_connection *con,
5239+
u64 global_id, void *reply, int reply_len,
5240+
u8 *session_key, int *session_key_len,
5241+
u8 *con_secret, int *con_secret_len)
5242+
{
5243+
struct ceph_mds_session *s = con->private;
5244+
struct ceph_auth_client *ac = s->s_mdsc->fsc->client->monc.auth;
5245+
struct ceph_auth_handshake *auth = &s->s_auth;
5246+
5247+
return ceph_auth_handle_svc_reply_done(ac, auth, reply, reply_len,
5248+
session_key, session_key_len,
5249+
con_secret, con_secret_len);
5250+
}
5251+
5252+
static int mds_handle_auth_bad_method(struct ceph_connection *con,
5253+
int used_proto, int result,
5254+
const int *allowed_protos, int proto_cnt,
5255+
const int *allowed_modes, int mode_cnt)
5256+
{
5257+
struct ceph_mds_session *s = con->private;
5258+
struct ceph_mon_client *monc = &s->s_mdsc->fsc->client->monc;
5259+
int ret;
5260+
5261+
if (ceph_auth_handle_bad_authorizer(monc->auth, CEPH_ENTITY_TYPE_MDS,
5262+
used_proto, result,
5263+
allowed_protos, proto_cnt,
5264+
allowed_modes, mode_cnt)) {
5265+
ret = ceph_monc_validate_auth(monc);
5266+
if (ret)
5267+
return ret;
5268+
}
5269+
5270+
return -EACCES;
5271+
}
5272+
51995273
static struct ceph_msg *mds_alloc_msg(struct ceph_connection *con,
52005274
struct ceph_msg_header *hdr, int *skip)
52015275
{
@@ -5245,6 +5319,10 @@ static const struct ceph_connection_operations mds_con_ops = {
52455319
.alloc_msg = mds_alloc_msg,
52465320
.sign_message = mds_sign_message,
52475321
.check_message_signature = mds_check_message_signature,
5322+
.get_auth_request = mds_get_auth_request,
5323+
.handle_auth_reply_more = mds_handle_auth_reply_more,
5324+
.handle_auth_done = mds_handle_auth_done,
5325+
.handle_auth_bad_method = mds_handle_auth_bad_method,
52485326
};
52495327

52505328
/* eof */

include/linux/ceph/auth.h

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,12 @@ int ceph_auth_entity_name_encode(const char *name, void **p, void *end);
120120

121121
extern int ceph_build_auth(struct ceph_auth_client *ac,
122122
void *msg_buf, size_t msg_len);
123-
124123
extern int ceph_auth_is_authenticated(struct ceph_auth_client *ac);
124+
125+
int __ceph_auth_get_authorizer(struct ceph_auth_client *ac,
126+
struct ceph_auth_handshake *auth,
127+
int peer_type, bool force_new,
128+
int *proto, int *pref_mode, int *fallb_mode);
125129
extern int ceph_auth_create_authorizer(struct ceph_auth_client *ac,
126130
int peer_type,
127131
struct ceph_auth_handshake *auth);
@@ -157,4 +161,34 @@ int ceph_auth_check_message_signature(struct ceph_auth_handshake *auth,
157161
return auth->check_message_signature(auth, msg);
158162
return 0;
159163
}
164+
165+
int ceph_auth_get_request(struct ceph_auth_client *ac, void *buf, int buf_len);
166+
int ceph_auth_handle_reply_more(struct ceph_auth_client *ac, void *reply,
167+
int reply_len, void *buf, int buf_len);
168+
int ceph_auth_handle_reply_done(struct ceph_auth_client *ac,
169+
u64 global_id, void *reply, int reply_len,
170+
u8 *session_key, int *session_key_len,
171+
u8 *con_secret, int *con_secret_len);
172+
bool ceph_auth_handle_bad_method(struct ceph_auth_client *ac,
173+
int used_proto, int result,
174+
const int *allowed_protos, int proto_cnt,
175+
const int *allowed_modes, int mode_cnt);
176+
177+
int ceph_auth_get_authorizer(struct ceph_auth_client *ac,
178+
struct ceph_auth_handshake *auth,
179+
int peer_type, void *buf, int *buf_len);
180+
int ceph_auth_handle_svc_reply_more(struct ceph_auth_client *ac,
181+
struct ceph_auth_handshake *auth,
182+
void *reply, int reply_len,
183+
void *buf, int *buf_len);
184+
int ceph_auth_handle_svc_reply_done(struct ceph_auth_client *ac,
185+
struct ceph_auth_handshake *auth,
186+
void *reply, int reply_len,
187+
u8 *session_key, int *session_key_len,
188+
u8 *con_secret, int *con_secret_len);
189+
bool ceph_auth_handle_bad_authorizer(struct ceph_auth_client *ac,
190+
int peer_type, int used_proto, int result,
191+
const int *allowed_protos, int proto_cnt,
192+
const int *allowed_modes, int mode_cnt);
193+
160194
#endif

include/linux/ceph/ceph_fs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ struct ceph_dir_layout {
9393
#define CEPH_AUTH_NONE 0x1
9494
#define CEPH_AUTH_CEPHX 0x2
9595

96+
#define CEPH_AUTH_MODE_NONE 0
97+
#define CEPH_AUTH_MODE_AUTHORIZER 1
98+
#define CEPH_AUTH_MODE_MON 10
99+
96100
/* msgr2 protocol modes */
97101
#define CEPH_CON_MODE_UNKNOWN 0x0
98102
#define CEPH_CON_MODE_CRC 0x1

include/linux/ceph/decode.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ static inline void ceph_encode_timespec64(struct ceph_timespec *tv,
221221
#define CEPH_ENTITY_ADDR_TYPE_NONE 0
222222
#define CEPH_ENTITY_ADDR_TYPE_LEGACY __cpu_to_le32(1)
223223
#define CEPH_ENTITY_ADDR_TYPE_MSGR2 __cpu_to_le32(2)
224+
#define CEPH_ENTITY_ADDR_TYPE_ANY __cpu_to_le32(3)
224225

225226
static inline void ceph_encode_banner_addr(struct ceph_entity_addr *a)
226227
{
@@ -243,6 +244,9 @@ extern int ceph_decode_entity_addr(void **p, void *end,
243244
int ceph_decode_entity_addrvec(void **p, void *end, bool msgr2,
244245
struct ceph_entity_addr *addr);
245246

247+
int ceph_entity_addr_encoding_len(const struct ceph_entity_addr *addr);
248+
void ceph_encode_entity_addr(void **p, const struct ceph_entity_addr *addr);
249+
246250
/*
247251
* encoders
248252
*/

include/linux/ceph/libceph.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@
3131
#define CEPH_OPT_FSID (1<<0)
3232
#define CEPH_OPT_NOSHARE (1<<1) /* don't share client with other sbs */
3333
#define CEPH_OPT_MYIP (1<<2) /* specified my ip */
34-
#define CEPH_OPT_NOCRC (1<<3) /* no data crc on writes */
34+
#define CEPH_OPT_NOCRC (1<<3) /* no data crc on writes (msgr1) */
3535
#define CEPH_OPT_NOMSGAUTH (1<<4) /* don't require msg signing feat */
3636
#define CEPH_OPT_TCP_NODELAY (1<<5) /* TCP_NODELAY on TCP sockets */
37-
#define CEPH_OPT_NOMSGSIGN (1<<6) /* don't sign msgs */
37+
#define CEPH_OPT_NOMSGSIGN (1<<6) /* don't sign msgs (msgr1) */
3838
#define CEPH_OPT_ABORT_ON_FULL (1<<7) /* abort w/ ENOSPC when full */
3939

4040
#define CEPH_OPT_DEFAULT (CEPH_OPT_TCP_NODELAY)
@@ -84,6 +84,7 @@ struct ceph_options {
8484
#define CEPH_MONC_HUNT_BACKOFF 2
8585
#define CEPH_MONC_HUNT_MAX_MULT 10
8686

87+
#define CEPH_MSG_MAX_CONTROL_LEN (16*1024*1024)
8788
#define CEPH_MSG_MAX_FRONT_LEN (16*1024*1024)
8889
#define CEPH_MSG_MAX_MIDDLE_LEN (16*1024*1024)
8990

@@ -152,6 +153,10 @@ struct ceph_client {
152153

153154
#define from_msgr(ms) container_of(ms, struct ceph_client, msgr)
154155

156+
static inline bool ceph_msgr2(struct ceph_client *client)
157+
{
158+
return client->options->con_modes[0] != CEPH_CON_MODE_UNKNOWN;
159+
}
155160

156161
/*
157162
* snapshots

include/linux/ceph/messenger.h

Lines changed: 133 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#define __FS_CEPH_MESSENGER_H
44

55
#include <linux/bvec.h>
6+
#include <linux/crypto.h>
67
#include <linux/kref.h>
78
#include <linux/mutex.h>
89
#include <linux/net.h>
@@ -52,6 +53,23 @@ struct ceph_connection_operations {
5253

5354
int (*sign_message) (struct ceph_msg *msg);
5455
int (*check_message_signature) (struct ceph_msg *msg);
56+
57+
/* msgr2 authentication exchange */
58+
int (*get_auth_request)(struct ceph_connection *con,
59+
void *buf, int *buf_len,
60+
void **authorizer, int *authorizer_len);
61+
int (*handle_auth_reply_more)(struct ceph_connection *con,
62+
void *reply, int reply_len,
63+
void *buf, int *buf_len,
64+
void **authorizer, int *authorizer_len);
65+
int (*handle_auth_done)(struct ceph_connection *con,
66+
u64 global_id, void *reply, int reply_len,
67+
u8 *session_key, int *session_key_len,
68+
u8 *con_secret, int *con_secret_len);
69+
int (*handle_auth_bad_method)(struct ceph_connection *con,
70+
int used_proto, int result,
71+
const int *allowed_protos, int proto_cnt,
72+
const int *allowed_modes, int mode_cnt);
5573
};
5674

5775
/* use format string %s%lld */
@@ -246,8 +264,15 @@ struct ceph_msg {
246264
#define CEPH_CON_S_PREOPEN 2
247265
#define CEPH_CON_S_V1_BANNER 3
248266
#define CEPH_CON_S_V1_CONNECT_MSG 4
249-
#define CEPH_CON_S_OPEN 5
250-
#define CEPH_CON_S_STANDBY 6
267+
#define CEPH_CON_S_V2_BANNER_PREFIX 5
268+
#define CEPH_CON_S_V2_BANNER_PAYLOAD 6
269+
#define CEPH_CON_S_V2_HELLO 7
270+
#define CEPH_CON_S_V2_AUTH 8
271+
#define CEPH_CON_S_V2_AUTH_SIGNATURE 9
272+
#define CEPH_CON_S_V2_SESSION_CONNECT 10
273+
#define CEPH_CON_S_V2_SESSION_RECONNECT 11
274+
#define CEPH_CON_S_OPEN 12
275+
#define CEPH_CON_S_STANDBY 13
251276

252277
/*
253278
* ceph_connection flag bits
@@ -301,6 +326,99 @@ struct ceph_connection_v1_info {
301326
u32 peer_global_seq; /* peer's global seq for this connection */
302327
};
303328

329+
#define CEPH_CRC_LEN 4
330+
#define CEPH_GCM_KEY_LEN 16
331+
#define CEPH_GCM_IV_LEN sizeof(struct ceph_gcm_nonce)
332+
#define CEPH_GCM_BLOCK_LEN 16
333+
#define CEPH_GCM_TAG_LEN 16
334+
335+
#define CEPH_PREAMBLE_LEN 32
336+
#define CEPH_PREAMBLE_INLINE_LEN 48
337+
#define CEPH_PREAMBLE_PLAIN_LEN CEPH_PREAMBLE_LEN
338+
#define CEPH_PREAMBLE_SECURE_LEN (CEPH_PREAMBLE_LEN + \
339+
CEPH_PREAMBLE_INLINE_LEN + \
340+
CEPH_GCM_TAG_LEN)
341+
#define CEPH_EPILOGUE_PLAIN_LEN (1 + 3 * CEPH_CRC_LEN)
342+
#define CEPH_EPILOGUE_SECURE_LEN (CEPH_GCM_BLOCK_LEN + CEPH_GCM_TAG_LEN)
343+
344+
#define CEPH_FRAME_MAX_SEGMENT_COUNT 4
345+
346+
struct ceph_frame_desc {
347+
int fd_tag; /* FRAME_TAG_* */
348+
int fd_seg_cnt;
349+
int fd_lens[CEPH_FRAME_MAX_SEGMENT_COUNT]; /* logical */
350+
int fd_aligns[CEPH_FRAME_MAX_SEGMENT_COUNT];
351+
};
352+
353+
struct ceph_gcm_nonce {
354+
__le32 fixed;
355+
__le64 counter __packed;
356+
};
357+
358+
struct ceph_connection_v2_info {
359+
struct iov_iter in_iter;
360+
struct kvec in_kvecs[5]; /* recvmsg */
361+
struct bio_vec in_bvec; /* recvmsg (in_cursor) */
362+
int in_kvec_cnt;
363+
int in_state; /* IN_S_* */
364+
365+
struct iov_iter out_iter;
366+
struct kvec out_kvecs[8]; /* sendmsg */
367+
struct bio_vec out_bvec; /* sendpage (out_cursor, out_zero),
368+
sendmsg (out_enc_pages) */
369+
int out_kvec_cnt;
370+
int out_state; /* OUT_S_* */
371+
372+
int out_zero; /* # of zero bytes to send */
373+
bool out_iter_sendpage; /* use sendpage if possible */
374+
375+
struct ceph_frame_desc in_desc;
376+
struct ceph_msg_data_cursor in_cursor;
377+
struct ceph_msg_data_cursor out_cursor;
378+
379+
struct crypto_shash *hmac_tfm; /* post-auth signature */
380+
struct crypto_aead *gcm_tfm; /* on-wire encryption */
381+
struct aead_request *gcm_req;
382+
struct crypto_wait gcm_wait;
383+
struct ceph_gcm_nonce in_gcm_nonce;
384+
struct ceph_gcm_nonce out_gcm_nonce;
385+
386+
struct page **out_enc_pages;
387+
int out_enc_page_cnt;
388+
int out_enc_resid;
389+
int out_enc_i;
390+
391+
int con_mode; /* CEPH_CON_MODE_* */
392+
393+
void *conn_bufs[16];
394+
int conn_buf_cnt;
395+
396+
struct kvec in_sign_kvecs[8];
397+
struct kvec out_sign_kvecs[8];
398+
int in_sign_kvec_cnt;
399+
int out_sign_kvec_cnt;
400+
401+
u64 client_cookie;
402+
u64 server_cookie;
403+
u64 global_seq;
404+
u64 connect_seq;
405+
u64 peer_global_seq;
406+
407+
u8 in_buf[CEPH_PREAMBLE_SECURE_LEN];
408+
u8 out_buf[CEPH_PREAMBLE_SECURE_LEN];
409+
struct {
410+
u8 late_status; /* FRAME_LATE_STATUS_* */
411+
union {
412+
struct {
413+
u32 front_crc;
414+
u32 middle_crc;
415+
u32 data_crc;
416+
} __packed;
417+
u8 pad[CEPH_GCM_BLOCK_LEN - 1];
418+
};
419+
} out_epil;
420+
};
421+
304422
/*
305423
* A single connection with another host.
306424
*
@@ -346,7 +464,10 @@ struct ceph_connection {
346464
struct delayed_work work; /* send|recv work */
347465
unsigned long delay; /* current delay interval */
348466

349-
struct ceph_connection_v1_info v1;
467+
union {
468+
struct ceph_connection_v1_info v1;
469+
struct ceph_connection_v2_info v2;
470+
};
350471
};
351472

352473
extern struct page *ceph_zero_page;
@@ -397,6 +518,15 @@ bool ceph_con_v1_opened(struct ceph_connection *con);
397518
void ceph_con_v1_reset_session(struct ceph_connection *con);
398519
void ceph_con_v1_reset_protocol(struct ceph_connection *con);
399520

521+
/* messenger_v2.c */
522+
int ceph_con_v2_try_read(struct ceph_connection *con);
523+
int ceph_con_v2_try_write(struct ceph_connection *con);
524+
void ceph_con_v2_revoke(struct ceph_connection *con);
525+
void ceph_con_v2_revoke_incoming(struct ceph_connection *con);
526+
bool ceph_con_v2_opened(struct ceph_connection *con);
527+
void ceph_con_v2_reset_session(struct ceph_connection *con);
528+
void ceph_con_v2_reset_protocol(struct ceph_connection *con);
529+
400530

401531
extern const char *ceph_pr_addr(const struct ceph_entity_addr *addr);
402532

0 commit comments

Comments
 (0)