Author: Armin Rigo <[email protected]>
Branch: sandbox-2
Changeset: r97105:8655e95a8718
Date: 2019-08-08 17:16 +0200
http://bitbucket.org/pypy/pypy/changeset/8655e95a8718/

Log:    When requested, dump compilation information, which the controller
        process can use to check for bad versions or missing functions

diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py
--- a/rpython/translator/c/genc.py
+++ b/rpython/translator/c/genc.py
@@ -928,6 +928,10 @@
     fi = incfilename.open('w')
     fi.write('#ifndef _PY_COMMON_HEADER_H\n#define _PY_COMMON_HEADER_H\n')
 
+    if database.sandbox:
+        from rpython.translator.sandbox import rsandbox
+        eci = eci.merge(rsandbox.extra_eci(database.translator.rtyper))
+
     #
     # Header
     #
diff --git a/rpython/translator/sandbox/rsandbox.py 
b/rpython/translator/sandbox/rsandbox.py
--- a/rpython/translator/sandbox/rsandbox.py
+++ b/rpython/translator/sandbox/rsandbox.py
@@ -4,6 +4,7 @@
 and wait for an answer on STDIN.  Enable with 'translate.py --sandbox'.
 """
 import py
+import sys
 
 from rpython.rlib import types
 from rpython.rlib.objectmodel import specialize
@@ -45,16 +46,28 @@
         return 'v'
 
 
-eci = rffi.ExternalCompilationInfo(separate_module_sources=[
+def extra_eci(rtyper):
+    from rpython.translator.c.support import c_string_constant
+
+    sandboxed_functions = getattr(rtyper, '_sandboxed_functions', [])
+    dump = (
+        "Version: 20001\n" +
+        "Platform: %s\n" % sys.platform +
+        "Funcs: %s" % ' '.join(sorted(sandboxed_functions))
+    )
+    dump = c_string_constant(dump).replace('\n', '\\\n')
+
+    return rffi.ExternalCompilationInfo(separate_module_sources=[
+            '#define RPY_SANDBOX_DUMP %s\n' % (dump,) +
             py.path.local(__file__).join('..', 'src', 'rsandbox.c').read(),
         ],
         post_include_bits=[
             py.path.local(__file__).join('..', 'src', 'rsandbox.h').read(),
         ])
+
 def external(funcname, ARGS, RESULT):
     return rffi.llexternal(funcname, ARGS, RESULT,
-                           compilation_info=eci, sandboxsafe=True,
-                           _nowrapper=True)
+                           sandboxsafe=True, _nowrapper=True)
 
 rpy_sandbox_arg = {
     'i': external('rpy_sandbox_arg_i', [lltype.UnsignedLongLong], lltype.Void),
@@ -89,7 +102,12 @@
     result_func = rpy_sandbox_res[result_kind]
     RESTYPE = FUNCTYPE.RESULT
 
+    try:
+        lst = rtyper._sandboxed_functions
+    except AttributeError:
+        lst = rtyper._sandboxed_functions = []
     name_and_sig = '%s(%s)%s' % (fnname, ''.join(arg_kinds), result_kind)
+    lst.append(name_and_sig)
     log(name_and_sig)
     name_and_sig = rffi.str2charp(name_and_sig, track_allocation=False)
 
diff --git a/rpython/translator/sandbox/src/rsandbox.c 
b/rpython/translator/sandbox/src/rsandbox.c
--- a/rpython/translator/sandbox/src/rsandbox.c
+++ b/rpython/translator/sandbox/src/rsandbox.c
@@ -1,6 +1,9 @@
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 #include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 
 #define RPY_SANDBOX_ARGBUF    512
@@ -11,6 +14,7 @@
 
 static char sand_argbuf[RPY_SANDBOX_ARGBUF];
 static size_t sand_nextarg = RPY_SANDBOX_NAMEMAX;
+static int sand_dump_checked = 0;
 
 
 static void sand_writeall(const char *buf, size_t count)
@@ -89,18 +93,39 @@
     *(void **)sand_arg_output(sizeof(void *)) = p;
 }
 
+static void sand_dump_check(void)
+{
+    const char *p = getenv("RPY_SANDBOX_DUMP");
+    if (p && p[0]) {
+        puts(RPY_SANDBOX_DUMP);
+        exit(0);
+    }
+    sand_dump_checked = 1;
+}
+
 struct sand_data_s {
     void *data;
     size_t size;
 };
 
+static void sand_assert(int condition)
+{
+    if (!condition) {
+        fprintf(stderr, "sandbox: internal assert failed\n");
+        abort();
+    }
+}
+
 static void sand_interact(const char *name_and_sig, char expected_result,
                           void *result, size_t result_size)
 {
     int saved_errno = errno;
 
+    if (!sand_dump_checked)
+        sand_dump_check();
+
     size_t name_len = strlen(name_and_sig);
-    assert(name_len > 0);
+    sand_assert(name_len > 0);
     if (name_len > RPY_SANDBOX_NAMEMAX - 1) {
         fprintf(stderr,
              "sandbox: function name buffer overflow (RPY_SANDBOX_NAMEMAX)\n");
@@ -110,8 +135,8 @@
     *p = name_len;
     memcpy(p + 1, name_and_sig, name_len);
 
-    assert(sand_nextarg >= RPY_SANDBOX_NAMEMAX);
-    assert(sand_nextarg <= RPY_SANDBOX_ARGBUF);
+    sand_assert(sand_nextarg >= RPY_SANDBOX_NAMEMAX);
+    sand_assert(sand_nextarg <= RPY_SANDBOX_ARGBUF);
 
     sand_writeall(p, sand_nextarg - (p - sand_argbuf));
     sand_nextarg = RPY_SANDBOX_NAMEMAX;
diff --git a/rpython/translator/sandbox/test/test_sandboxio.py 
b/rpython/translator/sandbox/test/test_sandboxio.py
--- a/rpython/translator/sandbox/test/test_sandboxio.py
+++ b/rpython/translator/sandbox/test/test_sandboxio.py
@@ -389,3 +389,17 @@
     out = os.path.join("tmp", "spam") + '\n'
     expect(sandio, "write(ipi)i", (1, RAW(out), len(out)), len(out))
     expect_done(sandio)
+
+def test_sandbox_dump():
+    def entry_point(argv):
+        print "hello world!\n"
+        os.close(42)
+        return 0
+
+    exe = compile(entry_point)
+    popen = subprocess.Popen([exe], stdout=subprocess.PIPE,
+                             env={"RPY_SANDBOX_DUMP": "1"})
+    dump = popen.stdout.read()
+    popen.wait()
+    assert dump == ("Version: 20001\nPlatform: %s\n" % (sys.platform,) +
+                    "Funcs: close(i)i write(ipi)i\n")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to