Front page | perl.perl5.porters |
Postings from October 2003
[perl #24122] setreuid and friends borked on darwin/osx
From:
perlbug-followup
Date:
October 5, 2003 16:00
Subject:
[perl #24122] setreuid and friends borked on darwin/osx
Message ID:
rt-24122-65678.14.2411168523081@rt.perl.org
# New Ticket Created by pxm@nubz.org
# Please include the string: [perl #24122]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=24122 >
This is a bug report for perl from pxm@nubz.org,
generated with the help of perlbug 1.34 running under perl v5.8.1.
-----------------------------------------------------------------
[Please enter your report here]
The library calls setruid, setrgid, setreuid, and setregid on
darwin (MacOS X) are severely broken, causing any attempt to
change $< or $( to fail silently.
This will cause problems in scripts that use those variables to
drop privileges. Either they'll die unpleasantly (if they properly
check $< afterwards) or they might gain a security vulnerability.
Scripts that use POSIX::setuid will be unaffected ofcourse.
The only solution I can think of is to make the configure script
pretend those four calls don't exist on darwin. Properly testing
whether they work would require root perms.
The kernel has no useful alternate calls to changing ruid/rgid..
the only calls actually available are set[gu]id and sete[gu]id.
For reference, here's how setreuid is implemented in darwin's libc,
which should make the problem painfully clear:
int
setreuid(ruid, euid)
uid_t ruid, euid;
{
static uid_t saveduid = -1;
if (saveduid == -1)
saveduid = geteuid();
/*
* we assume that the intent here is to be able to
* get back ruid priviledge. So we make sure that
* we will be able to do so, but do not actually
* set the ruid.
*/
if (ruid != -1 && ruid != getuid() && ruid != saveduid) {
errno = EPERM;
return (-1);
}
if (euid != -1 && seteuid(euid) < 0)
return (-1);
return (0);
}
setregid is equivalent. setr[ug]id are implemented as calls to
setre[gu]id with the e[gu]id argument set to -1.
To further add to the joy, setuid(x) fails if x != ruid && euid != 0,
which means that $< = $> doesn't work, only ($>,$<)=($uid,$uid) does
thanks to delay-magic.. a workaround (tested) for this:
--- mg.c.bak 2003-10-05 22:29:39.000000000 +0200
+++ mg.c 2003-10-05 22:32:49.000000000 +0200
@@ -2253,5 +2253,9 @@
#else
- if (PL_uid == PL_euid) /* special case $< = $> */
+ if (PL_uid == PL_euid) { /* special case $< = $> */
+#ifdef PERL_DARWIN
+ if (PL_uid != 0 && PerlProc_getuid() == 0)
+ (void)PerlProc_setuid(0);
+#endif
(void)PerlProc_setuid(PL_uid);
- else {
+ } else {
PL_uid = PerlProc_getuid();
<@woggle> xmath: Did Apple have some committee setup to break set*id()?
[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
category=core
severity=medium
---
Site configuration information for perl v5.8.1:
Configured by xmath at Sun Oct 5 19:54:59 CEST 2003.
Summary of my perl5 (revision 5.0 version 8 subversion 1) configuration:
Platform:
osname=darwin, osvers=6.6, archname=darwin
uname='darwin quoose.lan 6.6 darwin kernel version 6.6: thu may 1 21:48:54 pdt 2003; root:xnuxnu-344.34.obj~1release_ppc power macintosh powerpc '
config_args=''
hint=recommended, useposix=true, d_sigaction=define
usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='gcc-3.3', ccflags ='-g -pipe -fno-common -DPERL_DARWIN -no-cpp-precomp -fno-strict-aliasing -I/sw/include',
optimize='-Os -mcpu=750 -mtune=750',
cppflags='-g -pipe -fno-common -DPERL_DARWIN -no-cpp-precomp -fno-strict-aliasing -I/sw/include'
ccversion='', gccversion='3.3 20030304 (Apple Computer, Inc. build 1435)', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=4321
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=8
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='gcc-3.3', ldflags ='-L/sw/lib -flat_namespace'
libpth=/sw/lib /usr/lib
libs=-lgdbm -ldb -ldl -lSystem
perllibs=-ldl -lSystem
libc=/usr/lib/libSystem.dylib, so=dylib, useshrplib=false, libperl=libperl.a
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_dyld.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags=' -flat_namespace -bundle -undefined suppress -L/sw/lib'
Locally applied patches:
---
@INC for perl v5.8.1:
/sw/lib/perl5/5.8.1/darwin
/sw/lib/perl5/5.8.1
/sw/lib/perl5/darwin
/sw/lib/perl5/5.8.0/darwin
/sw/lib/perl5/5.8.0
/sw/lib/perl5
/sw/lib/perl5/5.8.1/darwin
/sw/lib/perl5/5.8.1
/sw/lib/perl5/site_perl/5.8.1/darwin
/sw/lib/perl5/site_perl/5.8.1
/sw/lib/perl5/site_perl/5.8.0/darwin
/sw/lib/perl5/site_perl/5.8.0
/sw/lib/perl5/site_perl
/Library/Perl/darwin
/Library/Perl
/System/Library/Perl/darwin
/System/Library/Perl
.
---
Environment for perl v5.8.1:
DYLD_LIBRARY_PATH (unset)
HOME=/Users/xmath
LANG=en_US
LANGUAGE (unset)
LC_ALL=C
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=/sw/bin:/sw/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/Developer/Tools
PERL5LIB=/sw/lib/perl5
PERL_BADLANG (unset)
SHELL=/bin/tcsh