This is a note to let you know that I've just added the patch titled afs: Deal with an empty callback array to the 4.9-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: afs-deal-with-an-empty-callback-array.patch and it can be found in the queue-4.9 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From foo@baz Mon Dec 18 14:12:34 CET 2017 From: Marc Dionne <marc.dionne@xxxxxxxxxxxx> Date: Thu, 16 Mar 2017 16:27:44 +0000 Subject: afs: Deal with an empty callback array From: Marc Dionne <marc.dionne@xxxxxxxxxxxx> [ 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@xxxxxxxxxxxx> Signed-off-by: Sasha Levin <alexander.levin@xxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- fs/afs/cmservice.c | 11 +++++------ fs/afs/internal.h | 5 ++++- 2 files changed, 9 insertions(+), 7 deletions(-) --- a/fs/afs/cmservice.c +++ b/fs/afs/cmservice.c @@ -168,7 +168,6 @@ static int afs_deliver_cb_callback(struc 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(struc 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(struc 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++); --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -105,7 +105,10 @@ struct afs_call { unsigned request_size; /* size of request data */ unsigned reply_max; /* maximum size of reply */ unsigned first_offset; /* offset into mapping[first] */ - unsigned last_to; /* amount of mapping[last] */ + union { + unsigned last_to; /* amount of mapping[last] */ + unsigned count2; /* count used in unmarshalling */ + }; unsigned char unmarshall; /* unmarshalling phase */ bool incoming; /* T if incoming call */ bool send_pages; /* T if data from mapping should be sent */ Patches currently in stable-queue which might be from marc.dionne@xxxxxxxxxxxx are queue-4.9/afs-populate-group-id-from-vnode-status.patch queue-4.9/afs-adjust-mode-bits-processing.patch queue-4.9/afs-populate-and-use-client-modification-time.patch queue-4.9/afs-deal-with-an-empty-callback-array.patch