diff options
author | Jeff Darcy <jdarcy@redhat.com> | 2015-06-01 15:21:00 -0400 |
---|---|---|
committer | Niels de Vos <ndevos@redhat.com> | 2015-06-02 14:54:59 -0700 |
commit | 62992ac27d729ecc7da500ce42dc46592c13d003 (patch) | |
tree | 56863703ac4f18d467d72ba845ec70199dc6c1be /xlators/cluster | |
parent | 5a66d1e6186acfb15e9957b5f196659da8f3cf6d (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: 1222317
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>
Diffstat (limited to 'xlators/cluster')
-rw-r--r-- | xlators/cluster/stripe/src/stripe.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c index 71d9230f708..dbb76c30b38 100644 --- a/xlators/cluster/stripe/src/stripe.c +++ b/xlators/cluster/stripe/src/stripe.c @@ -5445,12 +5445,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); |