Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Jan 2005 23:02:20 -0600
From:      Alan Cox <alc@cs.rice.edu>
To:        Kris Kennaway <kris@obsecurity.org>
Cc:        krentel@dreamscape.com
Subject:   Re: fstat triggered INVARIANTS panic in memrw()
Message-ID:  <20050119050220.GU3194@noel.cs.rice.edu>
In-Reply-To: <20050119024657.GA78197@xor.obsecurity.org>
References:  <20050115083847.GA47466@xor.obsecurity.org> <20050116003432.GA448@xor.obsecurity.org> <20050116050433.GA65733@xor.obsecurity.org> <20050116211349.GG26214@noel.cs.rice.edu> <20050117014746.GA96797@xor.obsecurity.org> <20050117021815.GA8953@xor.obsecurity.org> <20050117023031.GA12825@xor.obsecurity.org> <20050118203153.GM3194@noel.cs.rice.edu> <20050119024657.GA78197@xor.obsecurity.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Jan 18, 2005 at 06:46:57PM -0800, Kris Kennaway wrote:
> On Tue, Jan 18, 2005 at 02:31:53PM -0600, Alan Cox wrote:
> 
> > > An interesting datapoint is that none of the non-i386 package machines
> > > have hit this problem, but the i386 machines can't stay up for more
> > > than a few minutes under load (which translates to only a few fstat
> > > invocations).
> > 
> > The field f_offset is 64 bits wide.  If this were a race between use
> > and deallocation of the file structure within the kernel, then I would
> > expect f_offset's value to be 0xdeadc0dedeadc0de, not
> > 0x00000000deadc0de.  More likely than not, the 0xdeadc0de is being
> > passed in from user level.  The i386 kernel is just not handling it
> > gracefully.  
> 
> Shouldn't this at least be hitting the check in memrw():
> 
>                         if (!kernacc((caddr_t)(int)uio->uio_offset, c,
>                             uio->uio_rw == UIO_READ ?
>                             VM_PROT_READ : VM_PROT_WRITE))
>                                 return (EFAULT);
>                         error = uiomove((caddr_t)(int)uio->uio_offset, (int)c, uio);
> 
> (kgdb) print uio->uio_offset
> $2 = 3735929054
> (kgdb) print uio->uio_rw
> $3 = UIO_READ
> (kgdb) print c
> $4 = 2058814332

Yes, it should.  :-)  The problem is two-fold.  First, kernacc()
unlike useracc() doesn't check for address wrap, i.e., end < start.
Presumably the author of kernacc() assumed that kernel code would
never call kernacc() with such dubious arguments.  Second,
vm_map_check_protection() returns "success" whenever address wrap
occurs. 

Alan



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050119050220.GU3194>