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

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

Thread Next
From:
Garry T. Williams
Date:
September 4, 2000 09:09
Subject:
[ID 20000904.005] POSIX::setuid() Doesn't Call setuid()
Message ID:
200009041609.e84G9iN12155@ifr.inside.zvolve.net

This is a bug report for perl from garry@zvolve.com,
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 POSIX.pm 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/setuid.al", 0x0010E0C0) = 0
	open64("/usr/local/lib/perl5/5.6.0/sun4-solaris/auto/POSIX/setuid.al", 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]
	getcontext(0xFFBEF868)
	setcontext(0xFFBEF868)
	llseek(0, 0, SEEK_CUR)                          = 1676894
	_exit(0)
	$

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): 

	DESCRIPTION
	     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
comparison: 

	$ cat test
	#!/usr/local/bin/perl -w
	use POSIX qw(setuid);
	print "1: uid=$<, euid=$>\n";
	setuid(100);
	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());
	    setuid(getuid());
	    printf("2: uid=%d, euid=%d\n", getuid(), geteuid());
	    exit(0);
	}
	$ 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]
-----------------------------------------------------------------
---
Flags:
    category=core
    severity=low
---
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:
  Platform:
    osname=solaris, osvers=2.7, archname=sun4-solaris
    uname='sunos repos 5.7 generic_106541-11 sun4u sparc sunw,ultra-60 '
    config_args=''
    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
  Compiler:
    cc='cc', optimize='-O', gccversion=
    cppflags='-I/usr/local/include'
    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/libc.so, 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:
    /usr/local/lib/perl5/5.6.0/sun4-solaris
    /usr/local/lib/perl5/5.6.0
    /usr/local/lib/perl5/site_perl/5.6.0/sun4-solaris
    /usr/local/lib/perl5/site_perl/5.6.0
    /usr/local/lib/perl5/site_perl
    .

---
Environment for perl v5.6.0:
    HOME=/home/garry
    LANG (unset)
    LANGUAGE (unset)
    LC_COLLATE=C
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/garry/bin:/bin:/sbin:/usr/sbin:/opt/SUNWspro/bin:/usr/ccs/bin:/usr/local/bin:/usr/openwin/bin:/usr/java1.1/bin
    PERL_BADLANG (unset)
    SHELL=/bin/ksh


Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About