diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 528365b89a35..ad72c0d57bee 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -8010,10 +8010,20 @@ __be32 manage_cpntf_state(struct nfsd_net *nn, stateid_t *st, state = NULL; goto unlock; } - if (!clp) + if (!clp) { refcount_inc(&state->cp_stateid.cs_count); - else + } else if (memcmp(&clp->cl_clientid, &state->cp_p_clid, + sizeof(clientid_t))) { + /* + * OFFLOAD_CANCEL: only the creating client may cancel. + * so_id is guessable, so without this check any client + * could free another's cpntf state. + */ + state = NULL; + goto unlock; + } else { _free_cpntf_state_locked(nn, state); + } } unlock: spin_unlock(&nn->s2s_cp_lock);