[Python-checkins] r50566 - in python/branches/bcannon-sandboxing: Include/Python.h Include/sandbox.h Python/sandbox.c

brett.cannon python-checkins at python.org
Tue Jul 11 03:33:55 CEST 2006


Author: brett.cannon
Date: Tue Jul 11 03:33:53 2006
New Revision: 50566

Modified:
   python/branches/bcannon-sandboxing/Include/Python.h
   python/branches/bcannon-sandboxing/Include/sandbox.h
   python/branches/bcannon-sandboxing/Python/sandbox.c
Log:
Initial implementation of memory cap.  No testing other than working in an unprotected interpreter.


Modified: python/branches/bcannon-sandboxing/Include/Python.h
==============================================================================
--- python/branches/bcannon-sandboxing/Include/Python.h	(original)
+++ python/branches/bcannon-sandboxing/Include/Python.h	Tue Jul 11 03:33:53 2006
@@ -113,9 +113,8 @@
 #include "codecs.h"
 #include "pyerrors.h"
 
-#include "sandbox.h"
-
 #include "pystate.h"
+#include "sandbox.h"
 
 #include "pyarena.h"
 #include "modsupport.h"

Modified: python/branches/bcannon-sandboxing/Include/sandbox.h
==============================================================================
--- python/branches/bcannon-sandboxing/Include/sandbox.h	(original)
+++ python/branches/bcannon-sandboxing/Include/sandbox.h	Tue Jul 11 03:33:53 2006
@@ -9,12 +9,37 @@
 struct _sandbox_state;  /* Forward */
 
 typedef struct _sandbox_state {
-    PY_LONG_LONG mem_cap;
+    /* The memory cap and current usage. */
+    Py_ssize_t mem_cap;
+    Py_ssize_t mem_usage;
 
 } PySandboxState;
 
+
+/* Return the sandbox state struct. */
+#define _PySandbox_GET() (PyThreadState_GET()->interp->sandbox_state)
+
 /* Return true if sandboxing is turn on for the current interpreter. */
-#define _PySandbox_Protected() (PyThreadState_GET()->interp->sandbox_state != NULL)
+#define _PySandbox_Check() (_PySandbox_GET() != NULL)
+
+/* Return true if memory caps are to be used.
+   Assumes sandboxing is turned on. */
+#define _PySandbox_IsMemCapped() (_PySandbox_GET()->mem_cap > 0)
+
+
+/*
+   Memory
+*/
+
+PyAPI_FUNC(int) PySandbox_SetMemoryCap(PyThreadState *, Py_ssize_t);
+
+PyAPI_FUNC(int) _PySandbox_AllowedMemoryAlloc(Py_ssize_t);
+/* Return for caller if memory allocation would exceed memory cap. */
+#define PySandbox_AllowedMemoryAlloc(alloc, err_return) \
+    if (!_PySandbox_AllowedMemoryAlloc(alloc)) return err_return
+
+/* Lower memory usage. */
+PyAPI_FUNC(void) PySandbox_AllowedMemoryFree(Py_ssize_t);
 
 #ifdef __cplusplus
 }

Modified: python/branches/bcannon-sandboxing/Python/sandbox.c
==============================================================================
--- python/branches/bcannon-sandboxing/Python/sandbox.c	(original)
+++ python/branches/bcannon-sandboxing/Python/sandbox.c	Tue Jul 11 03:33:53 2006
@@ -6,6 +6,60 @@
 extern "C" {
 #endif
 
+/*
+   Set the memory cap for a sandboxed interpreter.
+*/
+int
+PySandbox_SetMemoryCap(PyThreadState *s_tstate, Py_ssize_t mem_cap)
+{
+    PySandboxState *sandbox_state = s_tstate->interp->sandbox_state;
+
+    if (!sandbox_state)
+	return 0;
+
+    sandbox_state->mem_cap = mem_cap;
+
+    return 1;
+}
+
+/*
+   Verify that memory allocation is allowed.
+*/
+int
+_PySandbox_AllowedMemoryAlloc(Py_ssize_t allocate)
+{
+    PySandboxState *sandbox_state = _PySandbox_GET();
+
+    if (_PySandbox_Check() && _PySandbox_IsMemCapped()) {
+	sandbox_state->mem_usage += allocate;
+	if (sandbox_state->mem_cap < sandbox_state->mem_usage) {
+	    sandbox_state -= allocate;
+	    PyErr_SetString(PyExc_SandboxError, "memory allocation exceeded");
+	    return 0;
+	}
+	else
+	    return 1;
+	
+    }
+    else
+	return 1;
+}
+
+/*
+   Verify that freeing memory does not go past what was already used.
+*/
+void
+PySandbox_AllowedMemoryFree(Py_ssize_t deallocate)
+{
+    PySandboxState *sandbox_state = _PySandbox_GET();
+
+    if (_PySandbox_Check() && _PySandbox_IsMemCapped()) {
+	sandbox_state->mem_usage -= deallocate;
+	if (sandbox_state->mem_usage < 0)
+	    sandbox_state->mem_usage = 0;
+    }
+}
+
 #ifdef __cplusplus
 }
 #endif


More information about the Python-checkins mailing list