-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix use after free bug in fuse release/releasedir #4490
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: devel
Are you sure you want to change the base?
Conversation
Problem: fuse_fd_ctx_destroy() is being called in fuse_release()/fuse_releasedir() even before all the refs on the fd are released. This can lead to race situations where the fd_ctx is accessed after freeing. Fix: Make fuse_release()/fuse_releasedir() do the unrefs and let the final unref call xlator's release()/releasedir() like they are supposed to. Fixes: gluster#3945 Change-Id: If01acae815dd7a2b99eb012fff17ce2d044aa9dc Signed-off-by: Pranith Kumar Karampuri <[email protected]>
CLANG-FORMAT FAILURE: index 027dedca3..a740130a2 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -6340,7 +6340,8 @@ fuse_priv_dump(xlator_t *this)
if (!this)
return -1;
- private = this->private;
+ private
+ = this->private;
if (!private)
return -1;
@@ -6494,7 +6495,8 @@ notify(xlator_t *this, int32_t event, void *data, ...)
glusterfs_graph_t *graph = NULL;
struct pollfd pfd = {0};
- private = this->private;
+ private
+ = this->private;
graph = data;
@@ -6516,7 +6518,8 @@ notify(xlator_t *this, int32_t event, void *data, ...)
(event == GF_EVENT_CHILD_DOWN)) {
pthread_mutex_lock(&private->sync_mutex);
{
- private->event_recvd = 1;
+ private
+ ->event_recvd = 1;
pthread_cond_broadcast(&private->sync_cond);
}
pthread_mutex_unlock(&private->sync_mutex);
@@ -6525,16 +6528,18 @@ notify(xlator_t *this, int32_t event, void *data, ...)
pthread_mutex_lock(&private->sync_mutex);
{
if (!private->fuse_thread_started) {
- private->fuse_thread_started = 1;
+ private
+ ->fuse_thread_started = 1;
start_thread = _gf_true;
}
}
pthread_mutex_unlock(&private->sync_mutex);
if (start_thread) {
- private->fuse_thread = GF_CALLOC(private->reader_thread_count,
- sizeof(pthread_t),
- gf_fuse_mt_pthread_t);
+ private
+ ->fuse_thread = GF_CALLOC(private->reader_thread_count,
+ sizeof(pthread_t),
+ gf_fuse_mt_pthread_t);
for (i = 0; i < private->reader_thread_count; i++) {
ret = gf_thread_create(&private->fuse_thread[i], NULL,
fuse_thread_proc, this, "fuseproc");
@@ -6568,7 +6573,8 @@ notify(xlator_t *this, int32_t event, void *data, ...)
if (fuse_get_mount_status(this) != 0) {
goto auth_fail_unlock;
}
- private->mount_finished = _gf_true;
+ private
+ ->mount_finished = _gf_true;
} else if (pfd.revents) {
gf_log(this->name, GF_LOG_ERROR,
"mount pipe closed without status"); |
Is the clang formatting correct? I am running regression runs. Will update with the result |
@@ -3452,13 +3452,8 @@ fuse_release(xlator_t *this, fuse_in_header_t *finh, void *msg, | |||
|
|||
fd_close(state->fd); | |||
|
|||
fuse_fd_ctx_destroy(this, state->fd); | |||
fd_unref(fd); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we really delete the unrefing of the fd. I guess we have a ref on the fd hold by fuse that should be unrefed in fuse_release.
@@ -3904,13 +3899,8 @@ fuse_releasedir(xlator_t *this, fuse_in_header_t *finh, void *msg, | |||
gf_log("glusterfs-fuse", GF_LOG_TRACE, | |||
"finh->unique: %" PRIu64 ": RELEASEDIR %p", finh->unique, state->fd); | |||
|
|||
fuse_fd_ctx_destroy(this, state->fd); | |||
fd_unref(state->fd); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
Problem:
fuse_fd_ctx_destroy() is being called in
fuse_release()/fuse_releasedir() even before all the refs on the fd are released. This can lead to race situations where the fd_ctx is accessed after freeing.
Fix:
Make fuse_release()/fuse_releasedir() do the unrefs and let the final unref call xlator's release()/releasedir() like they are supposed to.
Fixes: #3945
Change-Id: If01acae815dd7a2b99eb012fff17ce2d044aa9dc