Why does @INC change when setgid-bit of C wrapper

2019-06-18 09:48发布

问题:

This is all on RHEL6

I am trying to run a perl script as a specific user (owner of the perl script) by wrapping it inside a C binary and then setting the setgid bit of the binary (ref: https://superuser.com/questions/440363/can-i-make-a-script-always-execute-as-root). The perl script uses various perl modules. If the perl modules are in PERL5LIB of the account trying to run the C binary, and the setgid-bit is NOT set on the C binary, it runs fine. If the setgid-bit IS set, then it fails because the used perl modules are not in @INC.

Some code to demo how @INC changes with the sticky bit...

the.pl

#!/usr/bin/env perl
print "Size of INC: ".scalar(@INC)."\n";
exit;

wrapper.c

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  exit(execvp("/home/me/the.pl",(char **)argv));
}

The perl script permissions are -rwxrwxr-x

When I set the wrapper's permissions to -rwxr-xr-x (note the setgid bit is not set), then run the binary from some other account, I get...

Size of INC = 87

...which is what I would expect (there are 87 elements in PERL5LIB).

But when I set the wrapper's permissions to -rwxr-sr-x (note the setgid bit is set), then run the binary from some other account, I get...

Size of INC = 4

I get the same results even if I load PERL5LIB with all 87 elements in the .cshrc of both the perl script's owner and that of the account that's running the wrapper.

I need to run the binary as the owner of the perl script because that account has a priv that the user's accounts don't have. The root user is not a player in any of this.

Why am I losing those PERL5LIB elements? Is there a way I can get around this ?

Thanks in Advance!

回答1:

A setuid perl script is run in taint mode, and perlsec says:

When the taint mode ("-T") is in effect, the "." directory is removed from @INC, and the environment variables "PERL5LIB" and "PERLLIB" are ignored by Perl. You can still adjust @INC from outside the program by using the "-I" command line option as explained in perlrun. The two environment variables are ignored because they are obscured, and a user running a program could be unaware that they are set, whereas the "-I" option is clearly visible and therefore permitted.

If you cannot adjust @INC inside the program (say, with use lib ...), you will want to rewrite your C program to call the perl executable instead of your script name, and to prepend argv with your script name and any appropriate -I... arguments that you want to use.