aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-03-25 13:26:30 -0400
committerSage Weil <sage@inktank.com>2013-05-02 00:17:15 -0400
commite9966076cdd952e19f2dd4854cd719be0d7cbebc (patch)
treec65c356996fcb0b58c5a9353011ae1cdc54ac577
parent27859f9773e4a0b2042435b13400ee2c891a61f4 (diff)
libceph: wrap auth methods in a mutex
The auth code is called from a variety of contexts, include the mon_client (protected by the monc's mutex) and the messenger callbacks (currently protected by nothing). Avoid chaos by protecting all auth state with a mutex. Nothing is blocking, so this should be simple and lightweight. Signed-off-by: Sage Weil <sage@inktank.com> Reviewed-by: Alex Elder <elder@inktank.com>
-rw-r--r--include/linux/ceph/auth.h2
-rw-r--r--net/ceph/auth.c78
2 files changed, 58 insertions, 22 deletions
diff --git a/include/linux/ceph/auth.h b/include/linux/ceph/auth.h
index c9c3b3abe4a3..5f3386844134 100644
--- a/include/linux/ceph/auth.h
+++ b/include/linux/ceph/auth.h
@@ -78,6 +78,8 @@ struct ceph_auth_client {
78 u64 global_id; /* our unique id in system */ 78 u64 global_id; /* our unique id in system */
79 const struct ceph_crypto_key *key; /* our secret key */ 79 const struct ceph_crypto_key *key; /* our secret key */
80 unsigned want_keys; /* which services we want */ 80 unsigned want_keys; /* which services we want */
81
82 struct mutex mutex;
81}; 83};
82 84
83extern struct ceph_auth_client *ceph_auth_init(const char *name, 85extern struct ceph_auth_client *ceph_auth_init(const char *name,
diff --git a/net/ceph/auth.c b/net/ceph/auth.c
index a22de543cedb..6b923bcaa2a4 100644
--- a/net/ceph/auth.c
+++ b/net/ceph/auth.c
@@ -47,6 +47,7 @@ struct ceph_auth_client *ceph_auth_init(const char *name, const struct ceph_cryp
47 if (!ac) 47 if (!ac)
48 goto out; 48 goto out;
49 49
50 mutex_init(&ac->mutex);
50 ac->negotiating = true; 51 ac->negotiating = true;
51 if (name) 52 if (name)
52 ac->name = name; 53 ac->name = name;
@@ -73,10 +74,12 @@ void ceph_auth_destroy(struct ceph_auth_client *ac)
73 */ 74 */
74void ceph_auth_reset(struct ceph_auth_client *ac) 75void ceph_auth_reset(struct ceph_auth_client *ac)
75{ 76{
77 mutex_lock(&ac->mutex);
76 dout("auth_reset %p\n", ac); 78 dout("auth_reset %p\n", ac);
77 if (ac->ops && !ac->negotiating) 79 if (ac->ops && !ac->negotiating)
78 ac->ops->reset(ac); 80 ac->ops->reset(ac);
79 ac->negotiating = true; 81 ac->negotiating = true;
82 mutex_unlock(&ac->mutex);
80} 83}
81 84
82int ceph_entity_name_encode(const char *name, void **p, void *end) 85int ceph_entity_name_encode(const char *name, void **p, void *end)
@@ -102,6 +105,7 @@ int ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len)
102 int i, num; 105 int i, num;
103 int ret; 106 int ret;
104 107
108 mutex_lock(&ac->mutex);
105 dout("auth_build_hello\n"); 109 dout("auth_build_hello\n");
106 monhdr->have_version = 0; 110 monhdr->have_version = 0;
107 monhdr->session_mon = cpu_to_le16(-1); 111 monhdr->session_mon = cpu_to_le16(-1);
@@ -122,15 +126,19 @@ int ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len)
122 126
123 ret = ceph_entity_name_encode(ac->name, &p, end); 127 ret = ceph_entity_name_encode(ac->name, &p, end);
124 if (ret < 0) 128 if (ret < 0)
125 return ret; 129 goto out;
126 ceph_decode_need(&p, end, sizeof(u64), bad); 130 ceph_decode_need(&p, end, sizeof(u64), bad);
127 ceph_encode_64(&p, ac->global_id); 131 ceph_encode_64(&p, ac->global_id);
128 132
129 ceph_encode_32(&lenp, p - lenp - sizeof(u32)); 133 ceph_encode_32(&lenp, p - lenp - sizeof(u32));
130 return p - buf; 134 ret = p - buf;
135out:
136 mutex_unlock(&ac->mutex);
137 return ret;
131 138
132bad: 139bad:
133 return -ERANGE; 140 ret = -ERANGE;
141 goto out;
134} 142}
135 143
136static int ceph_build_auth_request(struct ceph_auth_client *ac, 144static int ceph_build_auth_request(struct ceph_auth_client *ac,
@@ -151,11 +159,13 @@ static int ceph_build_auth_request(struct ceph_auth_client *ac,
151 if (ret < 0) { 159 if (ret < 0) {
152 pr_err("error %d building auth method %s request\n", ret, 160 pr_err("error %d building auth method %s request\n", ret,
153 ac->ops->name); 161 ac->ops->name);
154 return ret; 162 goto out;
155 } 163 }
156 dout(" built request %d bytes\n", ret); 164 dout(" built request %d bytes\n", ret);
157 ceph_encode_32(&p, ret); 165 ceph_encode_32(&p, ret);
158 return p + ret - msg_buf; 166 ret = p + ret - msg_buf;
167out:
168 return ret;
159} 169}
160 170
161/* 171/*
@@ -176,6 +186,7 @@ int ceph_handle_auth_reply(struct ceph_auth_client *ac,
176 int result_msg_len; 186 int result_msg_len;
177 int ret = -EINVAL; 187 int ret = -EINVAL;
178 188
189 mutex_lock(&ac->mutex);
179 dout("handle_auth_reply %p %p\n", p, end); 190 dout("handle_auth_reply %p %p\n", p, end);
180 ceph_decode_need(&p, end, sizeof(u32) * 3 + sizeof(u64), bad); 191 ceph_decode_need(&p, end, sizeof(u32) * 3 + sizeof(u64), bad);
181 protocol = ceph_decode_32(&p); 192 protocol = ceph_decode_32(&p);
@@ -227,35 +238,44 @@ int ceph_handle_auth_reply(struct ceph_auth_client *ac,
227 238
228 ret = ac->ops->handle_reply(ac, result, payload, payload_end); 239 ret = ac->ops->handle_reply(ac, result, payload, payload_end);
229 if (ret == -EAGAIN) { 240 if (ret == -EAGAIN) {
230 return ceph_build_auth_request(ac, reply_buf, reply_len); 241 ret = ceph_build_auth_request(ac, reply_buf, reply_len);
231 } else if (ret) { 242 } else if (ret) {
232 pr_err("auth method '%s' error %d\n", ac->ops->name, ret); 243 pr_err("auth method '%s' error %d\n", ac->ops->name, ret);
233 return ret;
234 } 244 }
235 return 0;
236 245
237bad:
238 pr_err("failed to decode auth msg\n");
239out: 246out:
247 mutex_unlock(&ac->mutex);
240 return ret; 248 return ret;
249
250bad:
251 pr_err("failed to decode auth msg\n");
252 ret = -EINVAL;
253 goto out;
241} 254}
242 255
243int ceph_build_auth(struct ceph_auth_client *ac, 256int ceph_build_auth(struct ceph_auth_client *ac,
244 void *msg_buf, size_t msg_len) 257 void *msg_buf, size_t msg_len)
245{ 258{
259 int ret = 0;
260
261 mutex_lock(&ac->mutex);
246 if (!ac->protocol) 262 if (!ac->protocol)
247 return ceph_auth_build_hello(ac, msg_buf, msg_len); 263 ret = ceph_auth_build_hello(ac, msg_buf, msg_len);
248 BUG_ON(!ac->ops); 264 else if (ac->ops->should_authenticate(ac))
249 if (ac->ops->should_authenticate(ac)) 265 ret = ceph_build_auth_request(ac, msg_buf, msg_len);
250 return ceph_build_auth_request(ac, msg_buf, msg_len); 266 mutex_unlock(&ac->mutex);
251 return 0; 267 return ret;
252} 268}
253 269
254int ceph_auth_is_authenticated(struct ceph_auth_client *ac) 270int ceph_auth_is_authenticated(struct ceph_auth_client *ac)
255{ 271{
256 if (!ac->ops) 272 int ret = 0;
257 return 0; 273
258 return ac->ops->is_authenticated(ac); 274 mutex_lock(&ac->mutex);
275 if (ac->ops)
276 ret = ac->ops->is_authenticated(ac);
277 mutex_unlock(&ac->mutex);
278 return ret;
259} 279}
260EXPORT_SYMBOL(ceph_auth_is_authenticated); 280EXPORT_SYMBOL(ceph_auth_is_authenticated);
261 281
@@ -263,17 +283,23 @@ int ceph_auth_create_authorizer(struct ceph_auth_client *ac,
263 int peer_type, 283 int peer_type,
264 struct ceph_auth_handshake *auth) 284 struct ceph_auth_handshake *auth)
265{ 285{
286 int ret = 0;
287
288 mutex_lock(&ac->mutex);
266 if (ac->ops && ac->ops->create_authorizer) 289 if (ac->ops && ac->ops->create_authorizer)
267 return ac->ops->create_authorizer(ac, peer_type, auth); 290 ret = ac->ops->create_authorizer(ac, peer_type, auth);
268 return 0; 291 mutex_unlock(&ac->mutex);
292 return ret;
269} 293}
270EXPORT_SYMBOL(ceph_auth_create_authorizer); 294EXPORT_SYMBOL(ceph_auth_create_authorizer);
271 295
272void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac, 296void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac,
273 struct ceph_authorizer *a) 297 struct ceph_authorizer *a)
274{ 298{
299 mutex_lock(&ac->mutex);
275 if (ac->ops && ac->ops->destroy_authorizer) 300 if (ac->ops && ac->ops->destroy_authorizer)
276 ac->ops->destroy_authorizer(ac, a); 301 ac->ops->destroy_authorizer(ac, a);
302 mutex_unlock(&ac->mutex);
277} 303}
278EXPORT_SYMBOL(ceph_auth_destroy_authorizer); 304EXPORT_SYMBOL(ceph_auth_destroy_authorizer);
279 305
@@ -283,8 +309,10 @@ int ceph_auth_update_authorizer(struct ceph_auth_client *ac,
283{ 309{
284 int ret = 0; 310 int ret = 0;
285 311
312 mutex_lock(&ac->mutex);
286 if (ac->ops && ac->ops->update_authorizer) 313 if (ac->ops && ac->ops->update_authorizer)
287 ret = ac->ops->update_authorizer(ac, peer_type, a); 314 ret = ac->ops->update_authorizer(ac, peer_type, a);
315 mutex_unlock(&ac->mutex);
288 return ret; 316 return ret;
289} 317}
290EXPORT_SYMBOL(ceph_auth_update_authorizer); 318EXPORT_SYMBOL(ceph_auth_update_authorizer);
@@ -292,15 +320,21 @@ EXPORT_SYMBOL(ceph_auth_update_authorizer);
292int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac, 320int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,
293 struct ceph_authorizer *a, size_t len) 321 struct ceph_authorizer *a, size_t len)
294{ 322{
323 int ret = 0;
324
325 mutex_lock(&ac->mutex);
295 if (ac->ops && ac->ops->verify_authorizer_reply) 326 if (ac->ops && ac->ops->verify_authorizer_reply)
296 return ac->ops->verify_authorizer_reply(ac, a, len); 327 ret = ac->ops->verify_authorizer_reply(ac, a, len);
297 return 0; 328 mutex_unlock(&ac->mutex);
329 return ret;
298} 330}
299EXPORT_SYMBOL(ceph_auth_verify_authorizer_reply); 331EXPORT_SYMBOL(ceph_auth_verify_authorizer_reply);
300 332
301void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, int peer_type) 333void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, int peer_type)
302{ 334{
335 mutex_lock(&ac->mutex);
303 if (ac->ops && ac->ops->invalidate_authorizer) 336 if (ac->ops && ac->ops->invalidate_authorizer)
304 ac->ops->invalidate_authorizer(ac, peer_type); 337 ac->ops->invalidate_authorizer(ac, peer_type);
338 mutex_unlock(&ac->mutex);
305} 339}
306EXPORT_SYMBOL(ceph_auth_invalidate_authorizer); 340EXPORT_SYMBOL(ceph_auth_invalidate_authorizer);