Commit e9966076cdd952e19f2dd4854cd719be0d7cbebc
1 parent
27859f9773
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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, |
net/ceph/auth.c
... | ... | @@ -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); |