diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3556a0b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/mod_wsgi-3.4.tar.gz diff --git a/.mod_wsgi.metadata b/.mod_wsgi.metadata new file mode 100644 index 0000000..8f9d399 --- /dev/null +++ b/.mod_wsgi.metadata @@ -0,0 +1 @@ +92ebc48e60ab658a984f97fd40cb71e0ae895469 SOURCES/mod_wsgi-3.4.tar.gz diff --git a/README.md b/README.md deleted file mode 100644 index 0e7897f..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 - -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/mod_wsgi-3.4-CVE-2014-0240.patch b/SOURCES/mod_wsgi-3.4-CVE-2014-0240.patch new file mode 100644 index 0000000..b1d770a --- /dev/null +++ b/SOURCES/mod_wsgi-3.4-CVE-2014-0240.patch @@ -0,0 +1,37 @@ +From d9d5fea585b23991f76532a9b07de7fcd3b649f4 Mon Sep 17 00:00:00 2001 +From: Graham Dumpleton +Date: Wed, 21 May 2014 16:16:47 +1000 +Subject: [PATCH] Local privilege escalation when using daemon mode. + (CVE-2014-0240) + +--- + mod_wsgi.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/mod_wsgi.c b/mod_wsgi.c +index 32b2903..3ef911b 100644 +--- a/mod_wsgi.c ++++ b/mod_wsgi.c +@@ -10756,6 +10756,19 @@ static void wsgi_setup_access(WSGIDaemonProcess *daemon) + ap_log_error(APLOG_MARK, WSGI_LOG_ALERT(errno), wsgi_server, + "mod_wsgi (pid=%d): Unable to change to uid=%ld.", + getpid(), (long)daemon->group->uid); ++ ++ /* ++ * On true UNIX systems this should always succeed at ++ * this point. With certain Linux kernel versions though ++ * we can get back EAGAIN where the target user had ++ * 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. ++ */ ++ ++ sleep(20); ++ ++ exit(-1); + } + + #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) +-- +2.0.3 + diff --git a/SOURCES/mod_wsgi-3.4-connsbh.patch b/SOURCES/mod_wsgi-3.4-connsbh.patch new file mode 100644 index 0000000..2f0c73e --- /dev/null +++ b/SOURCES/mod_wsgi-3.4-connsbh.patch @@ -0,0 +1,23 @@ + +Fix scoreboard handling. + +https://bugzilla.redhat.com/show_bug.cgi?id=867276 + +http://code.google.com/p/modwsgi/source/detail?path=/mod_wsgi.c&name=mod_wsgi-3.X&r=bdbeacb88f348909845445e9d52eb7be401abaf1 + +--- mod_wsgi-3.4/mod_wsgi.c.connsbh ++++ mod_wsgi-3.4/mod_wsgi.c +@@ -10600,7 +10600,13 @@ static void wsgi_process_socket(apr_pool + * will add their own input/output filters to the chain. + */ + ++#if AP_MODULE_MAGIC_AT_LEAST(20110619,0) ++ /* For 2.4 a NULL sbh pointer should work. */ ++ sbh = NULL; ++#else ++ /* For 2.2 a dummy sbh pointer is needed. */ + ap_create_sb_handle(&sbh, p, -1, 0); ++#endif + + c = (conn_rec *)apr_pcalloc(p, sizeof(conn_rec)); + diff --git a/SOURCES/mod_wsgi-3.4-coredump.patch b/SOURCES/mod_wsgi-3.4-coredump.patch new file mode 100644 index 0000000..07c4081 --- /dev/null +++ b/SOURCES/mod_wsgi-3.4-coredump.patch @@ -0,0 +1,47 @@ + +Enable core dumps. In upstream 3.x branch: + +http://code.google.com/p/modwsgi/source/detail?r=b4f55d756fa816a7eae0f7edc13d5f2da3f3d5c1&name=mod_wsgi-3.X&path=/mod_wsgi.c# + +--- mod_wsgi-3.4/configure.ac.dumpcore ++++ mod_wsgi-3.4/configure.ac +@@ -39,6 +39,8 @@ fi + + AC_SUBST(APXS) + ++AC_CHECK_FUNCS(prctl) ++ + AC_MSG_CHECKING(Apache version) + HTTPD="`${APXS} -q SBINDIR`/`${APXS} -q TARGET`" + HTTPD_INCLUDEDIR="`${APXS} -q INCLUDEDIR`" +--- mod_wsgi-3.4/mod_wsgi.c.coredump ++++ mod_wsgi-3.4/mod_wsgi.c +@@ -139,6 +139,10 @@ typedef regmatch_t ap_regmatch_t; + #include + #endif + ++#ifdef HAVE_SYS_PRCTL_H ++#include ++#endif ++ + #include "Python.h" + + #if !defined(PY_VERSION_HEX) +@@ -10485,6 +10489,17 @@ static void wsgi_setup_access(WSGIDaemon + "mod_wsgi (pid=%d): Unable to change to uid=%ld.", + getpid(), (long)daemon->group->uid); + } ++ ++#if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) ++ /* this applies to Linux 2.4+ */ ++ if (ap_coredumpdir_configured) { ++ if (prctl(PR_SET_DUMPABLE, 1)) { ++ ap_log_error(APLOG_MARK, WSGI_LOG_ALERT(errno), wsgi_server, ++ "mod_wsgi (pid=%d): set dumpable failed - this child will not coredump" ++ " after software errors", getpid()); ++ } ++ } ++#endif + } + + static int wsgi_setup_socket(WSGIProcessGroup *process) diff --git a/SOURCES/mod_wsgi-3.4-deadlock.patch b/SOURCES/mod_wsgi-3.4-deadlock.patch new file mode 100644 index 0000000..8754fc1 --- /dev/null +++ b/SOURCES/mod_wsgi-3.4-deadlock.patch @@ -0,0 +1,18 @@ + +https://github.com/GrahamDumpleton/mod_wsgi/commit/f8b43b2b79fabdcead4410f1a10484a10608ba6a + +--- mod_wsgi-3.4/mod_wsgi.c.deadlock ++++ mod_wsgi-3.4/mod_wsgi.c +@@ -11113,8 +11113,10 @@ + while (1) { + apr_sleep(apr_time_from_sec(1)); + +- gilstate = PyGILState_Ensure(); +- PyGILState_Release(gilstate); ++ if (!wsgi_daemon_shutdown) { ++ gilstate = PyGILState_Ensure(); ++ PyGILState_Release(gilstate); ++ } + + apr_thread_mutex_lock(wsgi_shutdown_lock); + wsgi_deadlock_shutdown_time = apr_time_now(); diff --git a/SOURCES/mod_wsgi-3.4-head-to-get.patch b/SOURCES/mod_wsgi-3.4-head-to-get.patch new file mode 100644 index 0000000..4d2d425 --- /dev/null +++ b/SOURCES/mod_wsgi-3.4-head-to-get.patch @@ -0,0 +1,149 @@ +diff --git a/mod_wsgi.c b/mod_wsgi.c +index c65344e..b32fc5c 100644 +--- a/mod_wsgi.c ++++ b/mod_wsgi.c +@@ -500,6 +500,7 @@ typedef struct { + int script_reloading; + int error_override; + int chunked_request; ++ int map_head_to_get; + + int enable_sendfile; + +@@ -669,6 +670,11 @@ static void *wsgi_merge_server_config(apr_pool_t *p, void *base_conf, + else + config->chunked_request = parent->chunked_request; + ++ if (child->map_head_to_get != -1) ++ config->map_head_to_get = child->map_head_to_get; ++ else ++ config->map_head_to_get = parent->map_head_to_get; ++ + if (child->enable_sendfile != -1) + config->enable_sendfile = child->enable_sendfile; + else +@@ -704,6 +710,7 @@ typedef struct { + int script_reloading; + int error_override; + int chunked_request; ++ int map_head_to_get; + + int enable_sendfile; + +@@ -737,6 +744,7 @@ static WSGIDirectoryConfig *newWSGIDirectoryConfig(apr_pool_t *p) + object->script_reloading = -1; + object->error_override = -1; + object->chunked_request = -1; ++ object->map_head_to_get = -1; + + object->enable_sendfile = -1; + +@@ -820,6 +828,11 @@ static void *wsgi_merge_dir_config(apr_pool_t *p, void *base_conf, + else + config->chunked_request = parent->chunked_request; + ++ if (child->map_head_to_get != -1) ++ config->map_head_to_get = child->map_head_to_get; ++ else ++ config->map_head_to_get = parent->map_head_to_get; ++ + if (child->enable_sendfile != -1) + config->enable_sendfile = child->enable_sendfile; + else +@@ -880,6 +893,7 @@ typedef struct { + int script_reloading; + int error_override; + int chunked_request; ++ int map_head_to_get; + + int enable_sendfile; + +@@ -1229,6 +1243,14 @@ static WSGIRequestConfig *wsgi_create_req_config(apr_pool_t *p, request_rec *r) + config->chunked_request = 0; + } + ++ config->map_head_to_get = dconfig->map_head_to_get; ++ ++ if (config->map_head_to_get < 0) { ++ config->map_head_to_get = sconfig->map_head_to_get; ++ if (config->map_head_to_get < 0) ++ config->map_head_to_get = 2; ++ } ++ + config->enable_sendfile = dconfig->enable_sendfile; + + if (config->enable_sendfile < 0) { +@@ -7993,6 +8015,40 @@ static const char *wsgi_set_chunked_request(cmd_parms *cmd, void *mconfig, + return NULL; + } + ++static const char *wsgi_set_map_head_to_get(cmd_parms *cmd, void *mconfig, ++ const char *f) ++{ ++ if (cmd->path) { ++ WSGIDirectoryConfig *dconfig = NULL; ++ dconfig = (WSGIDirectoryConfig *)mconfig; ++ ++ if (strcasecmp(f, "Off") == 0) ++ dconfig->map_head_to_get = 0; ++ else if (strcasecmp(f, "On") == 0) ++ dconfig->map_head_to_get = 1; ++ else if (strcasecmp(f, "Auto") == 0) ++ dconfig->map_head_to_get = 2; ++ else ++ return "WSGIMapHEADToGET must be one of: Off | On | Auto"; ++ } ++ else { ++ WSGIServerConfig *sconfig = NULL; ++ sconfig = ap_get_module_config(cmd->server->module_config, ++ &wsgi_module); ++ ++ if (strcasecmp(f, "Off") == 0) ++ sconfig->map_head_to_get = 0; ++ else if (strcasecmp(f, "On") == 0) ++ sconfig->map_head_to_get = 1; ++ else if (strcasecmp(f, "Auto") == 0) ++ sconfig->map_head_to_get = 2; ++ else ++ return "WSGIMapHEADToGET must be one of: Off | On | Auto"; ++ } ++ ++ return NULL; ++} ++ + static const char *wsgi_set_enable_sendfile(cmd_parms *cmd, void *mconfig, + const char *f) + { +@@ -8463,14 +8519,15 @@ static void wsgi_build_environment(request_rec *r) + * might change the content and/or headers. + */ + +-#if AP_SERVER_MAJORVERSION_NUMBER >= 2 +- if (r->method_number == M_GET && r->header_only && +- r->output_filters->frec->ftype < AP_FTYPE_PROTOCOL) +- apr_table_setn(r->subprocess_env, "REQUEST_METHOD", "GET"); +-#else +- if (r->method_number == M_GET && r->header_only) +- apr_table_setn(r->subprocess_env, "REQUEST_METHOD", "GET"); +-#endif ++ if (config->map_head_to_get == 2) { ++ if (r->method_number == M_GET && r->header_only && ++ r->output_filters->frec->ftype < AP_FTYPE_PROTOCOL) ++ apr_table_setn(r->subprocess_env, "REQUEST_METHOD", "GET"); ++ } ++ else if (config->map_head_to_get == 1) { ++ if (r->method_number == M_GET) ++ apr_table_setn(r->subprocess_env, "REQUEST_METHOD", "GET"); ++ } + + /* Determine whether connection uses HTTPS protocol. */ + +@@ -15856,6 +15913,8 @@ static const command_rec wsgi_commands[] = + NULL, OR_FILEINFO, "Enable/Disable overriding of error pages."), + AP_INIT_TAKE1("WSGIChunkedRequest", wsgi_set_chunked_request, + NULL, OR_FILEINFO, "Enable/Disable support for chunked requests."), ++ AP_INIT_TAKE1("WSGIMapHEADToGET", wsgi_set_map_head_to_get, ++ NULL, OR_FILEINFO, "Enable/Disable mapping of HEAD to GET."), + + #ifndef WIN32 + #if AP_SERVER_MAJORVERSION_NUMBER >= 2 diff --git a/SOURCES/mod_wsgi-3.4-procexit.patch b/SOURCES/mod_wsgi-3.4-procexit.patch new file mode 100644 index 0000000..7bb1690 --- /dev/null +++ b/SOURCES/mod_wsgi-3.4-procexit.patch @@ -0,0 +1,28 @@ + +Log exit status in daemon manager; improves diagnosics. + +http://code.google.com/p/modwsgi/source/detail?path=/mod_wsgi.c&name=mod_wsgi-3.X&r=b4f55d756fa816a7eae0f7edc13d5f2da3f3d5c1 + +--- mod_wsgi-3.3/mod_wsgi.c.procexit ++++ mod_wsgi-3.3/mod_wsgi.c +@@ -9845,6 +9845,20 @@ static void wsgi_manage_process(int reas + wsgi_server, "mod_wsgi (pid=%d): " + "Process '%s' has died, restarting.", + daemon->process.pid, daemon->group->name); ++ if (WIFEXITED(status)) { ++ ap_log_error(APLOG_MARK, WSGI_LOG_INFO(0), ++ wsgi_server, "mod_wsgi (pid=%d): " ++ "Process '%s' terminated normally, exit code %d", ++ daemon->process.pid, daemon->group->name, ++ WEXITSTATUS(status)); ++ } ++ else if (WIFSIGNALED(status)) { ++ ap_log_error(APLOG_MARK, WSGI_LOG_INFO(0), ++ wsgi_server, "mod_wsgi (pid=%d): " ++ "Process '%s' terminated by signal %d", ++ daemon->process.pid, daemon->group->name, ++ WTERMSIG(status)); ++ } + + wsgi_start_process(wsgi_parent_pool, daemon); + } diff --git a/SOURCES/wsgi.conf b/SOURCES/wsgi.conf new file mode 100644 index 0000000..19f3567 --- /dev/null +++ b/SOURCES/wsgi.conf @@ -0,0 +1 @@ +LoadModule wsgi_module modules/mod_wsgi.so diff --git a/SPECS/mod_wsgi.spec b/SPECS/mod_wsgi.spec new file mode 100644 index 0000000..2f38e31 --- /dev/null +++ b/SPECS/mod_wsgi.spec @@ -0,0 +1,198 @@ +%{!?_httpd_apxs: %{expand: %%global _httpd_apxs %%{_sbindir}/apxs}} +%{!?_httpd_mmn: %{expand: %%global _httpd_mmn %%(cat %{_includedir}/httpd/.mmn || echo missing-httpd-devel)}} +%{!?_httpd_confdir: %{expand: %%global _httpd_confdir %%{_sysconfdir}/httpd/conf.d}} +# /etc/httpd/conf.d with httpd < 2.4 and defined as /etc/httpd/conf.modules.d with httpd >= 2.4 +%{!?_httpd_modconfdir: %{expand: %%global _httpd_modconfdir %%{_sysconfdir}/httpd/conf.d}} +%{!?_httpd_moddir: %{expand: %%global _httpd_moddir %%{_libdir}/httpd/modules}} + +Name: mod_wsgi +Version: 3.4 +Release: 13%{?dist}.1 +Summary: A WSGI interface for Python web applications in Apache +Group: System Environment/Libraries +License: ASL 2.0 +URL: http://modwsgi.org +Source0: http://modwsgi.googlecode.com/files/%{name}-%{version}.tar.gz +Source1: wsgi.conf +Patch0: mod_wsgi-3.4-connsbh.patch +Patch1: mod_wsgi-3.4-procexit.patch +Patch2: mod_wsgi-3.4-coredump.patch +Patch3: mod_wsgi-3.4-CVE-2014-0240.patch +Patch4: mod_wsgi-3.4-deadlock.patch +Patch5: mod_wsgi-3.4-head-to-get.patch +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +BuildRequires: httpd-devel, python-devel, autoconf +Requires: httpd-mmn = %{_httpd_mmn} + +# Suppress auto-provides for module DSO +%{?filter_provides_in: %filter_provides_in %{_httpd_moddir}/.*\.so$} +%{?filter_setup} + +%description +The mod_wsgi adapter is an Apache module that provides a WSGI compliant +interface for hosting Python based web applications within Apache. The +adapter is written completely in C code against the Apache C runtime and +for hosting WSGI applications within Apache has a lower overhead than using +existing WSGI adapters for mod_python or CGI. + + +%prep +%setup -q +%patch0 -p1 -b .connsbh +%patch1 -p1 -b .procexit +%patch2 -p1 -b .coredump +%patch3 -p1 -b .cve20140240 +%patch4 -p1 -b .deadlock +%patch5 -p1 -b .headtoget + +%build +# Regenerate configure for -coredump patch change to configure.in +autoconf +export LDFLAGS="$RPM_LD_FLAGS -L%{_libdir}" +export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing" +%configure --enable-shared --with-apxs=%{_httpd_apxs} +make %{?_smp_mflags} + + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT LIBEXECDIR=%{_httpd_moddir} + +install -d -m 755 $RPM_BUILD_ROOT%{_httpd_modconfdir} +%if "%{_httpd_modconfdir}" == "%{_httpd_confdir}" +# httpd <= 2.2.x +install -p -m 644 %{SOURCE1} $RPM_BUILD_ROOT%{_httpd_confdir}/wsgi.conf +%else +# httpd >= 2.4.x +install -p -m 644 %{SOURCE1} $RPM_BUILD_ROOT%{_httpd_modconfdir}/10-wsgi.conf +%endif + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root,-) +%doc LICENCE README +%config(noreplace) %{_httpd_modconfdir}/*.conf +%{_httpd_moddir}/mod_wsgi.so + + +%changelog +* Thu Aug 30 2018 Luboš Uhliarik - 3.4-13.1 +- mod_wsgi forces HEAD to GET (#1623666) + +* Thu Dec 14 2017 Joe Orton - 3.4-13 +- reduce chance of deadlock at process shutdown (#1493429) + +* Tue Aug 19 2014 Jan Kaluza - 3.4-12 +- fix possible privilege escalation in setuid() (CVE-2014-0240) + +* Fri Jan 24 2014 Daniel Mach - 3.4-11 +- Mass rebuild 2014-01-24 + +* Mon Jan 13 2014 Joe Orton - 3.4-10 +- rebuild for #1029360 + +* Fri Dec 27 2013 Daniel Mach - 3.4-9 +- Mass rebuild 2013-12-27 + +* Thu Feb 14 2013 Fedora Release Engineering - 3.4-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Tue Dec 11 2012 Jan Kaluza - 3.4-7 +- compile with -fno-strict-aliasing to workaround Python + bug http://www.python.org/dev/peps/pep-3123/ + +* Thu Nov 22 2012 Joe Orton - 3.4-6 +- use _httpd_moddir macro + +* Thu Nov 22 2012 Joe Orton - 3.4-5 +- spec file cleanups + +* Wed Oct 17 2012 Joe Orton - 3.4-4 +- enable PR_SET_DUMPABLE in daemon process to enable core dumps + +* Wed Oct 17 2012 Joe Orton - 3.4-3 +- use a NULL c->sbh pointer with httpd 2.4 (possible fix for #867276) +- add logging for unexpected daemon process loss + +* Wed Oct 17 2012 Matthias Runge - 3.4-2 +- also use RPM_LD_FLAGS for build bz. #867137 + +* Mon Oct 15 2012 Matthias Runge - 3.4-1 +- update to upstream release 3.4 + +* Fri Jul 20 2012 Fedora Release Engineering - 3.3-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Wed Jun 13 2012 Joe Orton - 3.3-6 +- add possible fix for daemon mode crash (#831701) + +* Mon Mar 26 2012 Joe Orton - 3.3-5 +- move wsgi.conf to conf.modules.d + +* Mon Mar 26 2012 Joe Orton - 3.3-4 +- rebuild for httpd 2.4 + +* Tue Mar 13 2012 Joe Orton - 3.3-3 +- prepare for httpd 2.4.x + +* Fri Jan 13 2012 Fedora Release Engineering - 3.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Tue Nov 01 2011 James Bowes 3.3-1 +- update to 3.3 + +* Tue Feb 08 2011 Fedora Release Engineering - 3.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Tue Jul 27 2010 David Malcolm - 3.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild + +* Tue Mar 9 2010 Josh Kayse - 3.2-1 +- update to 3.2 + +* Sun Mar 07 2010 Josh Kayse - 3.1-2 +- removed conflicts as it violates fedora packaging policy + +* Sun Mar 07 2010 Josh Kayse - 3.1-1 +- update to 3.1 +- add explicit enable-shared +- add conflicts mod_python < 3.3.1 + +* Sat Jul 25 2009 Fedora Release Engineering - 2.5-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Thu Jul 02 2009 James Bowes 2.5-1 +- Update to 2.5 + +* Wed Feb 25 2009 Fedora Release Engineering - 2.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Sun Nov 30 2008 Ignacio Vazquez-Abrams - 2.3-2 +- Rebuild for Python 2.6 + +* Tue Oct 28 2008 Luke Macken 2.3-1 +- Update to 2.3 + +* Mon Sep 29 2008 James Bowes 2.1-2 +- Remove requires on httpd-devel + +* Wed Jul 02 2008 James Bowes 2.1-1 +- Update to 2.1 + +* Mon Jun 16 2008 Ricky Zhou 1.3-4 +- Build against the shared python lib. + +* Tue Feb 19 2008 Fedora Release Engineering - 1.3-3 +- Autorebuild for GCC 4.3 + +* Sun Jan 06 2008 James Bowes 1.3-2 +- Require httpd + +* Sat Jan 05 2008 James Bowes 1.3-1 +- Update to 1.3 + +* Sun Sep 30 2007 James Bowes 1.0-1 +- Initial packaging for Fedora +