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