Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

Sage Weil e9966076 27859f97

+58 -22
+2
include/linux/ceph/auth.h
··· 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,
+56 -22
net/ceph/auth.c
··· 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; ··· 74 73 */ 75 74 void ceph_auth_reset(struct ceph_auth_client *ac) 76 75 { 76 + mutex_lock(&ac->mutex); 77 77 dout("auth_reset %p\n", ac); 78 78 if (ac->ops && !ac->negotiating) 79 79 ac->ops->reset(ac); 80 80 ac->negotiating = true; 81 + mutex_unlock(&ac->mutex); 81 82 } 82 83 83 84 int ceph_entity_name_encode(const char *name, void **p, void *end) ··· 105 102 int i, num; 106 103 int ret; 107 104 105 + mutex_lock(&ac->mutex); 108 106 dout("auth_build_hello\n"); 109 107 monhdr->have_version = 0; 110 108 monhdr->session_mon = cpu_to_le16(-1); ··· 126 122 127 123 ret = ceph_entity_name_encode(ac->name, &p, end); 128 124 if (ret < 0) 129 - return ret; 125 + goto out; 130 126 ceph_decode_need(&p, end, sizeof(u64), bad); 131 127 ceph_encode_64(&p, ac->global_id); 132 128 133 129 ceph_encode_32(&lenp, p - lenp - sizeof(u32)); 134 - return p - buf; 130 + ret = p - buf; 131 + out: 132 + mutex_unlock(&ac->mutex); 133 + return ret; 135 134 136 135 bad: 137 - return -ERANGE; 136 + ret = -ERANGE; 137 + goto out; 138 138 } 139 139 140 140 static int ceph_build_auth_request(struct ceph_auth_client *ac, ··· 159 151 if (ret < 0) { 160 152 pr_err("error %d building auth method %s request\n", ret, 161 153 ac->ops->name); 162 - return ret; 154 + goto out; 163 155 } 164 156 dout(" built request %d bytes\n", ret); 165 157 ceph_encode_32(&p, ret); 166 - return p + ret - msg_buf; 158 + ret = p + ret - msg_buf; 159 + out: 160 + return ret; 167 161 } 168 162 169 163 /* ··· 186 176 int result_msg_len; 187 177 int ret = -EINVAL; 188 178 179 + mutex_lock(&ac->mutex); 189 180 dout("handle_auth_reply %p %p\n", p, end); 190 181 ceph_decode_need(&p, end, sizeof(u32) * 3 + sizeof(u64), bad); 191 182 protocol = ceph_decode_32(&p); ··· 238 227 239 228 ret = ac->ops->handle_reply(ac, result, payload, payload_end); 240 229 if (ret == -EAGAIN) { 241 - return ceph_build_auth_request(ac, reply_buf, reply_len); 230 + ret = ceph_build_auth_request(ac, reply_buf, reply_len); 242 231 } else if (ret) { 243 232 pr_err("auth method '%s' error %d\n", ac->ops->name, ret); 244 - return ret; 245 233 } 246 - return 0; 234 + 235 + out: 236 + mutex_unlock(&ac->mutex); 237 + return ret; 247 238 248 239 bad: 249 240 pr_err("failed to decode auth msg\n"); 250 - out: 251 - return ret; 241 + ret = -EINVAL; 242 + goto out; 252 243 } 253 244 254 245 int ceph_build_auth(struct ceph_auth_client *ac, 255 246 void *msg_buf, size_t msg_len) 256 247 { 248 + int ret = 0; 249 + 250 + mutex_lock(&ac->mutex); 257 251 if (!ac->protocol) 258 - return ceph_auth_build_hello(ac, msg_buf, msg_len); 259 - BUG_ON(!ac->ops); 260 - if (ac->ops->should_authenticate(ac)) 261 - return ceph_build_auth_request(ac, msg_buf, msg_len); 262 - return 0; 252 + ret = ceph_auth_build_hello(ac, msg_buf, msg_len); 253 + else if (ac->ops->should_authenticate(ac)) 254 + ret = ceph_build_auth_request(ac, msg_buf, msg_len); 255 + mutex_unlock(&ac->mutex); 256 + return ret; 263 257 } 264 258 265 259 int ceph_auth_is_authenticated(struct ceph_auth_client *ac) 266 260 { 267 - if (!ac->ops) 268 - return 0; 269 - return ac->ops->is_authenticated(ac); 261 + int ret = 0; 262 + 263 + mutex_lock(&ac->mutex); 264 + if (ac->ops) 265 + ret = ac->ops->is_authenticated(ac); 266 + mutex_unlock(&ac->mutex); 267 + return ret; 270 268 } 271 269 EXPORT_SYMBOL(ceph_auth_is_authenticated); 272 270 ··· 283 263 int peer_type, 284 264 struct ceph_auth_handshake *auth) 285 265 { 266 + int ret = 0; 267 + 268 + mutex_lock(&ac->mutex); 286 269 if (ac->ops && ac->ops->create_authorizer) 287 - return ac->ops->create_authorizer(ac, peer_type, auth); 288 - return 0; 270 + ret = ac->ops->create_authorizer(ac, peer_type, auth); 271 + mutex_unlock(&ac->mutex); 272 + return ret; 289 273 } 290 274 EXPORT_SYMBOL(ceph_auth_create_authorizer); 291 275 292 276 void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac, 293 277 struct ceph_authorizer *a) 294 278 { 279 + mutex_lock(&ac->mutex); 295 280 if (ac->ops && ac->ops->destroy_authorizer) 296 281 ac->ops->destroy_authorizer(ac, a); 282 + mutex_unlock(&ac->mutex); 297 283 } 298 284 EXPORT_SYMBOL(ceph_auth_destroy_authorizer); 299 285 ··· 309 283 { 310 284 int ret = 0; 311 285 286 + mutex_lock(&ac->mutex); 312 287 if (ac->ops && ac->ops->update_authorizer) 313 288 ret = ac->ops->update_authorizer(ac, peer_type, a); 289 + mutex_unlock(&ac->mutex); 314 290 return ret; 315 291 } 316 292 EXPORT_SYMBOL(ceph_auth_update_authorizer); ··· 320 292 int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac, 321 293 struct ceph_authorizer *a, size_t len) 322 294 { 295 + int ret = 0; 296 + 297 + mutex_lock(&ac->mutex); 323 298 if (ac->ops && ac->ops->verify_authorizer_reply) 324 - return ac->ops->verify_authorizer_reply(ac, a, len); 325 - return 0; 299 + ret = ac->ops->verify_authorizer_reply(ac, a, len); 300 + mutex_unlock(&ac->mutex); 301 + return ret; 326 302 } 327 303 EXPORT_SYMBOL(ceph_auth_verify_authorizer_reply); 328 304 329 305 void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, int peer_type) 330 306 { 307 + mutex_lock(&ac->mutex); 331 308 if (ac->ops && ac->ops->invalidate_authorizer) 332 309 ac->ops->invalidate_authorizer(ac, peer_type); 310 + mutex_unlock(&ac->mutex); 333 311 } 334 312 EXPORT_SYMBOL(ceph_auth_invalidate_authorizer);