summaryrefslogtreecommitdiff
path: root/src/pl/plperl/sql
diff options
context:
space:
mode:
authorAndrew Dunstan <andrew@dunslane.net>2010-05-13 16:43:14 +0000
committerAndrew Dunstan <andrew@dunslane.net>2010-05-13 16:43:14 +0000
commit64a42a2af8df2e325a23bf0381966ada0fe0a4bd (patch)
tree2ec41db18db44c08747e678ed87eb79636e1a71c /src/pl/plperl/sql
parenta68abcaacc7a516c547525ce694c87ca4d3d86a9 (diff)
Abandon the use of Perl's Safe.pm to enforce restrictions in plperl, as it is
fundamentally insecure. Instead apply an opmask to the whole interpreter that imposes restrictions on unsafe operations. These restrictions are much harder to subvert than is Safe.pm, since there is no container to be broken out of. Backported to release 7.4. In releases 7.4, 8.0 and 8.1 this also includes the necessary backporting of the two interpreters model for plperl and plperlu adopted in release 8.2. In versions 8.0 and up, the use of Perl's POSIX module to undo its locale mangling on Windows has become insecure with these changes, so it is replaced by our own routine, which is also faster. Nice side effects of the changes include that it is now possible to use perl's "strict" pragma in a natural way in plperl, and that perl's $a and $b variables now work as expected in sort routines, and that function compilation is significantly faster. Tim Bunce and Andrew Dunstan, with reviews from Alex Hunsaker and Alexey Klyukin. Security: CVE-2010-1169
Diffstat (limited to 'src/pl/plperl/sql')
-rw-r--r--src/pl/plperl/sql/plperl.sql5
-rw-r--r--src/pl/plperl/sql/plperlu_plperl.sql53
2 files changed, 58 insertions, 0 deletions
diff --git a/src/pl/plperl/sql/plperl.sql b/src/pl/plperl/sql/plperl.sql
index e312cd24dc0..27c89c625bb 100644
--- a/src/pl/plperl/sql/plperl.sql
+++ b/src/pl/plperl/sql/plperl.sql
@@ -337,3 +337,8 @@ CREATE OR REPLACE FUNCTION perl_spi_prepared_set(INTEGER, INTEGER) RETURNS SETOF
$$ LANGUAGE plperl;
SELECT * from perl_spi_prepared_set(1,2);
+--
+-- Test detection of unsafe operations
+CREATE OR REPLACE FUNCTION perl_unsafe1() RETURNS void AS $$
+ my $fd = fileno STDERR;
+$$ LANGUAGE plperl;
diff --git a/src/pl/plperl/sql/plperlu_plperl.sql b/src/pl/plperl/sql/plperlu_plperl.sql
new file mode 100644
index 00000000000..6bd1a317c85
--- /dev/null
+++ b/src/pl/plperl/sql/plperlu_plperl.sql
@@ -0,0 +1,53 @@
+--
+-- Test that recursing between plperl and plperlu doesn't allow plperl to perform unsafe ops
+--
+
+-- recurse between a plperl and plperlu function that are identical except that
+-- each calls the other. Each also checks if an unsafe opcode can be executed.
+
+CREATE OR REPLACE FUNCTION recurse_plperl(i int) RETURNS SETOF TEXT LANGUAGE plperl
+AS $$
+ my $i = shift;
+ return unless $i > 0;
+ return_next "plperl $i entry: ".((eval "stat;1") ? "ok" : $@);
+ return_next $_
+ for map { $_->{recurse_plperlu} }
+ @{spi_exec_query("select * from recurse_plperlu($i-1)")->{rows}};
+ return;
+$$;
+
+CREATE OR REPLACE FUNCTION recurse_plperlu(i int) RETURNS SETOF TEXT LANGUAGE plperlu
+AS $$
+ my $i = shift;
+ return unless $i > 0;
+ return_next "plperlu $i entry: ".((eval "stat;1") ? "ok" : $@);
+ return_next $_
+ for map { $_->{recurse_plperl} }
+ @{spi_exec_query("select * from recurse_plperl($i-1)")->{rows}};
+ return;
+$$;
+
+SELECT * FROM recurse_plperl(5);
+SELECT * FROM recurse_plperlu(5);
+
+--
+-- Make sure we can't use/require things in plperl
+--
+
+CREATE OR REPLACE FUNCTION use_plperlu() RETURNS void LANGUAGE plperlu
+AS $$
+use Errno;
+$$;
+
+CREATE OR REPLACE FUNCTION use_plperl() RETURNS void LANGUAGE plperl
+AS $$
+use Errno;
+$$;
+
+-- make sure our overloaded require op gets restored/set correctly
+select use_plperlu();
+
+CREATE OR REPLACE FUNCTION use_plperl() RETURNS void LANGUAGE plperl
+AS $$
+use Errno;
+$$;