-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Hello Brandon.
Thanks for your reply.
> I think that the first part that you're having trouble with is
> sharing data (or code) with the "compartment". I think that if
> you want for $anon_func to be available to the Safe compartment,
> and therefore the untrusted_script.pl when executed with the Safe
> compartment, you need to pass the name of the anonymous function
> variable instead of the variable itself.
Yes you're right.
> It also appears that you cannot share lexical variables with
> these compartments (see perldoc Safe) so you need to make
> $anon_func a package variable (or copy it to one).
Once again you're right.
I was able to fix my example:
### Example.pl
use strict;
use warnings;
use Safe;
use 5.020;
my $UNTRUSTED_SCRIPT="untrusted_script.pl";
sub run_me{
my $sandbox = Safe->new("Sandbox");
$sandbox->permit(qw(:base_core :base_loop :base_mem :base_io :load
:base_orig));
our $operation = "Dangerous";
sub anon_func{
my $param = shift;
print "$operation $param operation!\n";
}
$sandbox->share('&anon_func');
$sandbox->rdo($UNTRUSTED_SCRIPT);
if ($@) {
say "Erro! $@";
}
$sandbox->reval('func1()');
}
run_me();
### untrusted_script.pl
use 5.020;
use warnings;
sub func1{
say "About to run shared function!";
anon_func("func1");
}
######
The output is what i was expecting:
$ perl Example.pl
About to run shared function!
Dangerous func1 operation!
Thanks Brandon for your help.
Best regards,
David Santiago
Em Sun, 28 Dec 2014 16:35:50 -0500
Brandon McCaig <[email protected]> escreveu:
> David:
>
> On Sun, Dec 28, 2014 at 07:35:14PM +0100, David Emanuel da Costa
> Santiago wrote:
> > Hello!
>
> Hello,
>
> > How do i run and pass arguments to an anonymous subroutine that i
> > shared on a safe compartment?
> >
> > My goal is to have a function that perform "dangerous" operations,
> > that must be available to untrusted code, however this function
> > needs some parameters that are only available when the code is
> > executing, and the untrusted code doesn't know them (hence the
> > anonymous subroutine).
> >
> > Example (35 lines):
> >
> > ### Example.pl file
> > use strict;
> > use warnings;
> > use Safe;
> > use 5.020;
> >
> > my $UNTRUSTED_SCRIPT="untrusted_script.pl";
> >
> > sub run_me{
> >
> > my $sandbox = Safe->new("Sandbox");
> > $sandbox->permit(qw(:base_core :base_loop :base_mem :base_io :load
> > :base_orig));
> > $sandbox->deny(qw(die exit));
> >
> > my $operation = "Dangerous";
> >
> > my $anon_func = sub{
> > my $param = shift;
> > print "$operation $param operation!\n";
> > };
> >
> > $sandbox->share($anon_func);
> > $sandbox->rdo($UNTRUSTED_SCRIPT);
> > $sandbox->reval('func1()');
> > }
> >
> > run_me();
> >
> > ### untrusted_script.pl
> > use 5.020;
> > use warnings;
> > use utf8;
> >
> >
> > sub func1{
> > say "About to run shared function!";
> > $anon_func->("func1");
> > }
> >
> > ######
> >
> > The output of the Example.pl script is:
> >
> > Error while executing the sandbox: Global symbol "$anon_func"
> > requires explicit package name at untrusted_script.pl line 5.
> >
> > I was expecting of the output of the Example.pl script to be
> > "Dangerous func1 operation!". What am i doing wrong?
>
> I am not familiar with Safe.pm so I don't know anything about
> that, but $anon_func is a lexically scoped variable in
> Example.pl. That variable is not available within the
> untrusted_script.pl file. I also don't see a subroutine or
> anything at all named "func1" defined so I can't imagine how
> $sandbox->reval('func1()') is supposed to work.
>
> I think that the first part that you're having trouble with is
> sharing data (or code) with the "compartment". I think that if
> you want for $anon_func to be available to the Safe compartment,
> and therefore the untrusted_script.pl when executed with the Safe
> compartment, you need to pass the name of the anonymous function
> variable instead of the variable itself.
>
> $sandbox->share('$anon_func');
>
> It also appears that you cannot share lexical variables with
> these compartments (see perldoc Safe) so you need to make
> $anon_func a package variable (or copy it to one). A named
> function would work too. So either:
>
> our $anon_func = sub { ... };
>
> ...
>
> $sandbox->share('$anon_func');
>
> Or else:
>
> sub shared_func = sub { ... };
>
> ...
>
> $sandbox->share('&shared_func');
>
> A bareword passed to Safe::share is apparently assumed to be a
> named function too. You can also use Safe::share_from to share a
> subroutine from a different package than the caller.
>
> I worked out a little contrived example to figure this out
> myself:
>
> ./program:
> #!/usr/bin/env perl
>
> use strict;
> use warnings;
>
> use Safe;
>
> my $sandbox = Safe->new();
> $sandbox->permit(qw/print/);
>
> # Shared variables cannot be lexicals!
> our $get_id = do {
> my $id = 0;
>
> sub {
> my ($base) = @_;
> my $result = "${base}${id}";
>
> ++$id;
>
> return $result;
> };
> };
>
> $sandbox->share('$get_id');
>
> $sandbox->rdo('unsafe') or die $!;
>
> __END__
>
> ./unsafe:
> my $id = $get_id->("foo_");
>
> print "Unsafe script got id $id!\n";
>
> __END__
>
> Output should be:
>
> $ ./program
> Unsafe script got id foo_0!
>
> Regards,
>
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
iQIcBAEBCAAGBQJUoIFSAAoJEP84J6veUQ8l1HEP/2oDeyVM1BpI2xjoFsG+tyOt
p5uYDALp7wQFUtwzKFuEE/tAJvrDn7OmZ5YyWF725C45o1ji/oddY08ME0ipKKeE
AMI4yLtdiI2Rs4uMHGs/o04clIIOjJpPoMb3JlpXiMYXECu1JRQv6EMh/cu+xwWs
2lIgQjytYj040RRhbqRV9+yst7JrIlEAClK990VI+Gj2zoLpRPeOaewxdNZ4SuK2
ev3Kz7rb8xiEyB3ZxdGISGir/ISIq+ini9Svotz/kEec1lxjNJLK0hmfDAKo9Imr
EQp2KmPNPClYno84ozoxKXnMy08IWyN41IFk7bU4Et2kfd2taw4AH6AhL5bpB0hE
z/xS4zNVygX82THuVLWxuCiGyLzBbKYElOthjCBM8hxJNMLIECfAFzcOzT8aRF+5
5cz9JomZX7DLvasd94p60bXEkmAMxwfAb7y4R38xZsClW7jMFLHeiwWP1OdMMsW5
iAvAfeKBVUO+5idKA0ca08G7bjdckMIRnQPTrU8zEMvBs01yJRSu28mEOYg1YRRx
f3SEqsBWD8tBaz+sCgtarFYbZZFslsVyl9MuA3zqNyvknbQwRuJa+203diJcItuT
2MnuwmPxnhq7tNJOjEt0PutozAv2O/xYlWsnFuyDn9JrC+k5S4LSyiVxBwYlMhmk
pIbMAPH1x3sZoPYzW7Wg
=bu7m
-----END PGP SIGNATURE-----