Skip to content

Commit

Permalink
Merge branch 'release/4.2.4'
Browse files Browse the repository at this point in the history
  • Loading branch information
GrahamDumpleton committed Jun 18, 2014
2 parents b286c1f + 5956495 commit 0abb042
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 8 deletions.
1 change: 1 addition & 0 deletions docs/release-notes/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Release Notes
.. toctree::
:maxdepth: 2

version-4.2.4.rst
version-4.2.3.rst
version-4.2.2.rst
version-4.2.1.rst
Expand Down
37 changes: 37 additions & 0 deletions docs/release-notes/version-4.2.4.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
=============
Version 4.2.4
=============

Version 4.2.4 of mod_wsgi can be obtained from:

https://github.com/GrahamDumpleton/mod_wsgi/archive/4.2.4.tar.gz

Known Issues
------------

1. The makefiles for building mod_wsgi on Windows are currently broken and
need updating. As most new changes relate to mod_wsgi daemon mode, which is
not supported under Windows, you should keep using the last available
binary for version 3.X on Windows instead.

Bugs Fixed
----------

1. Fixed one off error in applying limit to the number of supplementary
groups allowed for a daemon process group. The result could be that if
more groups than the operating system allowed were specified to the option
``supplementary-groups``, then memory corruption or a process crash could
occur.

2. Improved error handling in setting up the current working directory and
group access rights for a process when creating a daemon process group. The
change means that if any error occurs that the daemon process group will be
restarted rather than allow it to keep running with an incorrect working
directory or group access rights.

New Features
------------

1. Added the ``--setup-only`` option to mod_wsgi express so that it is
possible to create the configuration when using the Django management command
``runmodwsgi`` without actually starting the server.
13 changes: 12 additions & 1 deletion src/server/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,14 @@ def check_percentage(option, opt_str, value, parser):
optparse.make_option('--enable-docs', action='store_true', default=False,
help='Flag indicating whether the mod_wsgi documentation should '
'be made available at the /__wsgi__/docs sub URL.'),

optparse.make_option('--setup-only', action='store_true', default=False,
help='Flag indicating that after the configuration files have '
'been setup, that the command should then exit and not go on '
'to actually run up the Apache server. This is to allow for '
'the generation of the configuration with Apache then later '
'being started separately using the generated \'apachectl\' '
'script.'),
)

def cmd_setup_server(params):
Expand Down Expand Up @@ -1350,7 +1358,7 @@ def _cmd_setup_server(command, args, options):
if options['envvars_script']:
print('Environ Variables :', options['envvars_script'])

if command == 'setup-server':
if command == 'setup-server' or options['setup_only']:
if not options['envvars_script']:
print('Environ Variables :', options['server_root'] + '/envvars')
print('Control Script :', options['server_root'] + '/apachectl')
Expand All @@ -1369,6 +1377,9 @@ def cmd_start_server(params):

config = _cmd_setup_server('start-server', args, vars(options))

if config['setup_only']:
return

executable = os.path.join(config['server_root'], 'apachectl')
name = executable.ljust(len(config['process_name']))
os.execl(executable, name, 'start', '-DNO_DETACH')
Expand Down
5 changes: 4 additions & 1 deletion src/server/management/commands/runmodwsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class Command(BaseCommand):
option_list = BaseCommand.option_list + mod_wsgi.server.option_list
args = '[options]'
args = ''
help = 'Starts Apache/mod_wsgi web server.'

def handle(self, *args, **options):
Expand Down Expand Up @@ -47,6 +47,9 @@ def handle(self, *args, **options):
options = mod_wsgi.server._cmd_setup_server(
'start-server', args, options)

if options['setup_only']:
return

executable = os.path.join(options['server_root'], 'apachectl')
name = executable.ljust(len(options['process_name']))
os.execl(executable, name, 'start', '-DNO_DETACH')
56 changes: 52 additions & 4 deletions src/server/mod_wsgi.c
Original file line number Diff line number Diff line change
Expand Up @@ -6690,7 +6690,7 @@ static const char *wsgi_add_daemon_process(cmd_parms *cmd, void *mconfig,
group_name = ap_getword(cmd->pool, &items, ',');

while (group_name && *group_name) {
if (groups_count > groups_maximum)
if (groups_count >= groups_maximum)
return "Too many supplementary groups WSGI daemon process";

groups[groups_count++] = ap_gname2id(group_name);
Expand Down Expand Up @@ -7087,7 +7087,7 @@ static void wsgi_setup_daemon_name(WSGIDaemonProcess *daemon, apr_pool_t *p)
#endif
}

static void wsgi_setup_access(WSGIDaemonProcess *daemon)
static int wsgi_setup_access(WSGIDaemonProcess *daemon)
{
/* Setup the umask for the effective user. */

Expand All @@ -7101,6 +7101,8 @@ static void wsgi_setup_access(WSGIDaemonProcess *daemon)
ap_log_error(APLOG_MARK, APLOG_ALERT, errno, wsgi_server,
"mod_wsgi (pid=%d): Unable to change root "
"directory to '%s'.", getpid(), daemon->group->root);

return -1;
}
}

