Date: Mon, 29 May 2000 10:40:07 -0700 (PDT) From: Anatoly Vorobey <mellon@pobox.com> To: freebsd-bugs@FreeBSD.org Subject: Re: kern/18874: 32bit NFS servers export wrong negative values to 64bit clients Message-ID: <200005291740.KAA59402@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/18874; it has been noted by GNATS. From: Anatoly Vorobey <mellon@pobox.com> To: Alexander Langer <alex@big.endian.de> Cc: FreeBSD-gnats-submit@FreeBSD.ORG Subject: Re: kern/18874: 32bit NFS servers export wrong negative values to 64bit clients Date: Mon, 29 May 2000 13:34:47 -0400 You, Alexander Langer, were spotted writing this on Mon, May 29, 2000 at 07:21:40PM +0200: > Thus spake Anatoly Vorobey (mellon@pobox.com): > > > Gotta love those signed<-->unsigned bugs ;) > > Isn't that 32bit signed vs. 64bit signed? I thought that was the case at first too, but it doesn't appear so. NFS transfers available values for statfs as 32-bit unsigned in v2, and 64-bit unsigned in v3, regardless of platforms it runs on (your setup uses NFSv3, right?). See the nfs_statfs structure in sys/nfs/nfsproto.h . Now the bug says that either the server puts the value in nfs_statfs incorrectly (maybe, but I couldn't find any fault with the sources in nfs_serv.c), or the client takes it out incorrectly (I think that's likely, hence the attached patch), or the xdr conversion routines work incorrectly for quad values (very unlikely, would've broken lots of things in NFS). > > but I don't really have a working setup with Alpha NFS to test this against. > > On the client, I guess? (the patch). Will it break the i386 nfs? Yes, on the client, and no, shouldn't break anything at all. > > A brief explanation: tquad is 64-bit unsigned, and holds the available > > bytes value which is really signed long. Suppose the real value is negative. > > If we divide it by NFS_FABLKSIZE first, and then > > cast to long, we risk turning it into a positive value by division. > > Yes, but what about i386, where long is only 32bit and can't hold that > value? Hmm. I haven't thought of that. A simple test I made on i386 showed that (long)(u_quad_t)(long)(-100) == -100, so I guess the conversion works fine, even though long is 32bit, and I can't really explain why at the moment :) If you want to be extra sure, you can cast tquad to quad_t before casting it to long. Then it'll hold the real negative value which must be correctly converted into long. I know that you can point out that Alpha's long was bigger than i386's long -- but there's not much you can do about *that*, since you have to start from struct statfs on Alpha and finish with struct statfs on i386, and f_bavail is long on both. You'll just have to hope that the underlying filesystem restricts this value to 32 bits or something. -- Anatoly Vorobey, mellon@pobox.com http://pobox.com/~mellon/ "Angels can fly because they take themselves lightly" - G.K.Chesterton To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200005291740.KAA59402>