After short testing I found a bug or at least a dangerous pitfall.
This leaves a backdoor open (probably in the saved UID):
#!/usr/bin/perl -wT
use strict;
require POSIX;
sub ids () { print "RUID=$< EUID=$> RGID=$( EGID=$)\n" }
print "Running $^X $0\n";
ids;
$> = $< = $<;
ids;
$> = $< = 0;
ids;
======= OUTPUT: ========
Running /usr/bin/perl /dev/fd/3
RUID=1000 EUID=0 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9 117 501 1001
RUID=1000 EUID=1000 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9 117 501 1001
RUID=0 EUID=0 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9 117 501 1001
While this drops privileges permanently:
#!/usr/bin/perl -wT
use strict;
require POSIX;
sub ids () { print "RUID=$< EUID=$> RGID=$( EGID=$)\n" }
print "Running $^X $0\n";
ids;
$< = $> = $<;
ids;
$> = $< = 0;
ids;
======= OUTPUT: ========
Running /usr/bin/perl /dev/fd/3
RUID=1000 EUID=0 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9 117 501 1001
RUID=1000 EUID=1000 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9 117 501 1001
RUID=1000 EUID=1000 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9 117 501 1001
Backdoor is still open when doing "$> = $< = 1000" or
"$< = 1000; $> = 1000;". POSIX::setuid($<) works fine.