Commit 606035e76e79b14bf7a7c219140c045a952cc76e
1 parent
3711d86a2d
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
autofs4: close the races around autofs4_notify_daemon()
Don't drop ->wq_mutex before calling autofs4_notify_daemon() only to regain it there. Besides being pointless, that opens a race window where autofs4_wait_release() could've come and freed wq->name.name. And do the debugging printk in the "reused an existing wq" case before dropping ->wq_mutex - the same reason... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Acked-by: Ian Kent <raven@themaw.net>
Showing 1 changed file with 3 additions and 10 deletions Side-by-side Diff
fs/autofs4/waitq.c
... | ... | @@ -109,13 +109,7 @@ |
109 | 109 | |
110 | 110 | pkt.hdr.proto_version = sbi->version; |
111 | 111 | pkt.hdr.type = type; |
112 | - mutex_lock(&sbi->wq_mutex); | |
113 | 112 | |
114 | - /* Check if we have become catatonic */ | |
115 | - if (sbi->catatonic) { | |
116 | - mutex_unlock(&sbi->wq_mutex); | |
117 | - return; | |
118 | - } | |
119 | 113 | switch (type) { |
120 | 114 | /* Kernel protocol v4 missing and expire packets */ |
121 | 115 | case autofs_ptype_missing: |
... | ... | @@ -427,7 +421,6 @@ |
427 | 421 | wq->tgid = current->tgid; |
428 | 422 | wq->status = -EINTR; /* Status return if interrupted */ |
429 | 423 | wq->wait_ctr = 2; |
430 | - mutex_unlock(&sbi->wq_mutex); | |
431 | 424 | |
432 | 425 | if (sbi->version < 5) { |
433 | 426 | if (notify == NFY_MOUNT) |
434 | 427 | |
435 | 428 | |
... | ... | @@ -449,15 +442,15 @@ |
449 | 442 | (unsigned long) wq->wait_queue_token, wq->name.len, |
450 | 443 | wq->name.name, notify); |
451 | 444 | |
452 | - /* autofs4_notify_daemon() may block */ | |
445 | + /* autofs4_notify_daemon() may block; it will unlock ->wq_mutex */ | |
453 | 446 | autofs4_notify_daemon(sbi, wq, type); |
454 | 447 | } else { |
455 | 448 | wq->wait_ctr++; |
456 | - mutex_unlock(&sbi->wq_mutex); | |
457 | - kfree(qstr.name); | |
458 | 449 | DPRINTK("existing wait id = 0x%08lx, name = %.*s, nfy=%d", |
459 | 450 | (unsigned long) wq->wait_queue_token, wq->name.len, |
460 | 451 | wq->name.name, notify); |
452 | + mutex_unlock(&sbi->wq_mutex); | |
453 | + kfree(qstr.name); | |
461 | 454 | } |
462 | 455 | |
463 | 456 | /* |