Re: Like Topsy, UNIX growed uids and gids, as is the Chibi Scheme SRFI-170 implementation Lassi Kortela 28 Jul 2019 14:23 UTC

Thanks for the legwork and entertaining posts on your progress Harold :)
I continue regret that I still can't put more time into this SRFI. I
will join in for real as soon as the GraphQL work plateaus.

> I bring this up because explaining the fiddly details of all of these
> set uid/gid functions, especially the two new ones, with
> set-user-real-and-effective-/gid/ being particularly complicated, is
> looking to get beyond the scope of the SRFI document.

It's probably best to provide dumb wrappers. Unix security has been an
active research area since like 1995. The finer points of things like
uid/gid setting are liable to change in the next decade for many
applications. I don't know of any concrete proposals, but it's not hard
to imagine, especially with containers and capability-based security
frameworks being explored constantly.

> I'm certainly
> being tempted to crib more than I should from the POSIX document, and
> I'm thinking we might want fall back to saying the SRFI's procedures are
> completely straightforward wrappers for these functions.

+1

> All of which
> take integers, even -1 for the -and- functions which means don't change
> that value, and all return 0 or -1 and errno.

I don't think the Scheme wrappers in the SRFI should return integers. Is
there any reason they shouldn't raise an exception and put the errno
value in the exception object?

> documentation, and e.g. Stevens presumably and others who tell you how
> to use them all to do things securely, we'd be covered without trying to
> write some near essay level material for what are from the SRFI's
> viewpoint trivial wrappers.

I agree that detailed explanations are not necessary. They are liable to
change anyway.

More generally, none of the Unix syscalls are useful to regard as
abstractions. One must know exactly what they do. It's not useful, for
example, to think that "write() writes to a file". You have to know
whether the file descriptor is in non-blocking mode, and worry about
EINTR, etc. Basically all of the APIs are like that. What's that quote
about "the expressive power of two dixie cups and a string"... To be
fair to Unix, Windows is hardly any better. Making a portable C-level OS
is just hard.

> And speaking of wrappers, I'm finding the Chibi Scheme automagic C FFI
> marvelous and ideal for a demonstration implementation of this SRFI,

Indeed, it's surprisingly good for a small interpreter.

> only failings of note so far are not being able to pass parameterized
> array sizes, e.g. for user-supplementary-gids, I'm currently doing
>
>> (define-c int (%getgroups getgroups) ((value 65537 int) (result (array
>> gid_t 65537))))

"If gidsetsize is 0, getgroups() shall return the number of group IDs
that it would otherwise return without modifying the array pointed to by
grouplist." [Source:
<https://pubs.opengroup.org/onlinepubs/007904875/functions/getgroups.html>]

Hence two reasonable strategies. First one:

* Call count = getgroups(0, NULL) to get the actual count.
* Then call getgroups(count, gid_array);

Second one:

* Call getgroups() with a reasonable size like 16.
* If you get EINVAL back, call it again, doubling the array size at each
call. All practical situations should be handled with two calls (what
sysadmin makes a system that needs 32 supplementary groups?) but if not,
the powers-of-two growth provides a nice O(log N) safeguard.

> Plus an inability to pass an array of two timespec structs to set file
> times to nanosecond precision, the argument type (array (struct
> timespec) 2) doesn't do the right thing:

I've also dealt with time structs in the Chibi FFI. I just passed four
integers for two (sec, nsec) pairs and combined things on the Scheme
side. It was fine.