in reply to Not understanding the code to drop privileges in perlsec
I'm not sure if this is already clear, but the upper-case variables in the example are all special variables: reading from them or writing to them invokes magic in the perl interpreter. Lines 4, 5, 7, 8 and 10 are all invoking "set" magic on one or two of those variables.
Or at least they would be if the code was prefaced with use English;. The special variables are usually called the "punctuation variables", since they have names like $<. The English module exists to give them more readable aliases like $UID. If you do not preface the code with use English;, then those names are just plain variables and the example code is essentially an extended no-op.
I don't know much about how these things work at the OS level, but within Perl the magic happens within mg.c:Perl_magic_set, in a case statement based on the names of the underlying punctuation variables - perlvar will tell you that $UID, $EUID, $GID, EGID are the English names for $<, $>, $(, $) respectively.
So for assignment to $UID, the relevant code is in case '<', where we see that it will use the first available of setruid(uid), setreuid(uid, -1), setresuid(uid, -1, -1) or (with more caveats) setuid(uid).
However, there is a wrinkle: if these variables form part of the left hand side of a list assignment, as in line 10 of your example code, additional effort is made to do multiple changes atomically. This is done by setting the interpreter variable PL_delaymagic = DM_DELAY in the handling of list assignment by pp_hot.c:PP(pp_aassign), then in Perl_magic_set setting more bits in PL_delaymagic to record what needs doing, then finally calling pp_hot.c:S_aassign_uid to do the simultaneous assignments.
In this case that's all a bit of a waste of effort, since the point is to assign to ($UID, $EUID) or to ($GID, $EGID) simultaneously, but the list assignment in the example code is to ($EUID, $EGID). It does mean, though, that the order of attempts is different: it is now the first available of setresuid(), setreuid(), setruid/seteuid(), setuid().
(That the order it chooses is different for scalar or list assignment may be a subtle bug; I've opened issue #22018 to get that checked out.)
|
---|
Replies are listed 'Best First'. | |
---|---|
Re^2: Not understanding the code to drop privileges in perlsec
by Nocturnus (Scribe) on Feb 23, 2024 at 18:12 UTC | |
by NERDVANA (Priest) on Feb 24, 2024 at 06:05 UTC |