diff options
author | Krutika Dhananjay <kdhananj@redhat.com> | 2016-10-17 15:13:28 +0530 |
---|---|---|
committer | Atin Mukherjee <amukherj@redhat.com> | 2016-10-24 07:11:08 -0700 |
commit | 41dc5ee07ffba6d17459757abf13fae9f174e6b6 (patch) | |
tree | 0cc0f68eb02c63300b2e1838ee39152af253ebe5 /xlators/protocol/server/src | |
parent | f31b3213e2a97259faa7dcae2354d2535732068b (diff) |
compound fops: Fix file corruption issue
1. Address of a local variable @args is copied into state->req
in server3_3_compound (). But even after the function has gone out of
scope, in server_compound_resume () this pointer is accessed and
dereferenced. This patch fixes that.
2. Compound fops, by virtue of NOT having a vector sizer (like the one
writev has), ends up having both the header and the data (in case one of
its member fops is WRITEV) in the same hdr_iobuf. This buffer was not
being preserved through the lifetime of the compound fop, causing it to
be overwritten by a parallel write fop, even when the writev associated
with the currently executing compound fop is yet to hit the desk, thereby
corrupting the file's data. This is fixed by associating the hdr_iobuf with
the iobref so its memory remains valid through the lifetime of the fop.
3. Also fixed a use-after-free bug in protocol/client in compound fops cbk,
missed by Linux but caught by NetBSD.
Finally, big thanks to Pranith Kumar K and Raghavendra Gowdappa for their
help in debugging this file corruption issue.
Change-Id: I6d5c04f400ecb687c9403a17a12683a96c2bf122
BUG: 1378778
Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com>
Reviewed-on: http://review.gluster.org/15654
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
Smoke: Gluster Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
Diffstat (limited to 'xlators/protocol/server/src')
-rw-r--r-- | xlators/protocol/server/src/server-rpc-fops.c | 4 | ||||
-rw-r--r-- | xlators/protocol/server/src/server.h | 2 |
2 files changed, 3 insertions, 3 deletions
diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c index 43061b03c56..25f575d3c6a 100644 --- a/xlators/protocol/server/src/server-rpc-fops.c +++ b/xlators/protocol/server/src/server-rpc-fops.c @@ -3324,7 +3324,7 @@ server_compound_resume (call_frame_t *frame, xlator_t *bound_xl) goto err; } - req = state->req; + req = &state->req; length = req->compound_req_array.compound_req_array_len; state->args = compound_fop_alloc (length, req->compound_fop_enum, @@ -6725,7 +6725,7 @@ server3_3_compound (rpcsvc_request_t *req) goto out; } - state->req = &args; + state->req = args; state->iobref = iobref_ref (req->iobref); if (len < req->msg[0].iov_len) { diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h index c87dbe67b12..0b37eb1414a 100644 --- a/xlators/protocol/server/src/server.h +++ b/xlators/protocol/server/src/server.h @@ -191,7 +191,7 @@ struct _server_state { struct gf_lease lease; lock_migration_info_t locklist; /* required for compound fops */ - gfs3_compound_req *req; + gfs3_compound_req req; /* last length till which iovec for compound * writes was processed */ int write_length; |