develooper Front page | perl.perl5.porters | Postings from September 2000

[ID 20000904.005] POSIX::setuid() Doesn't Call setuid()

Thread Next
Garry T. Williams
September 4, 2000 09:09
[ID 20000904.005] POSIX::setuid() Doesn't Call setuid()
Message ID:

This is a bug report for perl from,
generated with the help of perlbug 1.28 running under perl v5.6.0.

[Please enter your report here]

The POSIX::setuid() function does not call setuid() on this system.
From the module: 

	sub setuid {
	    usage "setuid(uid)" if @_ != 1;
	    $< = $_[0];

I ran a test with truss and this results in a call to setreuid() --
not setuid(): 

	$ truss perl -MPOSIX -e 'POSIX::setuid(100);'
	execve("/usr/local/bin/perl", 0xFFBEFC8C, 0xFFBEFCA0)  argc = 4
	stat64("/usr/local/lib/perl5/5.6.0/sun4-solaris/auto/POSIX/", 0x0010E0C0) = 0
	open64("/usr/local/lib/perl5/5.6.0/sun4-solaris/auto/POSIX/", O_RDONLY) = 3
	fstat64(3, 0xFFBEEFB0)                          = 0
	ioctl(3, TCGETA, 0xFFBEEF3C)                    Err#25 ENOTTY
	read(3, " #   N O T E :   D e r i".., 8192)     = 305
	read(3, 0x0012100C, 8192)                       = 0
	llseek(3, 0, SEEK_CUR)                          = 305
	close(3)                                        = 0
-->	setreuid(100, -1)                               = 0
	getuid()                                        = 100 [100]
	llseek(0, 0, SEEK_CUR)                          = 1676894

While this has the effect of changing the saved UID, it does *not*
change the effective UID.  From the Solaris manual page for setuid(2): 

	     The setuid() function sets the real user ID, effective  user
	     ID,  and  saved user ID of the calling process. 

So, if my intention was to relinquish privileges, the effective UID is
still unchanged.  If I read the manual page for setuid(2), I conclude
(incorrectly) that this is sufficient to drop privileges.  Here's a

	$ cat test
	#!/usr/local/bin/perl -w
	use POSIX qw(setuid);
	print "1: uid=$<, euid=$>\n";
	print "2: uid=$<, euid=$>\n";
	exit 0;
	$ ls -l test
	-rwsr-xr-x   1 root     staff        128 Sep  4 11:52 test*
	$ ./test
	1: uid=100, euid=0
-->	2: uid=100, euid=0
	$ cat test.c
	#include <stdio.h>
	int main() {
	    printf("1: uid=%d, euid=%d\n", getuid(), geteuid());
	    printf("2: uid=%d, euid=%d\n", getuid(), geteuid());
	$ sudo cc -o test_c test.c
	$ sudo chmod 04755 test_c
	$ ls -l test_c
	-rwsr-xr-x   1 root     staff       6268 Sep  4 11:53 test_c*
	$ ./test_c
	1: uid=100, euid=0
-->	2: uid=100, euid=100

After some experimentation, it seems that the way to drop privileges
on this system is to do the following in Perl: 

	$> = $id;
	$< = $id;

This is effective, but it is far from obvious.  

I have submitted a bug report regarding the perlsec manual page that I
believe would help to clear up this question.  However, it is still
the case that the POSIX::setuid() function does not call setuid().  

-Garry Williams

[Please do not change anything below this line]
Site configuration information for perl v5.6.0:

Configured by garry at Tue Aug  1 07:40:52 EDT 2000.

Summary of my perl5 (revision 5.0 version 6 subversion 0) configuration:
    osname=solaris, osvers=2.7, archname=sun4-solaris
    uname='sunos repos 5.7 generic_106541-11 sun4u sparc sunw,ultra-60 '
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
    useperlio=undef d_sfio=undef uselargefiles=define 
    use64bitint=undef use64bitall=undef uselongdouble=undef usesocks=undef
    cc='cc', optimize='-O', gccversion=
    ccflags ='-I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
    stdchar='char', d_stdstdio=define, usevfork=false
    intsize=4, longsize=4, ptrsize=4, doublesize=8
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, usemymalloc=y, prototype=define
  Linker and Libraries:
    ld='cc', ldflags ='-L/usr/local/lib '
    libpth=/usr/local/lib /opt/SUNWspro/SC5.0/lib /lib /usr/lib /usr/ccs/lib
    libs=-lsocket -lnsl -ldb -ldl -lm -lc -lcrypt -lsec
    libc=/lib/, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' '
    cccdlflags='-KPIC', lddlflags='-G -L/usr/local/lib'

Locally applied patches:

@INC for perl v5.6.0:

Environment for perl v5.6.0:
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PERL_BADLANG (unset)

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About