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