More on Bad Bug

2001-04-17 Thread Terry Lambert

NB: To keep me in the loop, keep me in the Cc: list, since I
rarely follow -current these days).

I've further localized the bug to the freeing of credentials
associated with socket buffers, and being unrelated to the
crhold()/crfree() calls in socreate() and sodealloc().

Specifically, the bug exhibits as INVARIANTS complaining about
a 72 byte malloc -- it seems that in avoiding system call
structures, I neglected struct rusage -- which is exactly 72
bytes in size, as well.

There seems to be some bad code in soo_close(), which looks like:

int
soo_close(fp, p)
struct file *fp;
struct proc *p;   
{
int error = 0;

fp-f_ops = badfileops;
if (fp-f_data)
error = soclose((struct socket *)fp-f_data);
fp-f_data = 0; 
return (error);
}

It seems to me this should be?

int
soo_close(fp, p)
struct file *fp;
struct proc *p;   
{
int error = 0;

if (fp-f_data)
error = soclose((struct socket *)fp-f_data);
if (!error) {
fp-f_data = 0; 
fp-f_ops = badfileops;
}
return (error);
}

But it's not clear that this is correct for the socket code.

The INVARIANTS code is actually part of the problem here, since the
reference count on the credential is one of the fields stomped by
the WIERD_ADDR "to be safer".

This doesn't evidence as a problem with a double free in the case
that INVARIANTS aren't used, in that the decremented count in the
crfree() (which decrements prior to examining the value to see if
it is exactly zero), would continue to be non-zero, and not decrement
back to zero (resulting in the double free).

Credentials are actually used _AMAZINGLY_ much; it seems that they
are a good candidate for some optimization to throw away references
that aren't really necessary (for example, it seems to me that a
socket can not exist without an fdp referencing it, and the fdp has
a reference count on the cred which the socket inherits from the fdp,
so the fdp's reference protects the sockets reference, and so the
socket's reference doesn't really need to be reference counted).

In any case, I'm leaving in the panic patch I sent earlier, and am
now rebuilding with my ucred reference count moved past the area
stomped by INVARIANTS.  This should permit the INVARIANTS to catch
double frees (which they can't, otherwise, because of the refcnt
decrement making it look like the block was used after being freed,
and tricking INVARIANTS in free() in kern_malloc.c.

I guess no one else is interested in this bug hunt, or no one else
is using 30,000 sockets on any of their machines?


Terry Lambert
[EMAIL PROTECTED]
---
Any opinions in this posting are my own and not those of my present
or previous employers.

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message



Re: More on Bad Bug

2001-04-17 Thread Alfred Perlstein

* Terry Lambert [EMAIL PROTECTED] [010417 16:28] wrote:
 
 I guess no one else is interested in this bug hunt, or no one else
 is using 30,000 sockets on any of their machines?

I've committed a variation of your invariants check to -current,
-stable is frozen and I'd prefer to leave it as is until after
the release date.

As far as tracking down the problem I don't have the resources in
terms of hardware, code and time for that right now, however it
looks like you've found a possible bug.

Please keep us in the loop on this.

-- 
-Alfred Perlstein - [[EMAIL PROTECTED]|[EMAIL PROTECTED]]
http://www.egr.unlv.edu/~slumos/on-netbsd.html

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message