Commit e9966076cdd952e19f2dd4854cd719be0d7cbebc

Authored by Sage Weil
1 parent 27859f9773

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>

Showing 2 changed files with 58 additions and 22 deletions Side-by-side Diff

include/linux/ceph/auth.h
... ... @@ -78,6 +78,8 @@
78 78 u64 global_id; /* our unique id in system */
79 79 const struct ceph_crypto_key *key; /* our secret key */
80 80 unsigned want_keys; /* which services we want */
  81 +
  82 + struct mutex mutex;
81 83 };
82 84  
83 85 extern struct ceph_auth_client *ceph_auth_init(const char *name,
... ... @@ -47,6 +47,7 @@
47 47 if (!ac)
48 48 goto out;
49 49  
  50 + mutex_init(&ac->mutex);
50 51 ac->negotiating = true;
51 52 if (name)
52 53 ac->name = name;
53 54  
... ... @@ -73,10 +74,12 @@
73 74 */
74 75 void ceph_auth_reset(struct ceph_auth_client *ac)
75 76 {
  77 + mutex_lock(&ac->mutex);
76 78 dout("auth_reset %p\n", ac);
77 79 if (ac->ops && !ac->negotiating)
78 80 ac->ops->reset(ac);
79 81 ac->negotiating = true;
  82 + mutex_unlock(&ac->mutex);
80 83 }
81 84  
82 85 int ceph_entity_name_encode(const char *name, void **p, void *end)
... ... @@ -102,6 +105,7 @@
102 105 int i, num;
103 106 int ret;
104 107  
  108 + mutex_lock(&ac->mutex);
105 109 dout("auth_build_hello\n");
106 110 monhdr->have_version = 0;
107 111 monhdr->session_mon = cpu_to_le16(-1);
108 112  
109 113  
... ... @@ -122,15 +126,19 @@
122 126  
123 127 ret = ceph_entity_name_encode(ac->name, &p, end);
124 128 if (ret < 0)
125   - return ret;
  129 + goto out;
126 130 ceph_decode_need(&p, end, sizeof(u64), bad);
127 131 ceph_encode_64(&p, ac->global_id);
128 132  
129 133 ceph_encode_32(&lenp, p - lenp - sizeof(u32));
130   - return p - buf;
  134 + ret = p - buf;
  135 +out:
  136 + mutex_unlock(&ac->mutex);
  137 + return ret;
131 138  
132 139 bad:
133   - return -ERANGE;
  140 + ret = -ERANGE;
  141 + goto out;
134 142 }
135 143  
136 144 static int ceph_build_auth_request(struct ceph_auth_client *ac,
137 145  
... ... @@ -151,11 +159,13 @@
151 159 if (ret < 0) {
152 160 pr_err("error %d building auth method %s request\n", ret,
153 161 ac->ops->name);
154   - return ret;
  162 + goto out;
155 163 }
156 164 dout(" built request %d bytes\n", ret);
157 165 ceph_encode_32(&p, ret);
158   - return p + ret - msg_buf;
  166 + ret = p + ret - msg_buf;
  167 +out:
  168 + return ret;
159 169 }
160 170  
161 171 /*
... ... @@ -176,6 +186,7 @@
176 186 int result_msg_len;
177 187 int ret = -EINVAL;
178 188  
  189 + mutex_lock(&ac->mutex);
179 190 dout("handle_auth_reply %p %p\n", p, end);
180 191 ceph_decode_need(&p, end, sizeof(u32) * 3 + sizeof(u64), bad);
181 192 protocol = ceph_decode_32(&p);
182 193  
183 194  
184 195  
185 196  
186 197  
187 198  
188 199  
189 200  
... ... @@ -227,35 +238,44 @@
227 238  
228 239 ret = ac->ops->handle_reply(ac, result, payload, payload_end);
229 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 242 } else if (ret) {
232 243 pr_err("auth method '%s' error %d\n", ac->ops->name, ret);
233   - return ret;
234 244 }
235   - return 0;
236 245  
237   -bad:
238   - pr_err("failed to decode auth msg\n");
239 246 out:
  247 + mutex_unlock(&ac->mutex);
240 248 return ret;
  249 +
  250 +bad:
  251 + pr_err("failed to decode auth msg\n");
  252 + ret = -EINVAL;
  253 + goto out;
241 254 }
242 255  
243 256 int ceph_build_auth(struct ceph_auth_client *ac,
244 257 void *msg_buf, size_t msg_len)
245 258 {
  259 + int ret = 0;
  260 +
  261 + mutex_lock(&ac->mutex);
246 262 if (!ac->protocol)
247   - return ceph_auth_build_hello(ac, msg_buf, msg_len);
248   - BUG_ON(!ac->ops);
249   - if (ac->ops->should_authenticate(ac))
250   - return ceph_build_auth_request(ac, msg_buf, msg_len);
251   - return 0;
  263 + ret = ceph_auth_build_hello(ac, msg_buf, msg_len);
  264 + else if (ac->ops->should_authenticate(ac))
  265 + ret = ceph_build_auth_request(ac, msg_buf, msg_len);
  266 + mutex_unlock(&ac->mutex);
  267 + return ret;
252 268 }
253 269  
254 270 int ceph_auth_is_authenticated(struct ceph_auth_client *ac)
255 271 {
256   - if (!ac->ops)
257   - return 0;
258   - return ac->ops->is_authenticated(ac);
  272 + int ret = 0;
  273 +
  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 }
260 280 EXPORT_SYMBOL(ceph_auth_is_authenticated);
261 281  
262 282  
263 283  
264 284  
... ... @@ -263,17 +283,23 @@
263 283 int peer_type,
264 284 struct ceph_auth_handshake *auth)
265 285 {
  286 + int ret = 0;
  287 +
  288 + mutex_lock(&ac->mutex);
266 289 if (ac->ops && ac->ops->create_authorizer)
267   - return ac->ops->create_authorizer(ac, peer_type, auth);
268   - return 0;
  290 + ret = ac->ops->create_authorizer(ac, peer_type, auth);
  291 + mutex_unlock(&ac->mutex);
  292 + return ret;
269 293 }
270 294 EXPORT_SYMBOL(ceph_auth_create_authorizer);
271 295  
272 296 void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac,
273 297 struct ceph_authorizer *a)
274 298 {
  299 + mutex_lock(&ac->mutex);
275 300 if (ac->ops && ac->ops->destroy_authorizer)
276 301 ac->ops->destroy_authorizer(ac, a);
  302 + mutex_unlock(&ac->mutex);
277 303 }
278 304 EXPORT_SYMBOL(ceph_auth_destroy_authorizer);
279 305  
280 306  
... ... @@ -283,8 +309,10 @@
283 309 {
284 310 int ret = 0;
285 311  
  312 + mutex_lock(&ac->mutex);
286 313 if (ac->ops && ac->ops->update_authorizer)
287 314 ret = ac->ops->update_authorizer(ac, peer_type, a);
  315 + mutex_unlock(&ac->mutex);
288 316 return ret;
289 317 }
290 318 EXPORT_SYMBOL(ceph_auth_update_authorizer);
291 319  
292 320  
293 321  
... ... @@ -292,16 +320,22 @@
292 320 int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,
293 321 struct ceph_authorizer *a, size_t len)
294 322 {
  323 + int ret = 0;
  324 +
  325 + mutex_lock(&ac->mutex);
295 326 if (ac->ops && ac->ops->verify_authorizer_reply)
296   - return ac->ops->verify_authorizer_reply(ac, a, len);
297   - return 0;
  327 + ret = ac->ops->verify_authorizer_reply(ac, a, len);
  328 + mutex_unlock(&ac->mutex);
  329 + return ret;
298 330 }
299 331 EXPORT_SYMBOL(ceph_auth_verify_authorizer_reply);
300 332  
301 333 void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, int peer_type)
302 334 {
  335 + mutex_lock(&ac->mutex);
303 336 if (ac->ops && ac->ops->invalidate_authorizer)
304 337 ac->ops->invalidate_authorizer(ac, peer_type);
  338 + mutex_unlock(&ac->mutex);
305 339 }
306 340 EXPORT_SYMBOL(ceph_auth_invalidate_authorizer);