diff options
| author | Jeff Darcy <jdarcy@redhat.com> | 2015-06-01 15:21:00 -0400 | 
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2015-06-10 05:38:29 -0700 | 
| commit | d4f9640a08c10beb4cedfefba0a91528b47867e7 (patch) | |
| tree | 6b0ecac771d88df6b9634af083d2a0244e598bcb | |
| parent | 922f9df5d7cdb7775dfa6fac4874105d5cc85c98 (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>
| -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 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);  | 
