[PATCH 3/6] nfsd: uniquify cl_confirm values

J. Bruce Fields bfields at fieldses.org
Tue Nov 27 15:21:00 EST 2007


On Tue, Nov 27, 2007 at 12:35:04PM -0500, Chuck Lever wrote:
> Hi Bruce-
>
> Some comments below.
>
> On Nov 26, 2007, at 7:32 PM, J. Bruce Fields wrote:
>> Using a counter instead of the nanoseconds value seems more likely to
>> produce a unique cl_confirm.
>>
>> Signed-off-by: J. Bruce Fields <bfields at citi.umich.edu>
>> ---
>>  fs/nfsd/nfs4state.c |   12 ++++++------
>>  1 files changed, 6 insertions(+), 6 deletions(-)
>>
>> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
>> index 035e70a..a26efa8 100644
>> --- a/fs/nfsd/nfs4state.c
>> +++ b/fs/nfsd/nfs4state.c
>> @@ -492,14 +492,14 @@ gen_clid(struct nfs4_client *clp) {
>>  }
>>
>>  static void
>> -gen_confirm(struct nfs4_client *clp) {
>> -	struct timespec 	tv;
>> -	u32 *			p;
>> +gen_confirm(struct nfs4_client *clp)
>> +{
>> +	static u32 i = 0;
>> +	u32 *p;
>>
>> -	tv = CURRENT_TIME;
>>  	p = (u32 *)clp->cl_confirm.data;
>> -	*p++ = tv.tv_sec;
>> -	*p++ = tv.tv_nsec;
>> +	*p++ = get_seconds();
>> +	*p++ = i++;
>>  }
>>
>>  static int
>
> get_seconds returns an unsigned long, which could be wider than a u32 on 
> some platforms.  Are you absolutely sure the implicit type conversion is 
> doing what you want here, even on platforms where a long isn't 32 bits?

Whoops, I hadn't noticed that.  But, yes, it's actually fine--since
we're converting to u^32, it'll just reduce mod 2^32, which will cause
collisions only for replays exactly 2^32 seconds (well over a century)
apart.

> I assume that cl_confirm.data is an opaque, so __be32 rather than u32 isn't 
> necessary for the pointer, and endianness is not an issue for the type 
> conversion.

Yes.

> You do need to guarantee that you are getting the bits that 
> change most often into cl_confirm.data.
>
> Also, what kind of serialization do gen_confirm()'s callers use?  Would it 
> be possible for a race to cause two callers to get the same uniquifier?  If 
> it's already safe, it bears adding a comment to that effect.

Alas, practically everything in this file is under one big mutex, so
it's littered with stuff like this.

> A couple of nits: I would avoid using "i" in this case, since you are not 
> indexing something.  "uniq" might be a better name for that variable.

Harrumph.  I thought "i" meant "integer", not "index".  And there's a
special place in my heart for one-letter variable names.

> And, checkpatch.pl (or its maintainer) would probably complain about
> leaving the function's return type declaration on a separate line.

OK, thanks.

>
> Would it be problematic for the confirm ID if time (as returned by 
> get_seconds()) went backward?

Perhaps, if it went backwards far enough that we had time to generate
2^32 cl_confirm's in the time it took to catch up again.

It seems  unlikely enough that I'm not inclined to worry about it.  And
I don't see a simpler way to generate a number guaranteed to be unique
across reboots.  (But I need to think some more about whether that's
actually required.)

> If this value is exposed on the network, it would be better to use a 
> randomized value instead of a time stamp to prevent exposing the system's 
> time on the network (SOP for secure networking).

NFS servers expose the server's time in ever getattr.  (I'm assuming
get_seconds reports gmt or something and not time-since-boot.)

> net_random() is the accepted mechanism to get an adequately random value 
> for such things.  It generates a non-repeating stream of pseudorandom 
> values without a lot of overhead.  You could use the tv_nsec field of 
> CURRENT_TIME as the seed.
>
> Would it be possible for a reboot to cause a replay of the uniquifier 
> values?  If so, is that going to cause trouble?  Instead of starting at 
> zero, the uniquifier should start at a random point.
>
> Starting the uniquifier at a random point would also be wise because 
> otherwise attackers could determine how many of these things have been 
> handed out (not sure if that's actually helpful info, but as mentioned it's 
> best practice to hide any real information if these IDs are going on the 
> network).

The thought of worrying about that just makes me tired.  If you make
patches for the obvious cases (e.g. not lock seqid's where last I
remember it was unclear whether we could get away with non-zero initial
values), I'll take them.

--b.


More information about the NFSv4 mailing list