summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/dht
diff options
context:
space:
mode:
authorKinglong Mee <kinglongmee@gmail.com>2018-10-18 17:46:26 +0800
committerN Balachandran <nbalacha@redhat.com>2018-11-05 04:24:19 +0000
commit029a7e5c1908f53cc4411a8d6cbf6a4e2b207879 (patch)
tree194d797737107f6615f3619629d05c6ed42f7901 /xlators/cluster/dht
parentaad1e56286c35237decb106434596fb7f081ee53 (diff)
dht: fix use after free in dht_rmdir_readdirp_cbk
The frame is freed when linkfile exist in dht_rmdir_is_subvol_empty(), the following message use the freed local. Change-Id: I41191e8bd477f031a2444d5f15e578dc4f086e6b Updates: bz#1640489 Signed-off-by: Kinglong Mee <mijinlong@open-fs.com>
Diffstat (limited to 'xlators/cluster/dht')
-rw-r--r--xlators/cluster/dht/src/dht-common.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
index 808b4ceb6e5..6947d21a1ec 100644
--- a/xlators/cluster/dht/src/dht-common.c
+++ b/xlators/cluster/dht/src/dht-common.c
@@ -10066,12 +10066,18 @@ dht_rmdir_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
xlator_t *prev = NULL;
xlator_t *src = NULL;
int ret = 0;
+ char *path = NULL;
local = frame->local;
prev = cookie;
src = prev;
if (op_ret > 2) {
+ /* dht_rmdir_is_subvol_empty() may free the frame,
+ * copy path for logging.
+ */
+ path = gf_strdup(local->loc.path);
+
ret = dht_rmdir_is_subvol_empty(frame, this, entries, src);
switch (ret) {
@@ -10082,25 +10088,22 @@ dht_rmdir_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
prev->name, local->loc.path, op_ret);
local->op_ret = -1;
local->op_errno = ENOTEMPTY;
- goto done;
+ break;
default:
/* @ret number of linkfiles are getting unlinked */
gf_msg_trace(this->name, 0,
"readdir on %s for %s found %d "
"linkfiles",
- prev->name, local->loc.path, ret);
+ prev->name, path, ret);
break;
}
}
- if (ret) {
- return 0;
- }
-
-done:
/* readdirp failed or no linkto files were found on this subvol */
+ if (!ret)
+ dht_rmdir_readdirp_done(frame, this);
- dht_rmdir_readdirp_done(frame, this);
+ GF_FREE(path);
return 0;
}