summaryrefslogtreecommitdiff
path: root/fs/afs/cmservice.c
diff options
context:
space:
mode:
authorMarc Dionne <marc.dionne@auristor.com>2017-03-16 16:27:44 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-12-20 10:07:24 +0100
commiteaaad7646d3de73ca30653e635261827242be124 (patch)
treee70b3cef90c9ffc98888da05877c5ea563e02afc /fs/afs/cmservice.c
parent900048089cc135fea39452ec32aa44415e1c8dba (diff)
afs: Deal with an empty callback array
[ Upstream commit bcd89270d93b7edebb5de5e5e7dca1a77a33496e ] Servers may send a callback array that is the same size as the FID array, or an empty array. If the callback count is 0, the code would attempt to read (fid_count * 12) bytes of data, which would fail and result in an unmarshalling error. This would lead to stale data for remotely modified files or directories. Store the callback array size in the internal afs_call structure and use that to determine the amount of data to read. Signed-off-by: Marc Dionne <marc.dionne@auristor.com> Signed-off-by: Sasha Levin <alexander.levin@verizon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/afs/cmservice.c')
-rw-r--r--fs/afs/cmservice.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c
index 8d2c5180e015..168f2a4d1180 100644
--- a/fs/afs/cmservice.c
+++ b/fs/afs/cmservice.c
@@ -168,7 +168,6 @@ static int afs_deliver_cb_callback(struct afs_call *call)
struct afs_callback *cb;
struct afs_server *server;
__be32 *bp;
- u32 tmp;
int ret, loop;
_enter("{%u}", call->unmarshall);
@@ -230,9 +229,9 @@ static int afs_deliver_cb_callback(struct afs_call *call)
if (ret < 0)
return ret;
- tmp = ntohl(call->tmp);
- _debug("CB count: %u", tmp);
- if (tmp != call->count && tmp != 0)
+ call->count2 = ntohl(call->tmp);
+ _debug("CB count: %u", call->count2);
+ if (call->count2 != call->count && call->count2 != 0)
return -EBADMSG;
call->offset = 0;
call->unmarshall++;
@@ -240,14 +239,14 @@ static int afs_deliver_cb_callback(struct afs_call *call)
case 4:
_debug("extract CB array");
ret = afs_extract_data(call, call->buffer,
- call->count * 3 * 4, false);
+ call->count2 * 3 * 4, false);
if (ret < 0)
return ret;
_debug("unmarshall CB array");
cb = call->request;
bp = call->buffer;
- for (loop = call->count; loop > 0; loop--, cb++) {
+ for (loop = call->count2; loop > 0; loop--, cb++) {
cb->version = ntohl(*bp++);
cb->expiry = ntohl(*bp++);
cb->type = ntohl(*bp++);