[net.unix-wizards] Acessing kmem, how about a driver?

egz@druky.UUCP (BonnellDS) (12/10/84)

<The problem's plain to see, too much technology>

     Seems to me that what people have been saying about a system call to
provide access to various system data structures could be handled very
effectively with a character device driver.

     The minor numbers for this driver would provide readonly access to
various areas, such as '/dev/proc' for the process table, '/dev/smap' for
the swap area map, '/dev/buf' for looking at the disk buffers, etc.

     Such a device driver would have the following benifits:

	1. Restricted access to memory, with useful error codes for anyone
	   trying to write to these read-only areas.

	2. Since the driver is a portion of the kernel, there is no
	   chance that the data reads will occur at the wrong address.

	3. Standard device names can be used, freeing applications code
	   from needing to 'nlist' a given kernel file (which may not even
	   be booted!).

	4. Such a driver could have it's own 'ioctl' commands. This feature
	   would allow an applications program to determine certain things
	   about a data area before the read occurs (such as the number and
	   size of 'proc' structures in '/dev/proc'). This way, the
	   applications code could notify the user that something is not
	   right, perhaps the applications code needs to be re-compiled.

     By using a driver, 'nlist' and 'lseek' are avoided, while data transfer
could be as great as, or greater than using a 'read' call, perhaps using
something similar to 'physio' (used in block device drivers)?

					Doug Bonnell
					AT&T ISL
					Denver, Colo.
					(303) 538-4762

guy@rlgvax.UUCP (Guy Harris) (12/12/84)

>      Seems to me that what people have been saying about a system call to
> provide access to various system data structures could be handled very
> effectively with a character device driver.
> 
>      The minor numbers for this driver would provide readonly access to
> various areas, such as '/dev/proc' for the process table, '/dev/smap' for
> the swap area map, '/dev/buf' for looking at the disk buffers, etc.
> 
>      Such a device driver would have the following benifits:
> 
> 	1. Restricted access to memory, with useful error codes for anyone
> 	   trying to write to these read-only areas.

This can be achieved, in large part, by having "/dev/kmem" only writable
by the super-user, and readable by group "0", and by having all programs
that only need to read the data be set-GID 0 rather than set-UID 0.  (While
we're on the topic of group "0", I've found that a lot of programs are set-UID
solely because they need to be able to *read* arbitrary files; would giving
"sub-super-user" privileges to gid 0, i.e., the ability to open arbitrary
files for reading, be useful?)

> 	2. Since the driver is a portion of the kernel, there is no
> 	   chance that the data reads will occur at the wrong address.

Well, if you got the right name list, this shouldn't happen anyway.  It
can happen if the table you're reading has pointers to other structures,
and those other structures move or change between reading the table entry
and the other structure in question, but fixing that would require a driver
which knew about those pointers and made reading the table entry and what
that entry points to an atomic operation.

> 	3. Standard device names can be used, freeing applications code
> 	   from needing to 'nlist' a given kernel file (which may not even
> 	   be booted!).

Unfortunately, a complete solution to this problem requires that you
provide a driver for every piece of data in the kernel that any program
would like to read.  There are a lot of programs in 4.2BSD that rummage
around the kernel ({io,vm,net}stat, just to name three) and they look
at a lot of data structures; it could be hard to anticipate all the
needed data structures.  It might solve part of the problem ("ps", for
instance), but any "complete" solution will break when the next program
is written.

>      By using a driver... data transfer could be as great as, or greater
> than using a 'read' call,

But you would be doing a "read" call to read from the driver anyway.  The
4.2BSD "memory driver" copies stuff from kernel space to user space about
as fast as it can be done - it uses a single "uiomove" call, which is
what your driver would have to do.

> perhaps using something similar to 'physio'?

Not needed - "physio" is used for devices which do direct DMA access;
the CPU can go through directly your machine's MMU to move stuff into
user space.

I'm not sure that anything is badly enough broken by being forced to do
an "nlist" and read from "/dev/kmem" that a fix is called for.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

andrew@garfield.UUCP (Andrew Draskoy) (12/20/84)

> From Guy Harris:
> This can be achieved, in large part, by having "/dev/kmem" only writable
> by the super-user, and readable by group "0", and by having all programs
> that only need to read the data be set-GID 0 rather than set-UID 0.  (While
> we're on the topic of group "0", I've found that a lot of programs are set-UID
> solely because they need to be able to *read* arbitrary files; would giving
> "sub-super-user" privileges to gid 0, i.e., the ability to open arbitrary
> files for reading, be useful?)

Using set-gid instead of set-uid makes things more secure on 4.2bsd,
but on other UN*Xes groups are incredibly insecure - especially group zero.

Now that I've got you thinking about security (again), perhaps we should
find a way to talk about it more openly.  Since any attempt to set up
a newsgroup or mailing list seems doomed to failure due to insecurity
in the mail/uucp/news software, perhaps an alternate method can be used.
I am thinking of something along the lines of a newsletter for people who
prove that they have licenses, to be run by a "respectable" organisation
which would hopefully not have too much trouble with an extra publication
(Maybe USENIX would help out with something like this?).

The nearest thing to a forum on UNIX security that I have heard of is the
"secret" security meeting supposedly held at the S.L.C. Usenix meeting.
I wasn't at S.L.C. so I don't know what happened there, but it hasn't
helped the rest of us.  I don't think such meetings would be the best
way to handle the issue, since

1) Not everyone who needs to can go.
2) The Usenix meetings are only held bi-annually.
3) How do you decide who should be allowed into the meeting?

It seems obvious from the recent discussions of security in unix-wizards
that there is some interest in doing something about the situation.
Does anyone have any comments?  (Flames by mail, please.)
-- 
Andrew Draskoy
{akgua,allegra,ihnp4,utcsrgv}!garfield!andrew
The opinions expressed above may not represent those of the author
after he has had some sleep.

jack@vu44.UUCP (Jack Jansen) (12/27/84)

I was thinking of making a modified kmem driver, especially for
things like 'ps', etc. It would incorporate a structure like

struct pmdevs {
	caddr_t pm_start;
	caddr_t pm_esize;
	caddr_t pm_last;
} pmdevs[] = {
	&u, sizeof(u), u+sizeof(u),	/* U area */
	&procs, sizeof(*procs), &procs[NPROCS], /* process table */
	....
	}

Every minor device would be associated with one of the entries in the
array, and would adress memory from pm_start to pm_last.
In this way, you could protect every table by it's own minor h
device, making superuser permission for things like 'ps' unnecesary.

The 'pm_esize' gives the size of a single entry. It can be collected
via a ioctl call, so the user program could for instance check whethet
the size of a certain structure hasn't changed since it was
compiled.

Does this seem like a feasible idea? If it is, has anyone implemented
it already, or something similar?
-- 
	Jack Jansen, {seismo|philabs|decvax}!mcvax!vu44!jack
	or				       ...!vu44!htsa!jack
If *this* is my opinion, I wasn't sober at the time.