From cddd253c5e3f0a7c3b91c35cea8ad1921cb43b98 Mon Sep 17 00:00:00 2001 From: Kinglong Mee Date: Thu, 18 Jul 2019 11:43:01 +0800 Subject: [PATCH 454/456] features/locks: avoid use after freed of frame for blocked lock The fop contains blocked lock may use freed frame info when other unlock fop has unwind the blocked lock. Because the blocked lock is added to block list in inode lock(or other lock), after that, when out of the inode lock, the fop contains the blocked lock should not use it. Upstream Patch - https://review.gluster.org/#/c/glusterfs/+/23155/ >Change-Id: Icb309a1cc78380dc982b26d50c18d67e4f2c8915 >fixes: bz#1737291 >Signed-off-by: Kinglong Mee Change-Id: Icb309a1cc78380dc982b26d50c18d67e4f2c8915 BUG: 1812789 Reviewed-on: https://code.engineering.redhat.com/gerrit/206465 Tested-by: RHGS Build Bot Reviewed-by: Xavi Hernandez Juan --- xlators/features/locks/src/common.c | 4 ++++ xlators/features/locks/src/entrylk.c | 4 ++-- xlators/features/locks/src/inodelk.c | 7 +++++-- xlators/features/locks/src/posix.c | 5 +++-- xlators/features/locks/src/reservelk.c | 2 -- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/xlators/features/locks/src/common.c b/xlators/features/locks/src/common.c index 6e7fb4b..1406e70 100644 --- a/xlators/features/locks/src/common.c +++ b/xlators/features/locks/src/common.c @@ -1080,6 +1080,10 @@ pl_setlk(xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock, lock->fl_type == F_UNLCK ? "Unlock" : "Lock", lock->client_pid, lkowner_utoa(&lock->owner), lock->user_flock.l_start, lock->user_flock.l_len); + + pl_trace_block(this, lock->frame, NULL, NULL, F_SETLKW, + &lock->user_flock, NULL); + lock->blocked = 1; __insert_lock(pl_inode, lock); ret = -1; diff --git a/xlators/features/locks/src/entrylk.c b/xlators/features/locks/src/entrylk.c index ced5eca..93c649c 100644 --- a/xlators/features/locks/src/entrylk.c +++ b/xlators/features/locks/src/entrylk.c @@ -552,6 +552,8 @@ __lock_blocked_add(xlator_t *this, pl_inode_t *pinode, pl_dom_list_t *dom, gf_msg_trace(this->name, 0, "Blocking lock: {pinode=%p, basename=%s}", pinode, lock->basename); + entrylk_trace_block(this, lock->frame, NULL, NULL, NULL, lock->basename, + ENTRYLK_LOCK, lock->type); out: return -EAGAIN; } @@ -932,8 +934,6 @@ out: op_ret, op_errno); unwind: STACK_UNWIND_STRICT(entrylk, frame, op_ret, op_errno, NULL); - } else { - entrylk_trace_block(this, frame, volume, fd, loc, basename, cmd, type); } if (pcontend != NULL) { diff --git a/xlators/features/locks/src/inodelk.c b/xlators/features/locks/src/inodelk.c index a9c42f1..24dee49 100644 --- a/xlators/features/locks/src/inodelk.c +++ b/xlators/features/locks/src/inodelk.c @@ -420,6 +420,8 @@ __lock_blocked_add(xlator_t *this, pl_dom_list_t *dom, pl_inode_lock_t *lock, lkowner_utoa(&lock->owner), lock->user_flock.l_start, lock->user_flock.l_len); + pl_trace_block(this, lock->frame, NULL, NULL, F_SETLKW, &lock->user_flock, + lock->volume); out: return -EAGAIN; } @@ -959,6 +961,7 @@ pl_common_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, int ret = -1; GF_UNUSED int dict_ret = -1; int can_block = 0; + short lock_type = 0; pl_inode_t *pinode = NULL; pl_inode_lock_t *reqlock = NULL; pl_dom_list_t *dom = NULL; @@ -1024,13 +1027,13 @@ pl_common_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, /* fall through */ case F_SETLK: + lock_type = flock->l_type; memcpy(&reqlock->user_flock, flock, sizeof(struct gf_flock)); ret = pl_inode_setlk(this, ctx, pinode, reqlock, can_block, dom, inode); if (ret < 0) { - if ((can_block) && (F_UNLCK != flock->l_type)) { - pl_trace_block(this, frame, fd, loc, cmd, flock, volume); + if ((can_block) && (F_UNLCK != lock_type)) { goto out; } gf_log(this->name, GF_LOG_TRACE, "returning EAGAIN"); diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c index 50f1265..7887b82 100644 --- a/xlators/features/locks/src/posix.c +++ b/xlators/features/locks/src/posix.c @@ -2557,6 +2557,7 @@ pl_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, uint32_t lk_flags = 0; posix_locks_private_t *priv = this->private; pl_local_t *local = NULL; + short lock_type = 0; int ret = dict_get_uint32(xdata, GF_LOCK_MODE, &lk_flags); if (ret == 0) { @@ -2701,6 +2702,7 @@ pl_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, case F_SETLK: reqlock->frame = frame; reqlock->this = this; + lock_type = flock->l_type; pthread_mutex_lock(&pl_inode->mutex); { @@ -2738,8 +2740,7 @@ pl_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, ret = pl_setlk(this, pl_inode, reqlock, can_block); if (ret == -1) { - if ((can_block) && (F_UNLCK != flock->l_type)) { - pl_trace_block(this, frame, fd, NULL, cmd, flock, NULL); + if ((can_block) && (F_UNLCK != lock_type)) { goto out; } gf_log(this->name, GF_LOG_DEBUG, "returning EAGAIN"); diff --git a/xlators/features/locks/src/reservelk.c b/xlators/features/locks/src/reservelk.c index 51076d7..604691f 100644 --- a/xlators/features/locks/src/reservelk.c +++ b/xlators/features/locks/src/reservelk.c @@ -312,8 +312,6 @@ grant_blocked_lock_calls(xlator_t *this, pl_inode_t *pl_inode) ret = pl_setlk(this, pl_inode, lock, can_block); if (ret == -1) { if (can_block) { - pl_trace_block(this, lock->frame, fd, NULL, cmd, - &lock->user_flock, NULL); continue; } else { gf_log(this->name, GF_LOG_DEBUG, "returning EAGAIN"); -- 1.8.3.1