Commit ec06293134b85876f9201d8a52b844c41581b2b3
- Diff rendering mode:
- inline
- side by side
Makefile.am
(1 / 0)
|   | |||
| 126 | 126 | fetchmail-features.html README.SSL README.NTLM \ | |
| 127 | 127 | README.packaging README.SSL-SERVER \ | |
| 128 | 128 | fetchmail-FAQ.book fetchmail-FAQ.pdf fetchmail-FAQ.html \ | |
| 129 | fetchmail-SA-2010-02.txt \ | ||
| 129 | 130 | fetchmail-SA-2010-01.txt \ | |
| 130 | 131 | fetchmail-SA-2009-01.txt \ | |
| 131 | 132 | fetchmail-SA-2008-01.txt \ |
NEWS
(8 / 0)
|   | |||
| 54 | 54 | ||
| 55 | 55 | fetchmail-6.3.17 (not yet released): | |
| 56 | 56 | ||
| 57 | # SECURITY FIX | ||
| 58 | * Fetchmail before release 6.3.17 did not properly sanitize external input | ||
| 59 | (mail headers and UID). When a multi-character locale (such as UTF-8) was in use, | ||
| 60 | this could cause memory exhaustion and thus a denial of service, because | ||
| 61 | fetchmail's report.c functions assumed that non-success of [v]snprintf was | ||
| 62 | due to insufficient buffer size allocation. It would then repeatedly reallocate | ||
| 63 | a larger buffer and fail formatting again. See fetchmail-SA-2010-02.txt. | ||
| 64 | |||
| 57 | 65 | # REGRESSION FIX | |
| 58 | 66 | * Fix string handling in rcfile scanner, which caused fetchmail to misparse a | |
| 59 | 67 | run control file in certain circumstances. Fixes BerliOS bug #14257. |
fetchmail-SA-2010-02.txt
(209 / 0)
|   | |||
| 1 | - DRAFT - XXX - DRAFT - | ||
| 2 | |||
| 3 | fetchmail-SA-2010-02: Denial of service in debug mode w/ multichar locales | ||
| 4 | |||
| 5 | Topics: Denial of service in debug output. | ||
| 6 | |||
| 7 | Author: Matthias Andree | ||
| 8 | Version: 0.1 XXX | ||
| 9 | Announced: XXX | ||
| 10 | Type: malloc() Buffer overrun with printable characters | ||
| 11 | Impact: Denial of service. | ||
| 12 | Danger: low | ||
| 13 | |||
| 14 | CVE Name: CVE-2010-XXXX | ||
| 15 | CVSSv2: XXX | ||
| 16 | URL: http://www.fetchmail.info/fetchmail-SA-2010-02.txt | ||
| 17 | Project URL: http://www.fetchmail.info/ | ||
| 18 | |||
| 19 | Affects: fetchmail releases 4.6.3 up to and including 6.3.16 | ||
| 20 | |||
| 21 | Not affected: fetchmail release 6.3.17 and newer | ||
| 22 | |||
| 23 | Corrected: 2010-04-18 Git (XXX) | ||
| 24 | |||
| 25 | |||
| 26 | 0. Release history | ||
| 27 | ================== | ||
| 28 | |||
| 29 | 2010-04-18 0.1 first draft (visible in SVN and through oss-security) | ||
| 30 | XXX | ||
| 31 | |||
| 32 | |||
| 33 | 1. Background | ||
| 34 | ============= | ||
| 35 | |||
| 36 | fetchmail is a software package to retrieve mail from remote POP2, POP3, | ||
| 37 | IMAP, ETRN or ODMR servers and forward it to local SMTP, LMTP servers or | ||
| 38 | message delivery agents. It supports SSL and TLS security layers through | ||
| 39 | the OpenSSL library, if enabled at compile time and if also enabled at | ||
| 40 | run time. | ||
| 41 | |||
| 42 | |||
| 43 | 2. Problem description and Impact | ||
| 44 | ================================= | ||
| 45 | |||
| 46 | In debug mode (-v -v), fetchmail prints information that was obtained from the | ||
| 47 | upstream server (POP3 UIDL lists) or from message headers retrieved from it. | ||
| 48 | If printing such information fails, for instance because there are invalid | ||
| 49 | multibyte character sequences in this information (message headers), fetchmail | ||
| 50 | will misinterpret this condition, and believe that the buffer was too small, | ||
| 51 | and reallocate a bigger one (with linearly increasing buffer size), and repeat, | ||
| 52 | until the allocation fails. At that point, fetchmail will abort. | ||
| 53 | |||
| 54 | Note that the "Affects:" line above may be inaccurate, and it may be that | ||
| 55 | versions before 5.6.6 are actually unaffected. The author was unable to | ||
| 56 | compile such old fetchmail versions to verify the existence of the bug. | ||
| 57 | Given that other security issues are present in such versions, those should | ||
| 58 | not be used, and the wider version range was listed as vulnerable to err | ||
| 59 | towards the safe. | ||
| 60 | |||
| 61 | |||
| 62 | 3. Solution | ||
| 63 | =========== | ||
| 64 | |||
| 65 | There are two alternatives, either of them by itself is sufficient: | ||
| 66 | |||
| 67 | a. Apply the patch found in section B of this announcement to | ||
| 68 | fetchmail 6.3.14 or newer, recompile and reinstall it. | ||
| 69 | |||
| 70 | b. Install fetchmail 6.3.17 or newer after it will have become available. | ||
| 71 | The fetchmail source code is always available from | ||
| 72 | <http://developer.berlios.de/project/showfiles.php?group_id=1824>. | ||
| 73 | |||
| 74 | |||
| 75 | 4. Workaround | ||
| 76 | ============= | ||
| 77 | |||
| 78 | Run fetchmail with at most one -v (--verbose) option. | ||
| 79 | |||
| 80 | |||
| 81 | A. Copyright, License and Warranty | ||
| 82 | ================================== | ||
| 83 | |||
| 84 | (C) Copyright 2010 by Matthias Andree, <matthias.andree@gmx.de>. | ||
| 85 | Some rights reserved. | ||
| 86 | |||
| 87 | This work is licensed under the Creative Commons | ||
| 88 | Attribution-Noncommercial-No Derivative Works 3.0 Germany License. | ||
| 89 | To view a copy of this license, visit | ||
| 90 | http://creativecommons.org/licenses/by-nc-nd/3.0/de/ or send a letter to | ||
| 91 | |||
| 92 | Creative Commons | ||
| 93 | 171 Second Street | ||
| 94 | Suite 300 | ||
| 95 | SAN FRANCISCO, CALIFORNIA 94105 | ||
| 96 | USA | ||
| 97 | |||
| 98 | |||
| 99 | THIS WORK IS PROVIDED FREE OF CHARGE AND WITHOUT ANY WARRANTIES. | ||
| 100 | Use the information herein at your own risk. | ||
| 101 | |||
| 102 | |||
| 103 | B. Patch to remedy the problem | ||
| 104 | ============================== | ||
| 105 | |||
| 106 | Note that when taking this from a GnuPG clearsigned file, the lines | ||
| 107 | starting with a "-" character are prefixed by another "- " (dash + | ||
| 108 | blank) combination. Either feed this file through GnuPG to strip them, | ||
| 109 | or strip them manually. You may want to use the "-p1" flag to patch. | ||
| 110 | |||
| 111 | Whitespace differences can usually be ignored by invoking "patch -l", | ||
| 112 | so try this if the patch does not apply. | ||
| 113 | |||
| 114 | diff --git a/rfc822.c b/rfc822.c | ||
| 115 | index 6f2dbf3..dbcda32 100644 | ||
| 116 | --- a/rfc822.c | ||
| 117 | +++ b/rfc822.c | ||
| 118 | @@ -25,6 +25,7 @@ MIT license. Compile with -DMAIN to build the demonstrator. | ||
| 119 | #include <stdlib.h> | ||
| 120 | |||
| 121 | #include "fetchmail.h" | ||
| 122 | +#include "sdump.h" | ||
| 123 | |||
| 124 | #ifndef MAIN | ||
| 125 | #include "i18n.h" | ||
| 126 | @@ -74,9 +75,10 @@ char *reply_hack( | ||
| 127 | } | ||
| 128 | |||
| 129 | #ifndef MAIN | ||
| 130 | - if (outlevel >= O_DEBUG) | ||
| 131 | - report_build(stdout, GT_("About to rewrite %.*s...\n"), | ||
| 132 | - (int)BEFORE_EOL(buf), buf); | ||
| 133 | + if (outlevel >= O_DEBUG) { | ||
| 134 | + report_build(stdout, GT_("About to rewrite %s...\n"), (cp = sdump(buf, BEFORE_EOL(buf)))); | ||
| 135 | + xfree(cp); | ||
| 136 | + } | ||
| 137 | |||
| 138 | /* make room to hack the address; buf must be malloced */ | ||
| 139 | for (cp = buf; *cp; cp++) | ||
| 140 | @@ -211,9 +213,12 @@ char *reply_hack( | ||
| 141 | } | ||
| 142 | |||
| 143 | #ifndef MAIN | ||
| 144 | - if (outlevel >= O_DEBUG) | ||
| 145 | - report_complete(stdout, GT_("...rewritten version is %.*s.\n"), | ||
| 146 | - (int)BEFORE_EOL(buf), buf); | ||
| 147 | + if (outlevel >= O_DEBUG) { | ||
| 148 | + report_complete(stdout, GT_("...rewritten version is %s.\n"), | ||
| 149 | + (cp = sdump(buf, BEFORE_EOL(buf)))); | ||
| 150 | + xfree(cp) | ||
| 151 | + } | ||
| 152 | + | ||
| 153 | #endif /* MAIN */ | ||
| 154 | *length = strlen(buf); | ||
| 155 | return(buf); | ||
| 156 | diff --git a/uid.c b/uid.c | ||
| 157 | index fdc6f5d..d813bee 100644 | ||
| 158 | --- a/uid.c | ||
| 159 | +++ b/uid.c | ||
| 160 | @@ -20,6 +20,7 @@ | ||
| 161 | |||
| 162 | #include "fetchmail.h" | ||
| 163 | #include "i18n.h" | ||
| 164 | +#include "sdump.h" | ||
| 165 | |||
| 166 | /* | ||
| 167 | * Machinery for handling UID lists live here. This is mainly to support | ||
| 168 | @@ -260,8 +261,11 @@ void initialize_saved_lists(struct query *hostlist, const char *idfile) | ||
| 169 | if (uidlcount) | ||
| 170 | { | ||
| 171 | report_build(stdout, GT_("Scratch list of UIDs:")); | ||
| 172 | - for (idp = scratchlist; idp; idp = idp->next) | ||
| 173 | - report_build(stdout, " %s", idp->id); | ||
| 174 | + for (idp = scratchlist; idp; idp = idp->next) { | ||
| 175 | + char *t = sdump(idp->id, strlen(idp->id)); | ||
| 176 | + report_build(stdout, " %s", t); | ||
| 177 | + free(t); | ||
| 178 | + } | ||
| 179 | if (!idp) | ||
| 180 | report_build(stdout, GT_(" <empty>")); | ||
| 181 | report_complete(stdout, "\n"); | ||
| 182 | @@ -517,8 +521,11 @@ void uid_swap_lists(struct query *ctl) | ||
| 183 | report_build(stdout, GT_("Merged UID list from %s:"), ctl->server.pollname); | ||
| 184 | else | ||
| 185 | report_build(stdout, GT_("New UID list from %s:"), ctl->server.pollname); | ||
| 186 | - for (idp = dofastuidl ? ctl->oldsaved : ctl->newsaved; idp; idp = idp->next) | ||
| 187 | - report_build(stdout, " %s = %d", idp->id, idp->val.status.mark); | ||
| 188 | + for (idp = dofastuidl ? ctl->oldsaved : ctl->newsaved; idp; idp = idp->next) { | ||
| 189 | + char *t = sdump(idp->id, strlen(idp->id)); | ||
| 190 | + report_build(stdout, " %s = %d", t, idp->val.status.mark); | ||
| 191 | + free(t); | ||
| 192 | + } | ||
| 193 | if (!idp) | ||
| 194 | report_build(stdout, GT_(" <empty>")); | ||
| 195 | report_complete(stdout, "\n"); | ||
| 196 | @@ -567,8 +574,11 @@ void uid_discard_new_list(struct query *ctl) | ||
| 197 | /* this is now a merged list! the mails which were seen in this | ||
| 198 | * poll are marked here. */ | ||
| 199 | report_build(stdout, GT_("Merged UID list from %s:"), ctl->server.pollname); | ||
| 200 | - for (idp = ctl->oldsaved; idp; idp = idp->next) | ||
| 201 | - report_build(stdout, " %s = %d", idp->id, idp->val.status.mark); | ||
| 202 | + for (idp = ctl->oldsaved; idp; idp = idp->next) { | ||
| 203 | + char *t = sdump(idp->id, strlen(idp->id)); | ||
| 204 | + report_build(stdout, " %s = %d", t, idp->val.status.mark); | ||
| 205 | + free(t); | ||
| 206 | + } | ||
| 207 | if (!idp) | ||
| 208 | report_build(stdout, GT_(" <empty>")); | ||
| 209 | report_complete(stdout, "\n"); |
rfc822.c
(11 / 6)
|   | |||
| 25 | 25 | #include <stdlib.h> | |
| 26 | 26 | ||
| 27 | 27 | #include "fetchmail.h" | |
| 28 | #include "sdump.h" | ||
| 28 | 29 | ||
| 29 | 30 | #ifndef MAIN | |
| 30 | 31 | #include "i18n.h" | |
| … | … | ||
| 75 | 75 | } | |
| 76 | 76 | ||
| 77 | 77 | #ifndef MAIN | |
| 78 | if (outlevel >= O_DEBUG) | ||
| 79 | report_build(stdout, GT_("About to rewrite %.*s...\n"), | ||
| 80 | (int)BEFORE_EOL(buf), buf); | ||
| 78 | if (outlevel >= O_DEBUG) { | ||
| 79 | report_build(stdout, GT_("About to rewrite %s...\n"), (cp = sdump(buf, BEFORE_EOL(buf)))); | ||
| 80 | xfree(cp); | ||
| 81 | } | ||
| 81 | 82 | ||
| 82 | 83 | /* make room to hack the address; buf must be malloced */ | |
| 83 | 84 | for (cp = buf; *cp; cp++) | |
| … | … | ||
| 213 | 213 | } | |
| 214 | 214 | ||
| 215 | 215 | #ifndef MAIN | |
| 216 | if (outlevel >= O_DEBUG) | ||
| 217 | report_complete(stdout, GT_("...rewritten version is %.*s.\n"), | ||
| 218 | (int)BEFORE_EOL(buf), buf); | ||
| 216 | if (outlevel >= O_DEBUG) { | ||
| 217 | report_complete(stdout, GT_("...rewritten version is %s.\n"), | ||
| 218 | (cp = sdump(buf, BEFORE_EOL(buf)))); | ||
| 219 | xfree(cp) | ||
| 220 | } | ||
| 221 | |||
| 219 | 222 | #endif /* MAIN */ | |
| 220 | 223 | *length = strlen(buf); | |
| 221 | 224 | return(buf); |
uid.c
(16 / 6)
|   | |||
| 20 | 20 | ||
| 21 | 21 | #include "fetchmail.h" | |
| 22 | 22 | #include "i18n.h" | |
| 23 | #include "sdump.h" | ||
| 23 | 24 | ||
| 24 | 25 | /* | |
| 25 | 26 | * Machinery for handling UID lists live here. This is mainly to support | |
| … | … | ||
| 261 | 261 | if (uidlcount) | |
| 262 | 262 | { | |
| 263 | 263 | report_build(stdout, GT_("Scratch list of UIDs:")); | |
| 264 | for (idp = scratchlist; idp; idp = idp->next) | ||
| 265 | report_build(stdout, " %s", idp->id); | ||
| 264 | for (idp = scratchlist; idp; idp = idp->next) { | ||
| 265 | char *t = sdump(idp->id, strlen(idp->id)); | ||
| 266 | report_build(stdout, " %s", t); | ||
| 267 | free(t); | ||
| 268 | } | ||
| 266 | 269 | if (!idp) | |
| 267 | 270 | report_build(stdout, GT_(" <empty>")); | |
| 268 | 271 | report_complete(stdout, "\n"); | |
| … | … | ||
| 521 | 521 | report_build(stdout, GT_("Merged UID list from %s:"), ctl->server.pollname); | |
| 522 | 522 | else | |
| 523 | 523 | report_build(stdout, GT_("New UID list from %s:"), ctl->server.pollname); | |
| 524 | for (idp = dofastuidl ? ctl->oldsaved : ctl->newsaved; idp; idp = idp->next) | ||
| 525 | report_build(stdout, " %s = %d", idp->id, idp->val.status.mark); | ||
| 524 | for (idp = dofastuidl ? ctl->oldsaved : ctl->newsaved; idp; idp = idp->next) { | ||
| 525 | char *t = sdump(idp->id, strlen(idp->id)); | ||
| 526 | report_build(stdout, " %s = %d", t, idp->val.status.mark); | ||
| 527 | free(t); | ||
| 528 | } | ||
| 526 | 529 | if (!idp) | |
| 527 | 530 | report_build(stdout, GT_(" <empty>")); | |
| 528 | 531 | report_complete(stdout, "\n"); | |
| … | … | ||
| 574 | 574 | /* this is now a merged list! the mails which were seen in this | |
| 575 | 575 | * poll are marked here. */ | |
| 576 | 576 | report_build(stdout, GT_("Merged UID list from %s:"), ctl->server.pollname); | |
| 577 | for (idp = ctl->oldsaved; idp; idp = idp->next) | ||
| 578 | report_build(stdout, " %s = %d", idp->id, idp->val.status.mark); | ||
| 577 | for (idp = ctl->oldsaved; idp; idp = idp->next) { | ||
| 578 | char *t = sdump(idp->id, strlen(idp->id)); | ||
| 579 | report_build(stdout, " %s = %d", t, idp->val.status.mark); | ||
| 580 | free(t); | ||
| 581 | } | ||
| 579 | 582 | if (!idp) | |
| 580 | 583 | report_build(stdout, GT_(" <empty>")); | |
| 581 | 584 | report_complete(stdout, "\n"); |

