Interesting Perl Bug

(You can suggest changes to this post.)

Interesting Perl Bug
To see an interesting bug which caused me many headaches, enter the following script, and mark it setuid. Then run it as any other user except the owner.
#!/usr/bin/perl -wT
$ENV{PATH} = "";
print "Hello World\n";
system($0,"1") unless @ARGV;

The result is a delightful message about how your kernel has a setuid script bug which is rather dangerous and easy to exploit... except that you don't

Perl is just getting confused because it looks like the interpretor has been started setuid before it's had a chance to do sanity checking and invoke suidperl. The result is the inability to have a setuid script invoke itself. Very bothersome.

The solution is to drop setuid privileges before the script calls itself again. Conveniently enough, Perl allows us to localise $> (effective UID), so the following program does work as intended:

#!/usr/bin/perl -wT
$ENV{PATH} = "";
print "Hello World\n";
unless (@ARGV) {local $> = $<; system($0,"1");}

Because of the use of local, setuid privileges are only dropped for the duration of the call to system. Of course, it's usually a good idea to drop setuid privileges as soon as possible, or only invoke them when you absolutely have to.

Bitcoin QR code This site is ad-free, and all text, style, and code may be re-used under a Creative Commons Attribution 3.0 license. If like what I do, please consider supporting me on Patreon, or donating via Bitcoin (1P9iGHMiQwRrnZuA6USp5PNSuJrEcH411f).

comments powered by Disqus