From 8e0c1c20aef0f233f93b6d5799f8b0e2c3bdd441 Mon Sep 17 00:00:00 2001 From: ensc Date: Feb 21 2010 11:20:31 +0000 Subject: updated --- diff --git a/milter-greylist-dkim-reentrant.patch b/milter-greylist-dkim-reentrant.patch new file mode 100644 index 0000000..7a7ee4c --- /dev/null +++ b/milter-greylist-dkim-reentrant.patch @@ -0,0 +1,73 @@ +Index: milter-greylist-4.2.3/dkimcheck.c +=================================================================== +--- milter-greylist-4.2.3.orig/dkimcheck.c ++++ milter-greylist-4.2.3/dkimcheck.c +@@ -63,6 +63,7 @@ __RCSID("$Id: dkimcheck.c,v 1.4 2008/10/ + #include "dkimcheck.h" + + static DKIM_LIB *dkim_ptr = NULL; ++static pthread_rwlock_t dkim_lock; + static sfsistat dkimcheck_error(struct mlfi_priv *); + + static sfsistat +@@ -115,28 +116,36 @@ dkimcheck_error(priv) + } + + void +-dkimcheck_init(void) ++dkimcheck_clear(void) + { ++ /* ++ * XXX This probably leaves stale handles for messages being processed ++ */ ++ ++ WRLOCK(&dkim_lock); ++ if (dkim_ptr != NULL) ++ dkim_close(dkim_ptr); ++ dkim_ptr = NULL; ++ + if ((dkim_ptr = dkim_init(NULL, NULL)) == NULL) { + mg_log(LOG_ERR, "dkim_init() failed"); + exit(EX_OSERR); + } +- +- return; ++ UNLOCK(&dkim_lock); + } + + void +-dkimcheck_clear(void) ++dkimcheck_init(void) + { +- /* +- * XXX This probably leaves stale handles for messages being processed +- */ +- if (dkim_ptr != NULL) +- dkim_close(dkim_ptr); +- dkim_ptr = NULL; ++ int error; + +- dkimcheck_init(); +- return; ++ if ((error = pthread_rwlock_init(&dkim_lock, NULL)) != 0) { ++ mg_log(LOG_ERR, "pthread_rwlock_init failed: %s", ++ strerror(error)); ++ exit(EX_OSERR); ++ } ++ ++ dkimcheck_clear(); + } + + sfsistat +@@ -159,8 +168,11 @@ dkimcheck_header(name, value, priv) + if (priv->priv_dkimstat != DKIM_STAT_OK) + return SMFIS_CONTINUE; + ++ WRLOCK(&dkim_lock); + priv->priv_dkim = dkim_verify(dkim_ptr, priv->priv_queueid, + NULL, &priv->priv_dkimstat); ++ UNLOCK(&dkim_lock); ++ + if (priv->priv_dkim == NULL) { + mg_log(LOG_ERR, "dkim_verify() failed: %s", + dkim_getresultstr(priv->priv_dkimstat)); diff --git a/milter-greylist-geoip-lock.patch b/milter-greylist-geoip-lock.patch new file mode 100644 index 0000000..2289c47 --- /dev/null +++ b/milter-greylist-geoip-lock.patch @@ -0,0 +1,98 @@ +Lock GeoIP calls + +Calls to GeoIP_id_by_name() and friends must not overlap because +these functions modify the given handle without locking it. When +milter-greylist sees two connection at nearly the same time, this +situation might be triggered causing corruption of internal data and +a segfault. + +Beside adding locking of the GeoIP functions, tbis patch uses +GeoIP_country_code_by_addr() instead of accessing the internal +GeoIP_country_code[] array directly (see the big "Warning: do not +use those arrays" comment in the GeoIP.h header). + + +Index: milter-greylist-4.2.3/geoip.c +=================================================================== +--- milter-greylist-4.2.3.orig/geoip.c ++++ milter-greylist-4.2.3/geoip.c +@@ -45,6 +45,7 @@ __RCSID("$Id"); + #include + #include + #include ++#include + #include + + #include +@@ -59,6 +60,21 @@ __RCSID("$Id"); + + static GeoIP *geoip_handle = NULL; + static char geoip_database[MAXPATHLEN + 1]; ++static pthread_rwlock_t geoip_lock; ++ ++void ++geoip_init(void) ++{ ++ int error; ++ ++ if ((error = pthread_rwlock_init(&geoip_lock, NULL)) != 0) { ++ mg_log(LOG_ERR, "pthread_rwlock_init failed: %s", ++ strerror(error)); ++ exit(EX_OSERR); ++ } ++ ++ return; ++} + + void + geoip_set_db(name) +@@ -104,7 +120,6 @@ geoip_set_ccode(priv) + struct mlfi_priv *priv; + { + char ipstr[IPADDRSTRLEN]; +- int cid; + + if (geoip_handle == NULL) { + mg_log(LOG_WARNING, "GeoIP is not available"); +@@ -119,9 +134,13 @@ geoip_set_ccode(priv) + return; + } + +- cid = GeoIP_id_by_name(geoip_handle, ipstr); ++ WRLOCK(geoip_lock); ++ priv->priv_ccode = GeoIP_country_code_by_addr(geoip_handle, ipstr); ++ UNLOCK(geoip_lock); ++ ++ if (priv->priv_ccode == NULL) ++ mg_log(LOG_DEBUG, "GeoIP failed to lookup ip '%s'", ipstr); + +- priv->priv_ccode = GeoIP_country_code[cid]; + + return; + } +Index: milter-greylist-4.2.3/geoip.h +=================================================================== +--- milter-greylist-4.2.3.orig/geoip.h ++++ milter-greylist-4.2.3/geoip.h +@@ -35,6 +35,7 @@ + #ifndef _MG_GEOIP_H_ + #define _MG_GEOIP_H_ + ++void geoip_init(void); + void geoip_set_db(char *); + void geoip_set_ccode(struct mlfi_priv *); + int geoip_filter(acl_data_t *, acl_stage_t, +Index: milter-greylist-4.2.3/milter-greylist.c +=================================================================== +--- milter-greylist-4.2.3.orig/milter-greylist.c ++++ milter-greylist-4.2.3/milter-greylist.c +@@ -1467,6 +1467,9 @@ main(argc, argv) + #ifdef USE_DKIM + dkimcheck_init(); + #endif ++#ifdef USE_GEOIP ++ geoip_init(); ++#endif + macro_init(); + + #ifdef USE_FD_POOL diff --git a/milter-greylist-p0f-reentrant.patch b/milter-greylist-p0f-reentrant.patch new file mode 100644 index 0000000..2fd315b --- /dev/null +++ b/milter-greylist-p0f-reentrant.patch @@ -0,0 +1,133 @@ +Index: milter-greylist-4.2.3/conf.c +=================================================================== +--- milter-greylist-4.2.3.orig/conf.c ++++ milter-greylist-4.2.3/conf.c +@@ -199,9 +199,6 @@ conf_load_internal(timestamp) + #ifdef USE_DKIM + dkimcheck_clear(); + #endif +-#ifdef USE_P0F +- p0f_clear(); +-#endif + all_list_clear(); + macro_clear(); + acl_clear(); +Index: milter-greylist-4.2.3/p0f.c +=================================================================== +--- milter-greylist-4.2.3.orig/p0f.c ++++ milter-greylist-4.2.3/p0f.c +@@ -98,27 +98,7 @@ struct p0f_response { + /* End of stuff borrowed from p0f/p0f-query.h */ + #endif /* P0F_QUERY_FROM_P0F_DIST */ + +-static int p0f_reconnect(void); +- +-static int p0fsock = -1; +- +-void +-p0f_init(void) +-{ +- return; +-} +- +-void +-p0f_clear(void) +-{ +- if (p0fsock != -1) { +- (void)shutdown(p0fsock, SHUT_RDWR); +- (void)close(p0fsock); +- p0fsock = -1; +- } +- p0f_init(); +- return; +-} ++static int p0f_connect(void); + + int + p0f_cmp(ad, stage, ap, priv) +@@ -166,6 +146,7 @@ p0f_lookup(priv) + char sastr[IPADDRSTRLEN + 1]; + char dastr[IPADDRSTRLEN + 1]; + char dpstr[IPADDRSTRLEN + 1]; ++ int p0fsock; + + /* + * The p0f query interface semms to only support IPv4 +@@ -192,9 +173,6 @@ p0f_lookup(priv) + dport = dpstr; + } + +- if (p0f_reconnect() != 0) +- return -1; +- + memset(&req, 0, sizeof(req)); + memset(&rep, 0, sizeof(rep)); + (void)gettimeofday(&tv, NULL); +@@ -214,19 +192,23 @@ p0f_lookup(priv) + inet_ntop(AF_INET, &req.dst_ad, dastr, IPADDRSTRLEN), + req.dst_port); + ++ p0fsock = p0f_connect(); ++ if (p0fsock < 0) ++ return -1; ++ + if (write(p0fsock, &req ,sizeof(req)) != sizeof(req)) { + mg_log(LOG_ERR, "writing to \"%s\" failed", conf.c_p0fsock); +- p0f_clear(); ++ close(p0fsock); + return -1; + } + + if (read(p0fsock, &rep, sizeof(rep)) != sizeof(rep)) { + mg_log(LOG_ERR, "reading from \"%s\" failed", conf.c_p0fsock); +- p0f_clear(); ++ close(p0fsock); + return -1; + } + +- p0f_clear(); ++ close(p0fsock); + + if (rep.id != req.id) { + mg_log(LOG_ERR, "p0f reply id mismatch %x expected %x", +@@ -277,12 +259,10 @@ p0f_sock_set(sock) + } + + static int +-p0f_reconnect(void) ++p0f_connect(void) + { + struct sockaddr_un sun; +- +- if (p0fsock != -1) +- return 0; ++ int p0fsock; + + if (!conf.c_p0fsock[0]) + return -1; +@@ -307,11 +287,10 @@ p0f_reconnect(void) + mg_log(LOG_ERR, "Cannot connect to p0f socket \"%s\"", + conf.c_p0fsock); + close(p0fsock); +- p0fsock = -1; + return -1; + } + +- return 0; ++ return p0fsock; + } + + #endif /* USE_P0F */ +Index: milter-greylist-4.2.3/p0f.h +=================================================================== +--- milter-greylist-4.2.3.orig/p0f.h ++++ milter-greylist-4.2.3/p0f.h +@@ -34,8 +34,6 @@ + + #include "config.h" + +-void p0f_init(void); +-void p0f_clear(void); + int p0f_cmp(acl_data_t *, acl_stage_t, + struct acl_param *, struct mlfi_priv *); + int p0f_regexec(acl_data_t *, acl_stage_t, diff --git a/milter-greylist.spec b/milter-greylist.spec index e25c33b..02e7bfe 100644 --- a/milter-greylist.spec +++ b/milter-greylist.spec @@ -4,7 +4,9 @@ ## Fedora Extras specific customization below... %bcond_without fedora %bcond_without noarch +%bcond_without upstart %bcond_with spf +%bcond_with libbind ## %{?with_noarch:%global noarch BuildArch: noarch} @@ -16,11 +18,13 @@ %global __chkconfig /sbin/chkconfig %{!?release_func:%global release_func() %1%{?dist}} +%{!?apply:%global apply(p:n:b:) %patch%%{-n:%%{-n*}} %%{-p:-p %%{-p*}} %%{-b:-b %%{-b*}} \ +%nil} Summary: Milter for greylisting, the next step in the spam control war Name: milter-greylist Version: 4.2.3 -Release: %release_func 1300%{?beta} +Release: %release_func 1301%{?beta} License: BSD with advertising Group: System Environment/Daemons URL: http://hcpnet.free.fr/milter-greylist/ @@ -28,6 +32,9 @@ Source0: ftp://ftp.espci.fr/pub/milter-greylist/%name-%version%{?beta}.tgz Source1: README.fedora Patch0: milter-greylist-2.0.2-sysv.patch Patch4: ai_addrconfig.patch +Patch5: milter-greylist-p0f-reentrant.patch +Patch6: milter-greylist-geoip-lock.patch +Patch7: milter-greylist-dkim-reentrant.patch BuildRoot: %_tmppath/%name-%version-%release-root Requires: init(%name) Provides: user(%username) = 7 @@ -36,6 +43,7 @@ BuildRequires: bison flex m4 BuildRequires: sendmail-devel %{?with_spf:libspf-devel} BuildRequires: fedora-usermgmt-devel BuildRequires: curl-devel GeoIP-devel +%{?with_libbind:BuildRequires: %_libdir/libbind.so} %{?FE_USERADD_REQ} %package sysvinit @@ -97,7 +105,10 @@ This package provides the upstart initscripts for the %name package. %prep %setup -q %{?beta:-n %name-%version%beta} %patch0 -p1 -b .sysv -%patch4 -p1 +%apply -n4 -p1 +%apply -n5 -p1 +%apply -n6 -p1 +%apply -n7 -p1 install -p -m0644 %SOURCE1 . @@ -120,8 +131,10 @@ done %define makeflags TEST=false BINDIR=%_sbindir %build -export CPPFLAGS="-DUSE_CURL -DUSE_GEOIP -D_GNU_SOURCE -D_REENTRANT $(pkg-config --cflags-only-I libcurl)" -export LDFLAGS="-Wl,--as-needed $(pkg-config --libs libcurl) -lGeoIP" +_comps="%{?with_libbind:libbind} libcurl" +export CPPFLAGS="-DUSE_CURL -DUSE_GEOIP -D_GNU_SOURCE -D_REENTRANT $(pkg-config --cflags-only-I $_comps)" +export LDFLAGS="-Wl,--as-needed $(pkg-config --libs $_comps) -lGeoIP" + %configure \ --disable-rpath \ --with-user=%username \ @@ -150,6 +163,7 @@ touch $RPM_BUILD_ROOT%_var/run/milter-greylist.pid ## Remove the unwanted init-methods %{?_without_sysv: rm -rf $RPM_BUILD_ROOT%_initrddir} +%{!?with_upstart: rm -rf $RPM_BUILD_ROOT/etc/init} %pre @@ -205,13 +219,19 @@ rm -rf $RPM_BUILD_ROOT %config %_initrddir/* %endif - +%if 0%{?with_upstart:1} %files upstart %defattr(-,root,root,-) %config(noreplace) /etc/init/* +%endif %changelog +* Sat Feb 20 2010 Enrico Scholz - 4.2.3-1301 +- added patches to fix races in dkim, geoip and p0f modules +- conditionalized -upstart subpackage +- added conditional to build it with libbind (required for RHEL5) + * Sun Dec 6 2009 Enrico Scholz - 4.2.3-1300 - updated -upstart to upstart 0.6.3