From 0282e67982033880c9871591139039536508c083 Mon Sep 17 00:00:00 2001 From: "skochinsky@gmail.com" Date: Mon, 26 Mar 2012 13:39:09 +0000 Subject: [PATCH] IDAPython 1.5.4 - fix for Python autorun script vulnerability reported by Greg MacManus - remove current directory from sys.path during initialization --- CHANGES.txt | 10 ++++++++++ build.py | 2 +- python.cpp | 32 ++++++++++++++++++++++++++++---- pywraps.hpp | 2 +- pywraps/py_idaapi.hpp | 26 +++++++++++++++++++------- swig/idaapi.i | 26 +++++++++++++++++++------- 6 files changed, 78 insertions(+), 20 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index f3c549a..fcfb01a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,16 @@ Please see http://code.google.com/p/idapython/source/list for a detailed list of changes. +Changes from version 1.5.3 to 1.5.4 +------------------------------------ +- fix for Python autorun script vulnerability reported by Greg MacManus +- remove current directory from sys.path during initialization +- added PyWraps sources. This will facilitate deployment, development and + debugging of IDAPython additions +- bugfix: op_t.is_reg() was buggy +- bugfix: build.py was putting duplicate files into the .zip +- bugfix: added back wrapped version of get_ascii_contents() + Changes from version 1.5.2 to 1.5.3 ------------------------------------ - IDA Pro 6.2 support diff --git a/build.py b/build.py index 330cbbf..245d15c 100644 --- a/build.py +++ b/build.py @@ -36,7 +36,7 @@ else: # IDAPython version VERSION_MAJOR = 1 VERSION_MINOR = 5 -VERSION_PATCH = 3 +VERSION_PATCH = 4 # Determine Python version PYTHON_MAJOR_VERSION = int(platform.python_version()[0]) diff --git a/python.cpp b/python.cpp index bd3fb38..e968dd7 100644 --- a/python.cpp +++ b/python.cpp @@ -1265,6 +1265,29 @@ static int idaapi menu_installer_cb(void *, int code, va_list) return 0; } +//------------------------------------------------------------------------- +// remove current directory (empty entry) from the sys.path +static void sanitize_path() +{ + char buf[QMAXPATH]; + qstrncpy(buf, Py_GetPath(), sizeof(buf)); + char *ctx; + qstring newpath; + for ( char *d0 = qstrtok(buf, DELIMITER, &ctx); + d0 != NULL; + d0 = qstrtok(NULL, DELIMITER, &ctx) ) + { + if ( d0[0] == '\0' ) + // skip empty entry + continue; + + if ( !newpath.empty() ) + newpath.append(DELIMITER); + newpath.append(d0); + } + PySys_SetPath(newpath.begin()); +} + //------------------------------------------------------------------------- // Initialize the Python environment bool IDAPython_Init(void) @@ -1280,7 +1303,7 @@ bool IDAPython_Init(void) if ( !CheckScriptFiles() ) return false; - char tmp[MAXSTR+64]; + char tmp[QMAXPATH]; #ifdef __LINUX__ // Export symbols from libpython to resolve imported module deps qsnprintf(tmp, sizeof(tmp), "libpython%d.%d.so.1", @@ -1319,10 +1342,9 @@ bool IDAPython_Init(void) read_user_config_file("python.cfg", set_python_options, NULL); if ( g_alert_auto_scripts ) { - const char *autofn = pywraps_check_autoscripts(); - if ( autofn != NULL + if ( pywraps_check_autoscripts(tmp, sizeof(tmp)) && askyn_c(0, "HIDECANCEL\nTITLE IDAPython\nThe script '%s' was found in the current directory and will be automatically executed by Python.\n\n" - "Do you want to continue loading IDAPython?", autofn) == 0 ) + "Do you want to continue loading IDAPython?", tmp) <= 0 ) { return false; } @@ -1336,6 +1358,8 @@ bool IDAPython_Init(void) return false; } + sanitize_path(); + // Enable multi-threading support if ( !PyEval_ThreadsInitialized() ) PyEval_InitThreads(); diff --git a/pywraps.hpp b/pywraps.hpp index e7f4a60..c0a8cbe 100644 --- a/pywraps.hpp +++ b/pywraps.hpp @@ -227,7 +227,7 @@ bool pywraps_nw_notify(int slot, ...); bool pywraps_nw_init(); //--------------------------------------------------------------------------- -const char *pywraps_check_autoscripts(); +bool pywraps_check_autoscripts(char *buf, size_t bufsize); // [De]Initializes PyWraps bool init_pywraps(); diff --git a/pywraps/py_idaapi.hpp b/pywraps/py_idaapi.hpp index 8e61bcc..37cd11e 100644 --- a/pywraps/py_idaapi.hpp +++ b/pywraps/py_idaapi.hpp @@ -94,28 +94,40 @@ struct py_timer_ctx_t }; //------------------------------------------------------------------------ -const char *pywraps_check_autoscripts() +bool pywraps_check_autoscripts(char *buf, size_t bufsize) { - static const char *exts[] = {"py", "pyw", "pyc", "pyo"}; + static const char *const exts[] = + { + "py", + "pyc", + "pyd", + "pyo", + "pyw", + }; - static const char *fns[] = + static const char *const fns[] = { "swig_runtime_data" SWIG_RUNTIME_VERSION, "sitecustomize", "usercustomize" }; - for (size_t ifn=0; ifn < qnumber(fns); ++ifn ) + for ( size_t ifn=0; ifn < qnumber(fns); ++ifn ) { for ( size_t iext=0; iext < qnumber(exts); ++iext ) { static char fn[QMAXPATH]; - qsnprintf(fn, sizeof(fn), "%s.%s", fns[ifn], exts[iext]); + qsnprintf(buf, bufsize, "%s.%s", fns[ifn], exts[iext]); if ( qfileexist(fn) ) - return fn; + return true; + if ( qfileexist(fns[ifn]) ) + { + qstrncpy(buf, fns[ifn], bufsize); + return true; + } } } - return NULL; + return false; } //------------------------------------------------------------------------ diff --git a/swig/idaapi.i b/swig/idaapi.i index 110eea3..d83359c 100644 --- a/swig/idaapi.i +++ b/swig/idaapi.i @@ -1289,28 +1289,40 @@ struct py_timer_ctx_t }; //------------------------------------------------------------------------ -const char *pywraps_check_autoscripts() +bool pywraps_check_autoscripts(char *buf, size_t bufsize) { - static const char *exts[] = {"py", "pyw", "pyc", "pyo"}; + static const char *const exts[] = + { + "py", + "pyc", + "pyd", + "pyo", + "pyw", + }; - static const char *fns[] = + static const char *const fns[] = { "swig_runtime_data" SWIG_RUNTIME_VERSION, "sitecustomize", "usercustomize" }; - for (size_t ifn=0; ifn < qnumber(fns); ++ifn ) + for ( size_t ifn=0; ifn < qnumber(fns); ++ifn ) { for ( size_t iext=0; iext < qnumber(exts); ++iext ) { static char fn[QMAXPATH]; - qsnprintf(fn, sizeof(fn), "%s.%s", fns[ifn], exts[iext]); + qsnprintf(buf, bufsize, "%s.%s", fns[ifn], exts[iext]); if ( qfileexist(fn) ) - return fn; + return true; + if ( qfileexist(fns[ifn]) ) + { + qstrncpy(buf, fns[ifn], bufsize); + return true; + } } } - return NULL; + return false; } //------------------------------------------------------------------------