[Python-checkins] r50627 - python/branches/bcannon-sandboxing/Modules/sandboxmodule.c

brett.cannon python-checkins at python.org
Fri Jul 14 00:51:43 CEST 2006


Author: brett.cannon
Date: Fri Jul 14 00:51:43 2006
New Revision: 50627

Modified:
   python/branches/bcannon-sandboxing/Modules/sandboxmodule.c
Log:
Add tp_dealloc and tp_new implementations.


Modified: python/branches/bcannon-sandboxing/Modules/sandboxmodule.c
==============================================================================
--- python/branches/bcannon-sandboxing/Modules/sandboxmodule.c	(original)
+++ python/branches/bcannon-sandboxing/Modules/sandboxmodule.c	Fri Jul 14 00:51:43 2006
@@ -1,21 +1,82 @@
 #include "Python.h"
+#include "structmember.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/*
+   Destroy the sandboxed interpreter and dealloc memory.
+*/
+static void
+sandbox_dealloc(PyObject *self)
+{
+    PyThreadState *sand_tstate = NULL;
+    PyThreadState *cur_tstate = NULL;
+
+    /* To destory an interpreter using Py_EndInterpreter() it must be the
+       currently running interpreter.  This means you must temporariy make the
+       sanboxed interpreter the running interpreter again, destroy it, and then
+       swap back to the interpreter that created the interpreter in the first
+       place. */
+    sand_tstate = ((PySandboxObject *)self)->tstate;
+    cur_tstate = PyThreadState_Swap(sand_tstate);
+
+    Py_EndInterpreter(sand_tstate);
+    PyEval_RestoreThread(cur_tstate);
+
+    /* XXX need to do any special memory dealloc for sandboxed interpreter? */
+    self->ob_type->tp_free(self);
+}
+
+/*
+   Create new sandboxed interpreter.
+   XXX Might be better to wait until actual execution occurs to create the interpreter.  Would make these objects one-offs, but could then change this to a function instead where you pass in the needed arguments to handle everything (which is fine since object-capabilities puts the security into __builtins__ and thus only need that)).
+   XXX Could also create thread/interpreter from scratch and avoid all of this swapping of thread states (would need to do initialization that Py_NewInterpreter() did, though). */
+static PyObject *
+sandbox_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PySandboxObject *self;
+    PyThreadState *cur_tstate;
+
+    self = (PySandboxObject *)type->tp_alloc(type, 0);
+    if (self == NULL)
+	return NULL;
+
+    /* Creating a new interpreter swaps out the current one. */
+    cur_tstate = PyThreadState_GET();
+
+    /* XXX chang eto call PySandbox_NewInterpreter() */
+    if (Py_NewInterpreter() == NULL) {
+	Py_DECREF(self);
+	/* XXX SandboxError best exception to use here? */
+	PyErr_SetString(PyExc_SandboxError, "sub-interpreter creation failed");
+	return NULL;
+    }
+
+    self->tstate = PyThreadState_Swap(cur_tstate);
+    if (self->tstate == NULL) {
+	Py_DECREF(self);
+	PyErr_SetString(PyExc_SandboxError, "sub-interpreter swap failed");
+	return NULL;
+    }
+
+    return (PyObject *)self;
+}
+
+
 PyDoc_STRVAR(sandbox_type_doc,
 "XXX\n\
 \n\
 XXX");
 
 PyTypeObject PySandbox_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
+	PyObject_HEAD_INIT(NULL)
 	0,					/* ob_size */
 	"sandbox.Sandbox",			/* tp_name */
 	sizeof(PySandboxObject),		/* tp_basicsize */
 	0,               			/* tp_itemsize */
-	0,                      		/* tp_dealloc */
+	sandbox_dealloc,                      	/* tp_dealloc */
 	0,					/* tp_print */
 	0,			 		/* tp_getattr */
 	0,					/* tp_setattr */
@@ -30,7 +91,8 @@
 	0,                      		/* tp_getattro */
 	0,	                        	/* tp_setattro */
 	0,					/* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT,     		/* tp_flags */
+	Py_TPFLAGS_DEFAULT |
+	    Py_TPFLAGS_BASETYPE,     		/* tp_flags */
 	sandbox_type_doc,    			/* tp_doc */
 	0,                      		/* tp_traverse */
 	0,              			/* tp_clear */
@@ -48,7 +110,7 @@
 	0,                              	/* tp_dictoffset */
 	0,					/* tp_init */
 	0,					/* tp_alloc */
-	0,      				/* tp_new */
+	sandbox_new,     			/* tp_new */
 	0,                      		/* tp_free */
 	0,              			/* tp_is_gc */
 };
@@ -64,7 +126,7 @@
     if (module == NULL)
 	return;
 
-    PySandbox_Type.tp_new = PyType_GenericNew;
+    Py_INCREF(&PySandbox_Type);
     if (PyType_Ready(&PySandbox_Type) < 0)
 	return;
 


More information about the Python-checkins mailing list