Re: Amendment 1 to Making SRFI-170 less of a monster Lassi Kortela 02 Aug 2019 19:53 UTC
> I think you forgot "running in datacenter X on electrical grid Y in > country Z on the planet Earth in the Milky Way galaxy in the > Relativistic Quantum universe." Philosophical considerations of the meaning of sameness aside, all Scheme programs run in the same galaxy. There could be a non-ironic application of having the datacenter on the stack. Docker orchestration can already make a datacenter-in-a-box. > In the beginning, yes: one username, one uid. But the number of users > grew faster than the number of possible uids (which was 256 for a long > time) and users routinely shared uids for a while. The LOGNAME and USER > variables were invented to solve that problem. Nowadays there are 64K > uids and few systems have more than a few real users anyway. But I > agree: flush it. I didn't know the history. Anyway, setting USER means people can trivially lie about who they are. For the password database, only the sysadmin can change that (though users can still use an LD_PRELOAD hack to override those routines on most installations, and Scheme is powerless to stop that). Continuing on the "ban setuid" theme, this just shows that user information should probably be served by a daemon through a Unix-domain socket too :) Some systems have 2^32 UIDs now, though 2^15-1 is probably the safe portable maximum. I looked up the maximums for the popular systems for one program. > Interesting, but I don't think it matters. The important consideration > is whether this is a raw or block-structured device. I don't understand that. That FreeBSD link says "Block devices are disk devices for which the kernel provides caching. This caching makes block-devices almost unusable, or at least dangerously unreliable. The caching will reorder the sequence of write operations, depriving the application of the ability to know the exact disk contents at any one instant in time." Do you mean users need to know whether read/write on a byte granularity is possible, or whether users should do block read/writes with a particular block size? Not sure whether FreeBSD requires disk reads to be a multiple of 512 bytes, but all the talk of caching suggests it may not matter. > I've been thinking about a separate SRFI for OS errors too. That means > exceptions native to the Scheme implementation and unrelated SRFIs can > supply errno values in their exceptions too. > > I'd rather not. The errno compacts the whole universe of possible > errors into about 7 bits. See > <http://libexplain.sourceforge.net/lca2010/lca2010.pdf> (about > libexplain, which is a truly great library) for what users really need > to know. It's true that errno often leads to baffling error messages. But it's still the default thing to use and I think we should give access to those values. It can and should be supplemented by contextual information (such as the name of the syscall that failed) but I don't see why we should throw it away altogether or bury it in the internals. libexplain is a very neat idea but the implementation is huge: <https://github.com/Quuxplusone/libexplain/tree/master/libexplain-1.4/>. If we provide the name of the failed syscall to go with each errno, it'll be easy to plug in something like libexplain after the fact. > Yes, well, failing to drop privileges can be a disaster. The failed setuid() will raise an exception in Scheme. That will error-exit the program right there unless the programmer committed the sin of ignoring errors in a program that runs as root. > The couple of setuid programs needed on a system (su and sudo > > ls -l /bin /usr/bin | grep '^-rws' shows mount/umount/fusermount, > ping/ping6, at, chfn, chsh, passwd/gpasswd, and newgrp, all > administration or self-administration tools. I'd never heard of the > last one, pkexe, which lets you execute a program as another user, but a > little less crudely than su <name>. It's a FreeDesktop PolicyKit thing. Instructive. ping needs raw sockets to send ICMP echos. Newgrp seems similar to a restricted version of su. I'd probably file the others under historical design mistakes that should be replaced by privileged daemon + unprivileged client. That unprivileged users can start programs to frob the user database seems particularly worrying. The fundamental problem is that a setuid program needs to clean up a staggering array of system-dependent things to make sure nothing bad can happen. The right way to "clean up" is not to make a mess in the first place, by starting a daemon in controlled conditions via daemontools / runit / systemd. Daemons should only be started by sending a start command to a persistent supervisor like that - starting from whatever environment happens to be in the shell currently = things bound to go wrong in a non-reproducible manner.