diff options
author | Kinglong Mee <kinglongmee@gmail.com> | 2018-10-18 17:46:26 +0800 |
---|---|---|
committer | N Balachandran <nbalacha@redhat.com> | 2018-11-05 04:24:19 +0000 |
commit | 029a7e5c1908f53cc4411a8d6cbf6a4e2b207879 (patch) | |
tree | 194d797737107f6615f3619629d05c6ed42f7901 /xlators/cluster/dht | |
parent | aad1e56286c35237decb106434596fb7f081ee53 (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.c | 19 |
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; } |