henry (11/25/82)
I think I have just found a major security problem in System III, although I am working from the manual and have no operational system on hand to check it. The kill system call was changed between V7 and III to check effective uid of sender == real uid of receiver, whereas V7 used effective uids on both sides. The change means you can kill a setuid program. But it also means you can kill it at highly inopportune moments. For example, you can hit passwd with SIGKILL just as it is updating the password file. Unless some subtle factor that I'm unaware of intervenes, the change to use the real uid was clearly a mistake; somebody wasn't thinking clearly. The immediate fix is to change it back. This may mean a bit of tinkering because, if III's innards are like V7's, only one of the two uids is stored in the process table where it can be checked easily. It is hard to come up with a completely satisfactory way of letting people kill setuid processes without letting them kill them at bad times (i.e. during database updates). One possibility is to let signals through only if they are being caught. This fixes the security hole, but means that setuid processes are killable only by prearrangement. I see no easy way around this; *somehow* the setuid program's author has to indicate when it is safe to kill it. Allowing setuid(geteuid()) solves the problem for database updates (if setuid programs are conscientious about doing it), but I am not sure it is a complete solution. Does anyone else have any ideas?