diff -u libspf2-1.2.5.dfsg/debian/patches/42_empty_sender.dpatch libspf2-1.2.5.dfsg/debian/patches/42_empty_sender.dpatch --- libspf2-1.2.5.dfsg/debian/patches/42_empty_sender.dpatch +++ libspf2-1.2.5.dfsg/debian/patches/42_empty_sender.dpatch @@ -22,10 +22,10 @@ sr->env_from = strdup(from); - sr->env_from_lp = strdup(from); /* Too long, but simple */ - sr->env_from_lp[(cp - from)] = '\0'; -+ *cp = '\0'; -+ sr->env_from_lp = strdup(from); ++ sr->env_from[cp - from] = '\0'; ++ sr->env_from_lp = strdup(sr->env_from); sr->env_from_dp = strdup(cp + 1); -+ *cp = '@'; ++ sr->env_from[cp - from] = '@'; } else { + if (cp == from) from++; /* "@domain.example" */ diff -u libspf2-1.2.5.dfsg/debian/patches/00list libspf2-1.2.5.dfsg/debian/patches/00list --- libspf2-1.2.5.dfsg/debian/patches/00list +++ libspf2-1.2.5.dfsg/debian/patches/00list @@ -16,0 +17,2 @@ +51_actually-keep-track-of-max_var_len +52_compile_bufoverflow diff -u libspf2-1.2.5.dfsg/debian/changelog libspf2-1.2.5.dfsg/debian/changelog --- libspf2-1.2.5.dfsg/debian/changelog +++ libspf2-1.2.5.dfsg/debian/changelog @@ -1,3 +1,19 @@ +libspf2 (1.2.5.dfsg-4ubuntu0.7.10.2) gutsy-security; urgency=high + + * SECURITY UPDATE: + * 51_actually-keep-track-of-max_var_len.dpatch: Fix possible DoS with + long sender addresses. Thanks to Hannah Schroeter. + * 52_compile_bufoverflow.dpatch: Prevent buffer overflows in SPF_compile + from mechanisms with huge domainspecs. Workaround suggested by + upstream. Limits the size of mechanisms and modifiers, but that + shouldn't be a problem in practice. + * 42_empty_sender.dpatch could previously cause segfaults by trying to + write to a constant string. Fixed. + * Thanks to Magnus Holmgren for the fixes + * Thanks to Michael Casadevall for testing + + -- Scott Kitterman Mon, 10 Nov 2008 00:17:44 -0500 + libspf2 (1.2.5.dfsg-4ubuntu0.7.10.1) gutsy-security; urgency=high * SECURITY UPDATE: only in patch2: unchanged: --- libspf2-1.2.5.dfsg.orig/debian/patches/52_compile_bufoverflow.dpatch +++ libspf2-1.2.5.dfsg/debian/patches/52_compile_bufoverflow.dpatch @@ -0,0 +1,30 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 52_compile_bufoverflow.dpatch by Magnus Holmgren +## +## DP: Prevent buffer overflows from mechanisms with huge domainspecs. +## DP: As suggested by upstream. + +@DPATCH@ +diff -urNad lenny~/src/libspf2/spf_compile.c lenny/src/libspf2/spf_compile.c +--- lenny~/src/libspf2/spf_compile.c 2008-11-04 21:51:22.000000000 +0100 ++++ lenny/src/libspf2/spf_compile.c 2008-11-04 21:53:22.000000000 +0100 +@@ -711,6 +711,9 @@ + + SPF_errcode_t err; + ++ if (strlen(*mech_value) > (sizeof(buf) >> 1)) ++ return SPF_E_BIG_MECH; ++ + memset(buf, 'B', sizeof(buf)); /* Poison the buffer. */ + memset(spf_mechanism, 0, sizeof(SPF_mech_t)); + +@@ -858,6 +861,9 @@ + + SPF_errcode_t err; + ++ if (strlen(*mod_value) > (sizeof(buf) >> 1)) ++ return SPF_E_BIG_MOD; ++ + memset(buf, 'A', sizeof(buf)); + memset(spf_modifier, 0, sizeof(SPF_mod_t)); + only in patch2: unchanged: --- libspf2-1.2.5.dfsg.orig/debian/patches/51_actually-keep-track-of-max_var_len.dpatch +++ libspf2-1.2.5.dfsg/debian/patches/51_actually-keep-track-of-max_var_len.dpatch @@ -0,0 +1,144 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 51_actually-keep-track-of-max_var_len.dpatch by Hannah Schroeter +## +## DP: actually keep track of max_var_len so SPF_record_expand_data doesn't fail +## DP: and abort the whole program on some cases, e.g. creating the Received-SPF +## DP: header when the envelope from is very long. +## +## src/libspf2/spf_request.c | 50 +++++++++++++++++++++++++++++++++++++++++++- +## 1 files changed, 48 insertions(+), 2 deletions(-) + +@DPATCH@ +diff --git a/src/libspf2/spf_request.c b/src/libspf2/spf_request.c +index 181b0e4..cf6c39b 100644 +--- a/src/libspf2/spf_request.c ++++ b/src/libspf2/spf_request.c +@@ -41,6 +41,7 @@ SPF_request_t * + SPF_request_new(SPF_server_t *spf_server) + { + SPF_request_t *sr; ++ const char *rec_dom; + + sr = (SPF_request_t *)malloc(sizeof(SPF_request_t)); + if (! sr) +@@ -51,6 +52,9 @@ SPF_request_new(SPF_server_t *spf_server) + sr->client_ver = AF_UNSPEC; + sr->ipv4.s_addr = htonl(INADDR_ANY); + sr->ipv6 = in6addr_any; ++ rec_dom = SPF_request_get_rec_dom(sr); ++ if (rec_dom) ++ sr->max_var_len = strlen(rec_dom); + + return sr; + } +@@ -116,9 +120,15 @@ SPF_request_set_ipv6_str(SPF_request_t *sr, const char *astr) + SPF_errcode_t + SPF_request_set_helo_dom(SPF_request_t *sr, const char *dom) + { ++ size_t len; + SPF_ASSERT_NOTNULL(dom); + SPF_FREE(sr->helo_dom); + sr->helo_dom = strdup(dom); ++ if (! sr->helo_dom) ++ return SPF_E_NO_MEMORY; ++ len = strlen(dom); ++ if (len > sr->max_var_len) ++ sr->max_var_len = len; + /* set cur_dom and env_from? */ + if (sr->env_from == NULL) + return SPF_request_set_env_from(sr, dom); +@@ -130,16 +138,24 @@ SPF_request_set_helo_dom(SPF_request_t *sr, const char *dom) + const char * + SPF_request_get_rec_dom(SPF_request_t *sr) + { ++ char *result; ++ size_t len; + SPF_server_t *spf_server; + spf_server = sr->spf_server; +- return spf_server->rec_dom; ++ result = spf_server->rec_dom; ++ if (result) { ++ len = strlen(result); ++ if (len > sr->max_var_len) ++ sr->max_var_len = len; ++ } ++ return result; + } + + int + SPF_request_set_env_from(SPF_request_t *sr, const char *from) + { + char *cp; +- int len; ++ size_t len; + + SPF_ASSERT_NOTNULL(from); + SPF_FREE(sr->env_from); +@@ -187,6 +203,10 @@ SPF_request_set_env_from(SPF_request_t *sr, const char *from) + } + } + ++ len = strlen(sr->env_from); ++ if (sr->max_var_len < len) ++ sr->max_var_len = len; ++ + return 0; + } + +@@ -200,8 +220,12 @@ SPF_request_get_client_dom(SPF_request_t *sr) + SPF_ASSERT_NOTNULL(spf_server); + + if (sr->client_dom == NULL) { ++ size_t len; + sr->client_dom = SPF_dns_get_client_dom(spf_server->resolver, + sr); ++ len = strlen(sr->client_dom); ++ if (len > sr->max_var_len) ++ sr->max_var_len = len; + } + return sr->client_dom; + } +@@ -225,6 +249,16 @@ SPF_request_is_loopback(SPF_request_t *sr) + static SPF_errcode_t + SPF_request_prepare(SPF_request_t *sr) + { ++ const char *rec_dom; ++ size_t len; ++ ++ /* SPF_request_get_rec_dom result could have changed */ ++ rec_dom = SPF_request_get_rec_dom(sr); ++ if (rec_dom) { ++ len = strlen(rec_dom); ++ if (len > sr->max_var_len) ++ sr->max_var_len = len; ++ } + if (sr->use_helo) + sr->cur_dom = sr->helo_dom; + else +@@ -241,11 +275,23 @@ SPF_request_query_record(SPF_request_t *spf_request, + SPF_record_t *spf_record, + SPF_errcode_t err) + { ++ const char *rec_dom; ++ size_t len; ++ + if (err != SPF_E_SUCCESS) { + if (spf_record) + SPF_record_free(spf_record); + return err; + } ++ ++ /* SPF_request_get_rec_dom result could have changed */ ++ rec_dom = SPF_request_get_rec_dom(spf_request); ++ if (rec_dom) { ++ len = strlen(rec_dom); ++ if (len > spf_request->max_var_len) ++ spf_request->max_var_len = len; ++ } ++ + /* Now, in theory, SPF_response_errors(spf_response) == 0 */ + if (SPF_response_errors(spf_response) > 0) + SPF_infof("Warning: %d errors in response, " +-- +1.5.6.4 +