On Tue, Apr 17, 2012 at 10:51:00AM +1000, Graham Dumpleton wrote:
> On 17 April 2012 10:06, Luke Macken <[email protected]> wrote:
> > On Sun, Apr 15, 2012 at 08:02:58PM +1000, Graham Dumpleton wrote:
> >> 1. Means of turning on hash seed randomisation with recent updates of
> >> Python. I still have a few issues to sort out here. I was supplied a
> >> patch, but it doesn't go far enough and deal adequately with issues
> >> like upgrading patch levels of Python against a mod_wsgi compiled
> >> against an older version. It also didn't allow hash seeding, only
> >> randomisation.
> >
> > Attached is a patch that solves both of these problems.
> >
> > This creates a WSGIPythonHashSeed option, which gets set to the
> > PYTHONHASHSEED environment variable. This option accepts either 'random'
> > or seed values 0-4294967295.
> >
> > Thoughts?
> 
> Needs to be a bit more complicated than that I suspect.
> 
> Because it can be set to a specific seed, I don't believe you can make
> the assumption that one should allow that environment variable to be
> inherited by sub process as that would then affected any Python
> programs you might run from the process.
> 
> What I was likely to do was to set the environment variable, but defer
> doing that until just before Python interpreter initialised. Then
> after interpreter initialised, unset the environment variable from C
> process level. This does though still leave it with os.environ of the
> main interpreter, so may have to be removed manually from that.

Attached is an updated patch that addresses both of these concerns.
It will now setenv right before Py_Initialize, and unsetenv right after.
It will also remove PYTHONHASHSEED from the os.environ when
newInterpreterObject is called. As for the WIN32 stuff, I'm just
guessing.

> The other thing contending with is whether you allow this to be set
> differently for different daemon process groups, or just once globally
> for the whole Apache and mod_wsgi daemon processes.

With my limited knowledge of the mod_wsgi internals, I'm not quite sure
how this would be done.

luke

-- 
You received this message because you are subscribed to the Google Groups 
"modwsgi" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/modwsgi?hl=en.

--- mod_wsgi.c.orig     2012-04-16 19:24:08.671074746 -0400
+++ mod_wsgi.c  2012-04-16 22:07:21.204504425 -0400
@@ -457,6 +457,7 @@
     const char *python_home;
     const char *python_path;
     const char *python_eggs;
+    const char *python_hash_seed;
 
     int restrict_embedded;
     int restrict_stdin;
@@ -526,6 +527,7 @@
     object->python_home = NULL;
     object->python_path = NULL;
     object->python_eggs = NULL;
+    object->python_hash_seed = NULL;
 
     object->restrict_embedded = -1;
     object->restrict_stdin = -1;
@@ -4750,6 +4752,32 @@
         }
     }
 
+    if (wsgi_server_config->python_hash_seed != NULL) {
+        module = PyImport_ImportModule("os");
+
+        if (module) {
+            PyObject *dict = NULL;
+            PyObject *key = NULL;
+
+            dict = PyModule_GetDict(module);
+            object = PyDict_GetItemString(dict, "environ");
+
+            if (object) {
+#if PY_MAJOR_VERSION >= 3
+                key = PyUnicode_FromString("PYTHONHASHSEED");
+#else
+                key = PyString_FromString("PYTHONHASHSEED");
+#endif
+
+                PyObject_DelItem(object, key);
+
+                Py_DECREF(key);
+            }
+
+            Py_DECREF(module);
+        }
+    }
+
     /*
      * Install user defined Python module search path. This is
      * added using site.addsitedir() so that any Python .pth
@@ -5810,6 +5838,14 @@
         _wputenv(L"PYTHONIOENCODING=cp1252:backslashreplace");
 #endif
 
+        if (wsgi_server_config->python_hash_seed != NULL) {
+#if defined(WIN32)
+            _putenv_s("PYTHONHASHSEED", wsgi_server_config->python_hash_seed);
+#else
+            setenv("PYTHONHASHSEED", wsgi_server_config->python_hash_seed, 1);
+#endif
+        }
+
         /* Initialise Python. */
 
         ap_log_error(APLOG_MARK, WSGI_LOG_INFO(0), wsgi_server,
@@ -5827,6 +5863,10 @@
 
         wsgi_python_initialized = 1;
 
+        if (wsgi_server_config->python_hash_seed != NULL) {
+            unsetenv("PYTHONHASHSEED");
+        }
+
     /*
      * Register cleanups to be performed on parent restart
      * or shutdown. This will destroy Python itself.
@@ -7235,6 +7275,22 @@
     return NULL;
 }
 
+static const char *wsgi_set_python_hash_seed(cmd_parms *cmd, void *mconfig,
+                                             const char *f)
+{
+    const char *error = NULL;
+    WSGIServerConfig *sconfig = NULL;
+
+    error = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+    if (error != NULL)
+        return error;
+
+    sconfig = ap_get_module_config(cmd->server->module_config, &wsgi_module);
+    sconfig->python_hash_seed = f;
+
+    return NULL;
+}
+
 static const char *wsgi_set_restrict_embedded(cmd_parms *cmd, void *mconfig,
                                               const char *f)
 {
@@ -9204,6 +9260,8 @@
         RSRC_CONF, TAKE1, "Python module search path." },
     { "WSGIPythonEggs", wsgi_set_python_eggs, NULL,
         RSRC_CONF, TAKE1, "Python eggs cache directory." },
+    { "WSGIPythonHashSeed", wsgi_set_python_hash_seed, NULL,
+        RSRC_CONF, TAKE1, "Python hash seed." },
 
     { "WSGIRestrictStdin", wsgi_set_restrict_stdin, NULL,
         RSRC_CONF, TAKE1, "Enable/Disable restrictions on use of STDIN." },
@@ -14890,6 +14948,8 @@
         NULL, RSRC_CONF, "Python module search path."),
     AP_INIT_TAKE1("WSGIPythonEggs", wsgi_set_python_eggs,
         NULL, RSRC_CONF, "Python eggs cache directory."),
+    AP_INIT_RAW_ARGS("WSGIPythonHashSeed", wsgi_set_python_hash_seed,
+        NULL, RSRC_CONF, "Python hash seed."),
 
 #if defined(MOD_WSGI_WITH_DAEMONS)
     AP_INIT_TAKE1("WSGIRestrictEmbedded", wsgi_set_restrict_embedded,

Reply via email to