From: J. Bruce Fields Date: Mon, 12 Sep 2016 20:00:47 +0000 (-0400) Subject: nfsd: randomize SETCLIENTID reply to help distinguish servers X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;h=6ab13dd7deefb5b8f9d6f7b8b78e0cded220ce71;p=deliverable%2Flinux.git nfsd: randomize SETCLIENTID reply to help distinguish servers NFSv4.1 has built-in trunking support that allows a client to determine whether two connections to two different IP addresses are actually to the same server. NFSv4.0 does not, but RFC 7931 attempts to provide clients a means to do this by suggesting that they perform SETCLIENTIDs to the two servers and comparing the clientids and verifiers. Linux clients since 05f4c350ee02 "NFS: Discover NFSv4 server trunking when mounting" implement this suggestion. It is possible that other clients do to. knfsd generates the 64-bit clientid by concatenating the 32-bit boot time (in seconds) and a counter. This makes collisions between clientids generated by the same server extremely unlikely. But collisions are very likely between clientids generated by servers that boot at the same time, and it's quite common for multiple servers to boot at the same time. The verifier is generated in the same way, so has the same problem. Therefore recent NFSv4.0 clients may decide two different servers are really the same, and mount a filesystem from the wrong server. The fault is really with RFC 7931, and needs a client fix, but it's not clear what that fix will be. In the meantime, mitigate the chance of these collisions by randomizing the starting value of the counters used to generate clientids and verifiers. Signed-off-by: J. Bruce Fields --- diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 65ad0165a94f..36b2af931e06 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -1216,6 +1216,8 @@ static __net_init int nfsd_init_net(struct net *net) goto out_idmap_error; nn->nfsd4_lease = 90; /* default lease time */ nn->nfsd4_grace = 90; + nn->clverifier_counter = prandom_u32(); + nn->clientid_counter = prandom_u32(); return 0; out_idmap_error: