summaryrefslogtreecommitdiff
path: root/pp_hot.c
diff options
context:
space:
mode:
authorÆvar Arnfjörð Bjarmason <avar@cpan.org>2012-02-12 18:56:35 +0000
committerÆvar Arnfjörð Bjarmason <avar@cpan.org>2012-02-18 23:39:38 +0000
commit985213f2fede57896814a0d7f5d12b04cc05be5b (patch)
treedba5979a55b4d6a426815d208821d5a0fdf6fa06 /pp_hot.c
parentf0bcc49ad675e0a60f19580435d94bbee904084d (diff)
downloadperl-985213f2fede57896814a0d7f5d12b04cc05be5b.tar.gz
Remove gete?[ug]id caching
Currently we cache the UID/GID and effective UID/GID similarly to how we used to cache getpid() before v5.14.0-251-g0e21945. Remove this magical behavior in favor of always calling getpid(), getgid() etc. This resolves RT #96208. A minimal testcase for this is the following by Leon Timmermans attached to RT #96208: eval { require 'syscall.ph'; 1 } or eval { require 'sys/syscall.ph'; 1 } or die $@; if (syscall(&SYS_setuid, $ARGV[0] + 0 || 1000) >= 0 or die "$!") { printf "\$< = %d, getuid = %d\n", $<, syscall(&SYS_getuid); } I.e. if we call the sete?[ug]id() functions unbeknownst to perl the $<, $>, $( and $) variables won't be updated. This results in the same sort of issues we had with $$ before v5.14.0-251-g0e21945, and getppid() before my v5.15.7-407-gd7c042c patch. I'm completely eliminating the PL_egid, PL_euid, PL_gid and PL_uid variables as part of this patch, this will break some CPAN modules, but it'll be really easy before the v5.16.0 final to reinstate them. I'd like to remove them to see what breaks, and how easy it is to fix it. These variables are not part of the public API, and the modules using them could either use the Perl_gete?[ug]id() functions or are working around the bug I'm fixing with this commit. The new PL_delaymagic_(egid|euid|gid|uid) variables I'm adding are *only* intended to be used internally in the interpreter to facilitate the delaymagic in Perl_pp_sassign. There's probably some way not to export these to programs that embed perl, but I haven't found out how to do that.
Diffstat (limited to 'pp_hot.c')
-rw-r--r--pp_hot.c48
1 files changed, 27 insertions, 21 deletions
diff --git a/pp_hot.c b/pp_hot.c
index f63164012a..6bf5a741a1 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1091,71 +1091,77 @@ PP(pp_aassign)
}
}
if (PL_delaymagic & ~DM_DELAY) {
+ /* Will be used to set PL_tainting below */
+ UV tmp_uid = PerlProc_getuid();
+ UV tmp_euid = PerlProc_geteuid();
+ UV tmp_gid = PerlProc_getgid();
+ UV tmp_egid = PerlProc_getegid();
+
if (PL_delaymagic & DM_UID) {
#ifdef HAS_SETRESUID
- (void)setresuid((PL_delaymagic & DM_RUID) ? PL_uid : (Uid_t)-1,
- (PL_delaymagic & DM_EUID) ? PL_euid : (Uid_t)-1,
+ (void)setresuid((PL_delaymagic & DM_RUID) ? PL_delaymagic_uid : (Uid_t)-1,
+ (PL_delaymagic & DM_EUID) ? PL_delaymagic_euid : (Uid_t)-1,
(Uid_t)-1);
#else
# ifdef HAS_SETREUID
- (void)setreuid((PL_delaymagic & DM_RUID) ? PL_uid : (Uid_t)-1,
- (PL_delaymagic & DM_EUID) ? PL_euid : (Uid_t)-1);
+ (void)setreuid((PL_delaymagic & DM_RUID) ? PL_delaymagic_uid : (Uid_t)-1,
+ (PL_delaymagic & DM_EUID) ? PL_delaymagic_euid : (Uid_t)-1);
# else
# ifdef HAS_SETRUID
if ((PL_delaymagic & DM_UID) == DM_RUID) {
- (void)setruid(PL_uid);
+ (void)setruid(PL_delaymagic_uid);
PL_delaymagic &= ~DM_RUID;
}
# endif /* HAS_SETRUID */
# ifdef HAS_SETEUID
if ((PL_delaymagic & DM_UID) == DM_EUID) {
- (void)seteuid(PL_euid);
+ (void)seteuid(PL_delaymagic_euid);
PL_delaymagic &= ~DM_EUID;
}
# endif /* HAS_SETEUID */
if (PL_delaymagic & DM_UID) {
- if (PL_uid != PL_euid)
+ if (PL_delaymagic_uid != PL_delaymagic_euid)
DIE(aTHX_ "No setreuid available");
- (void)PerlProc_setuid(PL_uid);
+ (void)PerlProc_setuid(PL_delaymagic_uid);
}
# endif /* HAS_SETREUID */
#endif /* HAS_SETRESUID */
- PL_uid = PerlProc_getuid();
- PL_euid = PerlProc_geteuid();
+ tmp_uid = PerlProc_getuid();
+ tmp_euid = PerlProc_geteuid();
}
if (PL_delaymagic & DM_GID) {
#ifdef HAS_SETRESGID
- (void)setresgid((PL_delaymagic & DM_RGID) ? PL_gid : (Gid_t)-1,
- (PL_delaymagic & DM_EGID) ? PL_egid : (Gid_t)-1,
+ (void)setresgid((PL_delaymagic & DM_RGID) ? PL_delaymagic_gid : (Gid_t)-1,
+ (PL_delaymagic & DM_EGID) ? PL_delaymagic_egid : (Gid_t)-1,
(Gid_t)-1);
#else
# ifdef HAS_SETREGID
- (void)setregid((PL_delaymagic & DM_RGID) ? PL_gid : (Gid_t)-1,
- (PL_delaymagic & DM_EGID) ? PL_egid : (Gid_t)-1);
+ (void)setregid((PL_delaymagic & DM_RGID) ? PL_delaymagic_gid : (Gid_t)-1,
+ (PL_delaymagic & DM_EGID) ? PL_delaymagic_egid : (Gid_t)-1);
# else
# ifdef HAS_SETRGID
if ((PL_delaymagic & DM_GID) == DM_RGID) {
- (void)setrgid(PL_gid);
+ (void)setrgid(PL_delaymagic_gid);
PL_delaymagic &= ~DM_RGID;
}
# endif /* HAS_SETRGID */
# ifdef HAS_SETEGID
if ((PL_delaymagic & DM_GID) == DM_EGID) {
- (void)setegid(PL_egid);
+ (void)setegid(PL_delaymagic_egid);
PL_delaymagic &= ~DM_EGID;
}
# endif /* HAS_SETEGID */
if (PL_delaymagic & DM_GID) {
- if (PL_gid != PL_egid)
+ if (PL_delaymagic_gid != PL_delaymagic_egid)
DIE(aTHX_ "No setregid available");
- (void)PerlProc_setgid(PL_gid);
+ (void)PerlProc_setgid(PL_delaymagic_gid);
}
# endif /* HAS_SETREGID */
#endif /* HAS_SETRESGID */
- PL_gid = PerlProc_getgid();
- PL_egid = PerlProc_getegid();
+ tmp_gid = PerlProc_getgid();
+ tmp_egid = PerlProc_getegid();
}
- PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
+ PL_tainting |= (tmp_uid && (tmp_euid != tmp_uid || tmp_egid != tmp_gid));
}
PL_delaymagic = 0;