Re: setuid scripts (was Re: proc fs and shared pids)

Albert Cahalan (albert@ccs.neu.edu)
Sat, 28 Sep 1996 16:33:43 -0400 (EDT)


From: Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>
>
> Or maybe we should start working on a "real" /dev/fd filesystem as
> found on Solaris (possibly other systems too, but I can't check right
...
> One nice thing about these files is that they are really character
> devices (minor number == fd number), and so they don't need to be

Then fd numbers are limited by the biggest minor number.

> Now, I have tried looking into implementing a /dev/fd/* driver
> (as described by the Solaris man page), but I'm not sure if it
> is possible with our current VFS interface. I can have my own
> low level open() routine, but I can't replace the existing code
> which does all the "struct file" allocation (unnecessary in this
> case - we just need the minor number of the device, do a "dup"
> and return the new file descriptor). Any ideas? (other than
> a dirty hack: add a check for /dev/fd major directly into the
> linux/fs/open.c code - but Linus probably wouldn't like it very
> much ;-)

OK, check for the "/dev/fd" string instead :-)

> [Another idea, somewhat unrelated: start moving /proc to a new location,
> so that it doesn't conflict with Solaris /proc, if someone ever implements
> that for more binary compatibility between SparcLinux and Solaris.

I really like that idea, but it will be hard! I think putting the
proc location in a header file might help. I'd like to move the
Linux /proc to /sys or /kernel and put all the process directories
in /sys/proc or /kernel/proc. It would be much cleaner.

> For now mount procfs under /proc-linux (or whatever) and keep a symlink
> /proc -> proc-linux for compatibility until all programs are changed to
> use /proc-linux; when that is done we can have a Solaris-like /proc.
> Choosing the same pathname for something that is quite different from
> other systems was a mistake IMHO... Does Digital Unix also have this
> /proc filesystem, or is it Solaris-specific?]

Does it ever! There is a /proc with _extensive_ debugging IOCTL support.
It has support for debugging threaded applications.

--------- some examples ----------

jupiter:/proc$ /bin/ls
00000 00302 01229 03503 08036 12522 16727 19611 22999 26382 30671
...
00295 00733 02973 07237 11997 16078 19324 22533 25934 29680 32711
00296 00786 03264 07287 12009 16550 19346 22739 25987 29710
00297 00855 03270 07662 12128 16622 19385 22932 26199 29974
00299 00887 03350 07831 12332 16715 19521 22938 26226 30404

[There are no weird things, just processes.]

jupiter:/proc$ /bin/ls -l $$
-rw------- 1 acahalan cs1999 17350656 Sep 28 16:01 22533

jupiter:/proc$ file $$
22533: cannot open for reading
22533: Invalid argument

jupiter:/proc$ /bin/ls -l 00000
-rw------- 1 root system 290193408 Sep 28 16:00 00000

jupiter:/proc$ file 00000
00000: cannot open for reading
00000: Permission denied

--------- some documentation -------------

For each running and zombie process, there is an entry in the system process
table, which appears as a file name in the /proc directory. The file name is
the decimal representation of the process id. File names are padded with
leading zeros (0) so that each file name is a minimum of 5 decimal digits.
For example, if a process has a process id of 123, its file name would be
specified as 00123. You do not have to specify the leading zeros when
specifying the file name. For example, specifying ls -l /proc/123 is
acceptable.

[Very nice, just don't be thinking octal. It sorts well and you can
make some buffer size assumptions to improve the speed of your code.]

All auditing requirements for the /proc file system are handled at the
Virtual File System (VFS). The /proc file system is read only. Only root or
the superuser can open all processes using the /proc file system. If you are
a nonprivileged user, a debugging process can open an active process only if
the following conditions are met:

** Both the uid and the gid of the debugging (opening) process matches
those of the running process.

** The debugging (opening) process has read permission for the executable
file from which the active process was created.

** The executable file from which the active process was created must not
have setuid or setgid permission unless the opening process has root
or SEC_DEBUG privilege established or is the owner (for setuid) or a
group member (for setgid).

If a debugging process opens an active process and the active process calls
exec(2) to start another image that has suid or sgid permissions, or if the
debugging process does not have read permission for the image that the
active process invokes, the debugging process is denied access to the
process information for the new image with the exception of a close
operation. Hence, a file descriptor is not always valid after the active
process executes another image. This is also true when you have root or
superuser privileges.

Any number of number of opens for read and write are allowed; however, to
prevent confusion, if several processes are trying to control another
process, an exclusive open for write can be requested. An open for write
that includes the O_EXCL specifier only succeeds if the process is not
already open for a write, even if you are root or an otherwise privileged
user. However, an open for write that does not specify O_EXCL always
succeeds for root or an otherwise privileged user.

When a file is closed, any tracing flags that were set are left on, unless
the Run on Last Close (RLC) flag was set by an ioctl call. If RLC is set,
and the last file descriptor pertaining to the process is closed, all
tracing flags are cleared and the process is set to run (if it was stopped).
Breakpoints are not affected by RLC because breakpoints are written into the
text area of a running process by a debugger; the debugger is therefore
always responsible for replacing the original instructions.

[There is much more, including structs used for the IOCTLs and info
about controlling threads]