]> git.baikalelectronics.ru Git - kernel.git/commitdiff
NFSD: fix seqid in copy stateid
authorOlga Kornievskaia <olga.kornievskaia@gmail.com>
Wed, 4 Dec 2019 20:13:53 +0000 (15:13 -0500)
committerJ. Bruce Fields <bfields@redhat.com>
Mon, 9 Dec 2019 16:44:07 +0000 (11:44 -0500)
s_stid->si_generation is a u32, copy->stateid.seqid is a __be32, so we
should be byte-swapping here if necessary.

This effectively undoes the byte-swap performed when reading
s_stid->s_generation in nfsd4_decode_copy().  Without this second swap,
the stateid we sent to the source in READ could be different from the
one the client provided us in the COPY.  We didn't spot this in testing
since our implementation always uses a 0 in the seqid field.  But other
implementations might not do that.

You'd think we should just skip the byte-swapping entirely, but the
s_stid field can be used for either our own stateids (in the
intra-server case) or foreign stateids (in the inter-server case), and
the former are interpreted by us and need byte-swapping.

Reported-by: kbuild test robot <lkp@intel.com>
Fixes: d5e54eeb0e3d ("NFSD add nfs4 inter ssc to nfsd4_copy")
Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/nfsd/nfs4proc.c

index fc72f57297327d56565a84cb91384db8d0ef25ba..42fee1f94a84b62e506f7aa8c6c0355a0bff10e0 100644 (file)
@@ -1280,7 +1280,7 @@ nfsd4_setup_inter_ssc(struct svc_rqst *rqstp,
 
        copy->c_fh.size = s_fh->fh_handle.fh_size;
        memcpy(copy->c_fh.data, &s_fh->fh_handle.fh_base, copy->c_fh.size);
-       copy->stateid.seqid = s_stid->si_generation;
+       copy->stateid.seqid = cpu_to_be32(s_stid->si_generation);
        memcpy(copy->stateid.other, (void *)&s_stid->si_opaque,
               sizeof(stateid_opaque_t));