https://www.mediawiki.org/wiki/Special:Code/MediaWiki/114880

Revision: 114880
Author:   tstarling
Date:     2012-04-13 10:19:27 +0000 (Fri, 13 Apr 2012)
Log Message:
-----------
* Implemented a safe version of setfenv()
* Allow registerLibrary() to work even if the global already exists. Just merge 
the libraries. This allows us to have an mw table with some PHP code and some 
Lua code.
* Made luasandbox_instanceof() non-inline
* Removed getfenv(), can break module isolation

Modified Paths:
--------------
    trunk/php/luasandbox/library.c
    trunk/php/luasandbox/luasandbox.c

Modified: trunk/php/luasandbox/library.c
===================================================================
--- trunk/php/luasandbox/library.c      2012-04-13 09:40:11 UTC (rev 114879)
+++ trunk/php/luasandbox/library.c      2012-04-13 10:19:27 UTC (rev 114880)
@@ -22,7 +22,8 @@
 static int luasandbox_math_random(lua_State * L);
 static int luasandbox_math_randomseed(lua_State * L);
 static int luasandbox_base_pcall(lua_State * L);
-static int luasandbox_base_xpcall (lua_State *L);
+static int luasandbox_base_xpcall(lua_State *L);
+static int luasandbox_base_setfenv(lua_State *L);
 
 /**
  * Allowed global variables. Omissions are:
@@ -36,6 +37,7 @@
  *   * tostring: Provides addresses of tables and functions, which provides an 
  *     easy ASLR workaround or heap address discovery mechanism for a memory 
  *     corruption exploit. We have our own version.
+ *   * getfenv, setfenv: Can be used to break module isolation.
  *   * Any new or undocumented functions like newproxy.
  *   * package: cpath, loadlib etc. are insecure.
  *   * coroutine: Not useful for our application so unreviewed at present.
@@ -48,8 +50,6 @@
        "assert",
        "error",
        "getmetatable",
-       "getfenv",
-       "getmetatable",
        "ipairs",
        "next",
        "pairs",
@@ -107,15 +107,16 @@
                }
        }
 
-       // Install our own version of tostring, pcall, xpcall
+       // Install our own versions of tostring, pcall, xpcall, setfenv
        lua_pushcfunction(L, luasandbox_base_tostring);
        lua_setglobal(L, "tostring");
        lua_pushcfunction(L, luasandbox_base_pcall);
        lua_setglobal(L, "pcall");
        lua_pushcfunction(L, luasandbox_base_xpcall);
        lua_setglobal(L, "xpcall");
+       lua_pushcfunction(L, luasandbox_base_setfenv);
+       lua_setglobal(L, "setfenv");
 
-
        // Remove string.dump: may expose private data
        lua_getglobal(L, "string");
        lua_pushnil(L);
@@ -348,3 +349,19 @@
        return lua_gettop(L);  // return status + all results
 }
 /* }}} */
+
+/* {{{ luasandbox_base_setfenv
+ *
+ * A setfenv() implementation that does not allow integer keys for the first
+ * argument.
+ */
+static int luasandbox_base_setfenv(lua_State *L)
+{
+       luaL_checktype(L, 2, LUA_TTABLE);
+       lua_pushvalue(L, 2);
+       if (!lua_isfunction(L, 1) || lua_iscfunction(L, 1) || lua_setfenv(L, 1) 
== 0) {
+               luaL_error(L, "'setfenv' cannot change environment of given 
object");   
+       }
+       return 1;
+}
+/* }}} */

Modified: trunk/php/luasandbox/luasandbox.c
===================================================================
--- trunk/php/luasandbox/luasandbox.c   2012-04-13 09:40:11 UTC (rev 114879)
+++ trunk/php/luasandbox/luasandbox.c   2012-04-13 10:19:27 UTC (rev 114880)
@@ -43,7 +43,10 @@
 static void luasandbox_handle_emergency_timeout(php_luasandbox_obj * sandbox);
 static int luasandbox_call_php(lua_State * L);
 static int luasandbox_dump_writer(lua_State * L, const void * p, size_t sz, 
void * ud);
+static zend_bool luasandbox_instanceof(
+       zend_class_entry *child_class, zend_class_entry *parent_class);
 
+
 zend_class_entry *luasandbox_ce;
 zend_class_entry *luasandboxerror_ce;
 zend_class_entry *luasandboxruntimeerror_ce;
@@ -1016,7 +1019,8 @@
  * relevant PHP code.
  *
  * The first parameter is the name of the library. In the Lua state, the global
- * variable of this name will be set to the table of functions.
+ * variable of this name will be set to the table of functions. If the table 
+ * already exists, the new functions will be added to it.
  *
  * The second parameter is an array, where each key is a function name, and 
  * each value is a corresponding PHP callback.
@@ -1051,17 +1055,14 @@
        lua_pushlstring(L, libname, libname_len);
        lua_pushvalue(L, -1);
        lua_rawget(L, LUA_GLOBALSINDEX);
-       if (lua_type(L, -1) != LUA_TNIL) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING,
-                       "library \"%s\" already exists", libname);
-               RETURN_FALSE;
+       if (lua_type(L, -1) == LUA_TNIL) {
+               // Remove the nil
+               lua_pop(L, 1);
+
+               // Create the new table
+               lua_createtable(L, 0, functions->nNumOfElements);
        }
-       // Remove the nil
-       lua_pop(L, 1);
 
-       // Create the new table
-       lua_createtable(L, 0, functions->nNumOfElements);
-
        for (p = functions->pListHead; p; p = p->pListNext) {
                // Push the key
                if (p->nKeyLength) {
@@ -1087,7 +1088,7 @@
 /** {{{ luasandbox_instanceof
  * Based on is_derived_class in zend_object_handlers.c
  */
-static inline zend_bool luasandbox_instanceof(
+static zend_bool luasandbox_instanceof(
        zend_class_entry *child_class, zend_class_entry *parent_class)
 {
        while (child_class) {


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to