Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

EUID cannot be set

by 0xbeef (Hermit)
on May 09, 2007 at 21:14 UTC ( #614493=perlquestion: print w/replies, xml ) Need Help??

0xbeef has asked for the wisdom of the Perl Monks concerning the following question:

Esteemed monks,

I have run into a peculiarity when using the $> variable to demote privileges in one of my programs, which can be simplified to:

sub DropPriv($uid,$groups) { $) = $groups; $> = $uid; if ($> != $uid) { print STDERR "demotion to $uid failed, EUID=$>.\n"; return 0; } return 1; }
This tested fine on my Linux system, the idea being that I would demote myself to nobody (uid 65534) before doing some system calls.

The same code unexpectedly failed on my AIX system with a resulting EUID=-2, which I'm now guessing to be related to an overflow problem since the only difference on AIX is that nobody's uid is 4294967294 by default. When I use a user with a lower uid it works fine.

The AIX system is running v5.8.0, but I got the same result on v5.8.8.

My workaround was to use the "sys" user (uid=3), but can anyone confirm this as an overflow issue with the built-in $> variable and perhaps an alternative solution?


Replies are listed 'Best First'.
Re: EUID cannot be set
by bluto (Curate) on May 09, 2007 at 22:55 UTC
    Setting $> seems to work fine on my AIX box (5.2, perl 5.8.8) if I set it to -2 or 4294967294. If I then touch a file it is owned by "nobody" in either case. The comparison fails for -2, but 4294967294 works fine. It looks like the $> variable is getting converted to an unsigned value, which would make sense since the underlying data type uid_t is unsigned.

    FWIW, I've had strange problems with setting uid/etc with variables in AIX, at least in the past. You may want to look at the various POSIX routines for this. AIX just loves to be different sometimes...

Re: EUID cannot be set
by mattr (Curate) on May 10, 2007 at 06:17 UTC
    This has been noted elsewhere in the past.

    Perl5-porters 2003.4.7-13: OS X peculiarities heading and the linked thread started by Dan Kogai (of and our merlyn jumped in too. Apparently Mac OS X and FreeBSD have the same problem/code.
    "... nobody, the traditional Unix low-privileged user, has user id -2 on MacOS X (according to /etc/passwd), but the uid_t C type is actually an unsigned integer. Consequently, getpwnam() says that nobody's UID is 4294967294." fixing User and Group in "Apache on AIX" doc.

    I don't know if overflow is the word to use.. Perlvar does say to check $!. I wonder if this is a subtle hint. Would getgrnam/getpwnam help keep your code cross-platform?
Re: EUID cannot be set
by jettero (Monsignor) on May 09, 2007 at 21:19 UTC

    I wasn't aware you could set the uid and gid through those vars... neat.

    I've always used POSIX::setuid (and setgid). perlvar states that if $> = $uid or $< = $uid fails that it sets the $! to an appropriate error message. I'd look there.

    $< = $> = 1000 or die "hrmph... silly perms or something: $!";


      Mmm, I did in fact check that:

      linux: demotion to sys(4294967294) failed: Bad file descriptor (euid: +-2) aix: demotion to nobody(4294967294) failed: (euid: -2)


        Note on AIX's nobody user for Exim
        Services for Unix blog

        It seems this is not overflow. It's just a representation in one place using an unsigned value and in another using a signed value.

        Considering there are 4,294,967,296 values in a 32-bit integer and that the signed number would be in two's complement if negative, -2 is exactly the same as 4294967294.

        As a matter of fact, I believe your EUID is being set. It's just not being set to the right interpretation of the number. I suggest you ponder this code:

        #!/usr/bin/perl -- use strict; use warnings; my $nobody = 4294967294; print $nobody . "\n"; $nobody = pack 'I', -2; $nobody = unpack 'I', $nobody; print $nobody . "\n";

        Christopher E. Stith
Re: EUID cannot be set
by AK108 (Friar) on May 10, 2007 at 03:18 UTC
    Your syntax for getting the variables is a bit odd. Shouldn't you be using something like this?
    sub DropPriv { my($uid, $groups) = @_; $) = $groups; $> = $uid; # ... }
      You are right, I rewrote the relevant bits from memory and messed it up a bit - but in real life it looks like yours.


Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://614493]
Approved by Corion
Front-paged by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (4)
As of 2022-06-24 23:06 GMT
Find Nodes?
    Voting Booth?
    My most frequent journeys are powered by:

    Results (80 votes). Check out past polls.