This is a note to let you know that I've just added the patch titled NFSv4.1: Fix Oopsable condition in server callback races to the 4.4-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: nfsv4.1-fix-oopsable-condition-in-server-callback-races.patch and it can be found in the queue-4.4 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From e09c978aae5bedfdb379be80363b024b7d82638b Mon Sep 17 00:00:00 2001 From: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> Date: Sat, 27 Aug 2016 23:44:04 -0400 Subject: NFSv4.1: Fix Oopsable condition in server callback races From: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> commit e09c978aae5bedfdb379be80363b024b7d82638b upstream. The slot table hasn't been an array since v3.7. Ensure that we use nfs4_lookup_slot() to access the slot correctly. Fixes: 87dda67e7386 ("NFSv4.1: Allow SEQUENCE to resize the slot table...") Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- fs/nfs/callback_proc.c | 5 +---- fs/nfs/nfs4session.c | 33 +++++++++++++++++++++++++++++++++ fs/nfs/nfs4session.h | 1 + 3 files changed, 35 insertions(+), 4 deletions(-) --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -400,11 +400,8 @@ static bool referring_call_exists(struct ((u32 *)&rclist->rcl_sessionid.data)[3], ref->rc_sequenceid, ref->rc_slotid); - spin_lock(&tbl->slot_tbl_lock); - status = (test_bit(ref->rc_slotid, tbl->used_slots) && - tbl->slots[ref->rc_slotid].seq_nr == + status = nfs4_slot_seqid_in_use(tbl, ref->rc_slotid, ref->rc_sequenceid); - spin_unlock(&tbl->slot_tbl_lock); if (status) goto out; } --- a/fs/nfs/nfs4session.c +++ b/fs/nfs/nfs4session.c @@ -135,6 +135,39 @@ static struct nfs4_slot *nfs4_find_or_cr return ERR_PTR(-ENOMEM); } +static int nfs4_slot_get_seqid(struct nfs4_slot_table *tbl, u32 slotid, + u32 *seq_nr) + __must_hold(&tbl->slot_tbl_lock) +{ + struct nfs4_slot *slot; + + slot = nfs4_lookup_slot(tbl, slotid); + if (IS_ERR(slot)) + return PTR_ERR(slot); + *seq_nr = slot->seq_nr; + return 0; +} + +/* + * nfs4_slot_seqid_in_use - test if a slot sequence id is still in use + * + * Given a slot table, slot id and sequence number, determine if the + * RPC call in question is still in flight. This function is mainly + * intended for use by the callback channel. + */ +bool nfs4_slot_seqid_in_use(struct nfs4_slot_table *tbl, u32 slotid, u32 seq_nr) +{ + u32 cur_seq; + bool ret = false; + + spin_lock(&tbl->slot_tbl_lock); + if (nfs4_slot_get_seqid(tbl, slotid, &cur_seq) == 0 && + cur_seq == seq_nr && test_bit(slotid, tbl->used_slots)) + ret = true; + spin_unlock(&tbl->slot_tbl_lock); + return ret; +} + /* * nfs4_alloc_slot - efficiently look for a free slot * --- a/fs/nfs/nfs4session.h +++ b/fs/nfs/nfs4session.h @@ -77,6 +77,7 @@ extern int nfs4_setup_slot_table(struct unsigned int max_reqs, const char *queue); extern void nfs4_shutdown_slot_table(struct nfs4_slot_table *tbl); extern struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl); +extern bool nfs4_slot_seqid_in_use(struct nfs4_slot_table *tbl, u32 slotid, u32 seq_nr); extern void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot); extern void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl); bool nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl, Patches currently in stable-queue which might be from trond.myklebust@xxxxxxxxxxxxxxx are queue-4.4/nfsv4.1-fix-oopsable-condition-in-server-callback-races.patch queue-4.4/pnfs-ensure-layoutget-and-layoutreturn-are-properly-serialised.patch queue-4.4/nfsv4.x-fix-a-refcount-leak-in-nfs_callback_up_net.patch queue-4.4/nfsv4.1-fix-the-create_session-slot-number-accounting.patch queue-4.4/pnfs-the-client-must-not-do-i-o-to-the-ds-if-it-s-lease-has-expired.patch -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html