Blob Blame History Raw
From 870513f9bade449fa760a81e242102860a0fdc91 Mon Sep 17 00:00:00 2001
From: N Balachandran <nbalacha@redhat.com>
Date: Thu, 13 Dec 2018 10:54:15 +0530
Subject: [PATCH 470/493] 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.

upstream patch: https://review.gluster.org/#/c/glusterfs/+/21446/

> Change-Id: I41191e8bd477f031a2444d5f15e578dc4f086e6b
> Updates: bz#1640489
> Signed-off-by: Kinglong Mee <mijinlong@open-fs.com>

Change-Id: Ia257e1da57cc486ab336e43f8e88187e984c70e2
BUG: 1654103
Author: Kinglong Mee <mijinlong@open-fs.com>
Signed-off-by: N Balachandran <nbalacha@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/158486
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
---
 xlators/cluster/dht/src/dht-common.c | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
index 2e19036..ff0099c 100644
--- a/xlators/cluster/dht/src/dht-common.c
+++ b/xlators/cluster/dht/src/dht-common.c
@@ -10175,6 +10175,7 @@ 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;
@@ -10182,6 +10183,11 @@ dht_rmdir_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
         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) {
@@ -10192,27 +10198,24 @@ dht_rmdir_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
                                       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);
+                                      "linkfiles",
+                                      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);
+        }
+        GF_FREE(path);
 
-        dht_rmdir_readdirp_done (frame, this);
         return 0;
 }
 
-- 
1.8.3.1