Subject: Re: new sysctl(KERN_PROC, ...) interface (was: sysinfo(2))
To: Eduardo Horvath <erh@nimenees.com>
From: Simon Burge <simonb@netbsd.org>
List: tech-kern
Date: 04/17/2000 10:40:17
Eduardo Horvath wrote:

> On Sat, 15 Apr 2000 erh@nimenees.com wrote:
> 
> If I recall correctly, the original source for this discussion was my
> mentioning that sysctl() and kernel grovelling does not work well for
> binaries under 32-bit emulation.

I thought the original motivation (and has been my main motivation) was
fixing ps's "proc size mismatch" errors, but 32 bit emulation is another
canditate as well.  Indeed, I don't think I'd seen a reference until
you sent one just after I sent my message about an implementation being
available.  Crossed wires or whatever...

> The proposed interface(s) don't really address this issue.
> 
> sysctl() is broken because it passes internal kernel structures
> directly out to userland.  This means that any 32-bit emulation
> sysctl() system call must have knowledge of all sysctl variables to make
> appropriate translations.

More below on this...

> And this still does not solve the kmem grovelling issue that results if
> you want to extract the data from a dead kernel.

This is handled (or will be when it's coded up) by kvm_getproc2().  In
theory you shouldn't need to use the sysctl interface directly, although
of course nothing stops you from doing that.

> What you need to do is provide a formal interface which provides data in a 
> specific format so the syscall wrappers can do required
> translations.  Providing raw kernel data structures along with a size does
> not help.  You could do the same thing with kernel grovelling by ignoring
> the structure size mismatch and presuming that no existing fields have
> changed size or location.

In generel there was no intent to pass raw kernel data structures back
to userland. kinfo_proc2 was defined in terms of a long of basic kernel
types (uid_t, pid_t, etc) and I had mentioned earlier that if the size
of these types changed then a backwards compatibilish type should be
provided for the kinfo_proc2 interface.

and from your last message:

> You should either get rid of all these pointers and convert them to a
> u_int64_t so the structure does not change, or provide some mechanism to
> repack te structure before the copyout() so this entire mess does not need
> to be reimplemented inside COMPAT_NETBSD32 code.

Ok, I've just about changed it so that _all_ fields are {u_,}intXX_t's,
except for the char[] fields.  One remaining hassle is sigset_t which is
defined as a structure of 4 u_int32_t's.  Instead of

	sigset_t p_siglist;

I could have

	u_int32_t p_siglist[SIGSET_LEN];

but that seems sorta ugly.


To deal with pointers, I've changed all pointers in kinfo_proc2 to
u_int64_t's, and got in fill_kproc2():

	#define PTRTOINT64(foo) ((u_int64_t)(long)(foo))

	ki->p_paddr = PTRTOINT64(p);

I need to double case to stop warnings on 32 bit platforms.  Is this
the best way?


One more thing - I guess I have to worry about structure packing,
especially for the compat32 case, right?  If so, I'll arrange for
everything to be aligned at 8 bytes then.

Will these changes address all of your compat32 concerns?  I don't have
anything to test this against - I imagine sparc64 with sparc userland is
the only user of this at the moment?

Simon.