Expand All @@ -7111,6 +7113,8 @@ static void wsgi_setup_access(WSGIDaemonProcess *daemon)
ap_log_error(APLOG_MARK, APLOG_ALERT, errno, wsgi_server,
"mod_wsgi (pid=%d): Unable to change working "
"directory to '%s'.", getpid(), daemon->group->home);

return -1;
}
}
else if (geteuid()) {
Expand All @@ -7123,12 +7127,16 @@ static void wsgi_setup_access(WSGIDaemonProcess *daemon)
ap_log_error(APLOG_MARK, APLOG_ALERT, errno, wsgi_server,
"mod_wsgi (pid=%d): Unable to change working "
"directory to '%s'.", getpid(), pwent->pw_dir);

return -1;
}
}
else {
ap_log_error(APLOG_MARK, APLOG_ALERT, errno, wsgi_server,
"mod_wsgi (pid=%d): Unable to determine home "
"directory for uid=%ld.", getpid(), (long)geteuid());

return -1;
}
}
else {
Expand All @@ -7141,27 +7149,33 @@ static void wsgi_setup_access(WSGIDaemonProcess *daemon)
ap_log_error(APLOG_MARK, APLOG_ALERT, errno, wsgi_server,
"mod_wsgi (pid=%d): Unable to change working "
"directory to '%s'.", getpid(), pwent->pw_dir);

return -1;
}
}
else {
ap_log_error(APLOG_MARK, APLOG_ALERT, errno, wsgi_server,
"mod_wsgi (pid=%d): Unable to determine home "
"directory for uid=%ld.", getpid(),
(long)daemon->group->uid);

return -1;
}
}

/* Don't bother switch user/group if not root. */

if (geteuid())
return;
return 0;

/* Setup the daemon process real and effective group. */

if (setgid(daemon->group->gid) == -1) {
ap_log_error(APLOG_MARK, APLOG_ALERT, errno, wsgi_server,
"mod_wsgi (pid=%d): Unable to set group id to gid=%u.",
getpid(), (unsigned)daemon->group->gid);

return -1;
}
else {
if (daemon->group->groups) {
Expand All @@ -7172,13 +7186,17 @@ static void wsgi_setup_access(WSGIDaemonProcess *daemon)
"to set supplementary groups for uname=%s "
"of '%s'.", getpid(), daemon->group->user,
daemon->group->groups_list);

return -1;
}
}
else if (initgroups(daemon->group->user, daemon->group->gid) == -1) {
ap_log_error(APLOG_MARK, APLOG_ALERT, errno,
wsgi_server, "mod_wsgi (pid=%d): Unable "
"to set groups for uname=%s and gid=%u.", getpid(),
daemon->group->user, (unsigned)daemon->group->gid);

return -1;
}
}

Expand All @@ -7196,8 +7214,19 @@ static void wsgi_setup_access(WSGIDaemonProcess *daemon)
* reached their process limit. In that case will be left
* running as wrong user. Just exit on all failures to be
* safe. Don't die immediately to avoid a fork bomb.
*
* We could just return -1 here and let the caller do the
* sleep() and exit() but this failure is critical enough
* that we still do it here so it is obvious that the issue
* is being addressed.
*/

ap_log_error(APLOG_MARK, APLOG_ALERT, 0, wsgi_server,
"mod_wsgi (pid=%d): Failure to configure the "
"daemon process correctly and process left in "
"unspecified state. Restarting daemon process "
"after delay.", getpid());

sleep(20);

exit(-1);
Expand All @@ -7219,6 +7248,8 @@ static void wsgi_setup_access(WSGIDaemonProcess *daemon)
}
}
#endif

return 0;
}

static int wsgi_setup_socket(WSGIProcessGroup *process)
Expand Down Expand Up @@ -8561,7 +8592,24 @@ static int wsgi_start_process(apr_pool_t *p, WSGIDaemonProcess *daemon)

/* Setup daemon process user/group/umask etc. */

wsgi_setup_access(daemon);
if (wsgi_setup_access(daemon) == -1) {
/*
* If we get any failure from setting up the appropriate
* permissions or working directory for the daemon process
* then we exit the process. Don't die immediately to avoid
* a fork bomb.
*/

ap_log_error(APLOG_MARK, APLOG_ALERT, 0, wsgi_server,
"mod_wsgi (pid=%d): Failure to configure the "
"daemon process correctly and process left in "
"unspecified state. Restarting daemon process "
"after delay.", getpid());

sleep(20);

exit(-1);
}

/* Reinitialise accept mutex in daemon process. */

Expand Down
4 changes: 2 additions & 2 deletions src/server/wsgi_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@

#define MOD_WSGI_MAJORVERSION_NUMBER 4
#define MOD_WSGI_MINORVERSION_NUMBER 2
#define MOD_WSGI_MICROVERSION_NUMBER 3
#define MOD_WSGI_VERSION_STRING "4.2.3"
#define MOD_WSGI_MICROVERSION_NUMBER 4
#define MOD_WSGI_VERSION_STRING "4.2.4"

/* ------------------------------------------------------------------------- */

Expand Down

0 comments on commit 0abb042

Please sign in to comment.