-----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 <bamcc...@gmail.com> 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-----