This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: [PATCH] for glibc-2.2 getdents code


On Wed, Feb 21, 2001 at 07:32:38PM +0100, Trond Myklebust wrote:
> >>>>> " " == Jakub Jelinek <jakub@redhat.com> writes:
> 
>      > But d_type should be completely orthogonal to LFS. It is not
>      > present in sys_getdents simply because sys_getdents was there
>      > before d_type was introduced and as userland getdents can call
>      > sys_getdents64 to get d_type, I have not added sys_newgetdents.
>      > IMHO the fix is really simple, if kernel nfs client will cast
>      > the offset for NFSv2 properly (it goes as 32bit value over the
>      > network AFAIC), then the problem will go away. And if people
>      > are using NFSv3 and the server passes d_off's which don't fit
>      > into 32bit off_t, then IMNSHO kernel sys_getdents should fail
>      > on it the same way as glibc getdents does, because it is better
>      > to give user error than incorrect information (= silently
>      > discarded bits from d_off).
> 
> No! No! No! How on earth is NFS supposed to know where a cookie came
> from and whether or not a sign extension has been performed on it?
> Is the cookie 0xFFFFFFFF80000001 on an NFSv3 system a sign extended
> 32-bit cookie 0x80000001, is it a full 64-bit cookie or what???
> 
> I agree that sys_getdents could return EOVERFLOW if we have 64-bit
> cookies, however that is not an excuse for glibc to be playing around
> with valid 32-bit cookies.
> 
> A cookie is an opaque value and cannot be processed.

I thought we're talking here about NFSv2.
u32 *
nfs_decode_dirent(u32 *p, struct nfs_entry *entry, int plus)
{
        if (!*p++) {
                if (!*p)
                        return ERR_PTR(-EAGAIN);
                entry->eof = 1;
                return ERR_PTR(-EBADCOOKIE);
        }

        entry->ino        = ntohl(*p++);
        entry->len        = ntohl(*p++);
        entry->name       = (const char *) p;
        p                += XDR_QUADLEN(entry->len);
        entry->prev_cookie        = entry->cookie;
        entry->cookie     = ntohl(*p++);
	^^^^^^
Here is really up to you if you do ntohl(*p++) or (s32)ntohl(*p++)
as the protocol has 32-bit cookies, not 64-bit cookies.
If you use the latter, then no cookie will cause EOVERFLOW and the server
really does not care, since when you pass the cookie back to it, you
truncate it to 32bits again.
        entry->eof        = !p[0] && p[1];

        return p;
}

With NFSv3, of course no sign extension or whatever should happen,
sys_getdents should return EOVERFLOW if it sees an d_off which does not fit
and users should use getdents64/readdir64, because everything else is wrong
(d_off value would be truncated).

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]