summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorJeff Darcy <jdarcy@redhat.com>2015-06-01 15:21:00 -0400
committerVijay Bellur <vbellur@redhat.com>2015-06-10 05:38:29 -0700
commitd4f9640a08c10beb4cedfefba0a91528b47867e7 (patch)
tree6b0ecac771d88df6b9634af083d2a0244e598bcb /xlators
parent922f9df5d7cdb7775dfa6fac4874105d5cc85c98 (diff)
stripe: fix use-after-free
Pretty much a classic case. STRIPE_STACK_UNWIND frees the "local" structure. In the "virtual xattr" path, used for lock recovery among other things, we were calling STRIPE_STACK_UNWIND and then continuing to clean up "our" parts of the just-freed structure. Oops. Change-Id: Ifa961b89cd21a2893de39a9eea243d184f9eac46 BUG: 1228510 Signed-off-by: Jeff Darcy <jdarcy@redhat.com> Reviewed-on: http://review.gluster.org/11037 Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Tested-by: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Niels de Vos <ndevos@redhat.com> (cherry picked from commit 62992ac27d729ecc7da500ce42dc46592c13d003) Reviewed-on: http://review.gluster.org/11145 Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'xlators')
-rw-r--r--xlators/cluster/stripe/src/stripe.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c
index 7ac131b2ca9..db363910b56 100644
--- a/xlators/cluster/stripe/src/stripe.c
+++ b/xlators/cluster/stripe/src/stripe.c
@@ -5440,12 +5440,18 @@ stripe_vgetxattr_cbk (call_frame_t *frame, void *cookie,
}
unwind:
- STRIPE_STACK_UNWIND (getxattr, frame, op_ret, op_errno,
- stripe_xattr, NULL);
-
+ /*
+ * Among other things, STRIPE_STACK_UNWIND will free "local"
+ * for us. That means we can't dereference it afterward.
+ * Fortunately, the actual result is in stripe_xattr now, so we
+ * can simply clean up before unwinding.
+ */
ret = stripe_free_xattr_str (local);
-
GF_FREE (local->xattr_list);
+ local->xattr_list = NULL;
+
+ STRIPE_STACK_UNWIND (getxattr, frame, op_ret, op_errno,
+ stripe_xattr, NULL);
if (stripe_xattr)
dict_unref (stripe_xattr);