summaryrefslogtreecommitdiffstats
path: root/xlators/mount/fuse/src
diff options
context:
space:
mode:
authorXavier Hernandez <xhernandez@datalab.es>2017-01-12 08:38:50 +0100
committerNiels de Vos <ndevos@redhat.com>2017-03-10 17:28:06 -0500
commitb0f1fce00f2b3c86077c88dff85ff99f3263b60b (patch)
tree0eb3d40ad6d8ecfc4fe6859407628ad15ddf7d2f /xlators/mount/fuse/src
parenta76304cd434028215de39cf3b45672cc7ec6ca70 (diff)
fuse: fix memory leak in setxattr
If there's some failed check in setxattr of mount/fuse before actually starting the operation, a fuse_state_t structure is leaked. This fix correctly releases allocated resources in case of error. > Change-Id: I8b1cda67a613c13b6bc38947352e2ccfccf96a1d > BUG: 1412174 > Signed-off-by: Xavier Hernandez <xhernandez@datalab.es> > Reviewed-on: http://review.gluster.org/16380 > Smoke: Gluster Build System <jenkins@build.gluster.org> > NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> > Reviewed-by: Niels de Vos <ndevos@redhat.com> > CentOS-regression: Gluster Build System <jenkins@build.gluster.org> > Reviewed-by: Jeff Darcy <jdarcy@redhat.com> Change-Id: I7e838f8284aa2aca2e43067a4b002e8530ad928d BUG: 1412994 Signed-off-by: Xavier Hernandez <xhernandez@datalab.es> Reviewed-on: https://review.gluster.org/16403 Smoke: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Raghavendra G <rgowdapp@redhat.com> Reviewed-by: Niels de Vos <ndevos@redhat.com>
Diffstat (limited to 'xlators/mount/fuse/src')
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c48
1 files changed, 21 insertions, 27 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index 525a6a6fbbc..0e1ba0b4dba 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -3213,6 +3213,7 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
fuse_state_t *state = NULL;
char *dict_value = NULL;
int32_t ret = -1;
+ int32_t op_errno = 0;
char *newkey = NULL;
priv = this->private;
@@ -3225,57 +3226,49 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
"%"PRIu64": SETXATTR %s/%"PRIu64" (%s):"
"refusing positioned setxattr",
finh->unique, state->loc.path, finh->nodeid, name);
- send_fuse_err (this, finh, EINVAL);
- FREE (finh);
- return;
+ op_errno = EINVAL;
+ goto done;
}
#endif
if (fuse_ignore_xattr_set (priv, name)) {
- (void) send_fuse_err (this, finh, 0);
- return;
+ goto done;
}
if (!priv->acl) {
if ((strcmp (name, POSIX_ACL_ACCESS_XATTR) == 0) ||
(strcmp (name, POSIX_ACL_DEFAULT_XATTR) == 0)) {
- send_fuse_err (this, finh, EOPNOTSUPP);
- GF_FREE (finh);
- return;
+ op_errno = EOPNOTSUPP;
+ goto done;
}
}
ret = fuse_check_selinux_cap_xattr (priv, name);
if (ret) {
- send_fuse_err (this, finh, EOPNOTSUPP);
- GF_FREE (finh);
- return;
+ op_errno = EOPNOTSUPP;
+ goto done;
}
/* Check if the command is for changing the log
level of process or specific xlator */
ret = is_gf_log_command (this, name, value);
if (ret >= 0) {
- send_fuse_err (this, finh, ret);
- GF_FREE (finh);
- return;
+ op_errno = ret;
+ goto done;
}
if (!strcmp ("inode-invalidate", name)) {
gf_log ("fuse", GF_LOG_TRACE,
"got request to invalidate %"PRIu64, finh->nodeid);
- send_fuse_err (this, finh, 0);
#if FUSE_KERNEL_MINOR_VERSION >= 11
fuse_invalidate_entry (this, finh->nodeid);
#endif
- GF_FREE (finh);
- return;
+ goto done;
}
if (!strcmp (GFID_XATTR_KEY, name) || !strcmp (GF_XATTR_VOL_ID_KEY, name)) {
- send_fuse_err (this, finh, EPERM);
- GF_FREE (finh);
- return;
+ op_errno = EPERM;
+ goto done;
}
state->size = fsi->size;
@@ -3287,17 +3280,14 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
"%"PRIu64": SETXATTR dict allocation failed",
finh->unique);
-
- send_fuse_err (this, finh, ENOMEM);
- free_fuse_state (state);
- return;
+ op_errno = ENOMEM;
+ goto done;
}
ret = fuse_flip_xattr_ns (priv, name, &newkey);
if (ret) {
- send_fuse_err (this, finh, ENOMEM);
- free_fuse_state (state);
- return;
+ op_errno = ENOMEM;
+ goto done;
}
if (fsi->size > 0) {
@@ -3320,6 +3310,10 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
fuse_resolve_and_resume (state, fuse_setxattr_resume);
return;
+
+done:
+ send_fuse_err(this, finh, op_errno);
+ free_fuse_state(state);
}