| @@ -1,29 +1,31 @@ | | | @@ -1,29 +1,31 @@ |
1 | $NetBSD: patch-aa,v 1.4 2010/09/10 23:33:42 gdt Exp $ | | 1 | $NetBSD: patch-aa,v 1.5 2011/03/18 15:26:30 gdt Exp $ |
2 | | | 2 | |
3 | This patch has hunks for three separate reasons: | | 3 | This patch has hunks for multiple reasons: |
4 | | | 4 | |
5 | 1) Ancient fix to avoid going beyond s2. | | 5 | 1) Ancient fix to avoid going beyond s2. |
6 | | | 6 | |
7 | 2) Added CVE-2010-1132 patch from: | | 7 | 2) Added CVE-2010-1132 patch from: |
8 | | | 8 | |
9 | https://bugzilla.redhat.com/attachment.cgi?id=401011 | | 9 | https://bugzilla.redhat.com/attachment.cgi?id=401011 |
10 | | | 10 | |
11 | 3) (Most of, some in .h) patch to add option to not scan mail from | | 11 | 3) (Most of, some in .h) patch to add option to not scan mail from |
12 | authenticated users, from: | | 12 | authenticated users, from: |
13 | | | 13 | |
14 | http://lists.freebsd.org/pipermail/freebsd-ports-bugs/2006-November/106024.html | | 14 | http://lists.freebsd.org/pipermail/freebsd-ports-bugs/2006-November/106024.html |
15 | | | 15 | |
16 | --- spamass-milter.cpp.orig 2010-09-10 15:50:58.000000000 +0000 | | 16 | 4) Avoid memory allocation in after fork and before exec. From PR pkg/44704. |
| | | 17 | |
| | | 18 | --- spamass-milter.cpp.orig 2011-03-18 15:15:56.000000000 +0000 |
17 | +++ spamass-milter.cpp | | 19 | +++ spamass-milter.cpp |
18 | @@ -170,10 +170,7 @@ char *spambucket; | | 20 | @@ -170,10 +170,7 @@ char *spambucket; |
19 | bool flag_full_email = false; /* pass full email address to spamc */ | | 21 | bool flag_full_email = false; /* pass full email address to spamc */ |
20 | bool flag_expand = false; /* alias/virtusertable expansion */ | | 22 | bool flag_expand = false; /* alias/virtusertable expansion */ |
21 | bool warnedmacro = false; /* have we logged that we couldn't fetch a macro? */ | | 23 | bool warnedmacro = false; /* have we logged that we couldn't fetch a macro? */ |
22 | - | | 24 | - |
23 | -#if defined(__FreeBSD__) /* popen bug - see PR bin/50770 */ | | 25 | -#if defined(__FreeBSD__) /* popen bug - see PR bin/50770 */ |
24 | -static pthread_mutex_t popen_mutex = PTHREAD_MUTEX_INITIALIZER; | | 26 | -static pthread_mutex_t popen_mutex = PTHREAD_MUTEX_INITIALIZER; |
25 | -#endif | | 27 | -#endif |
26 | +bool auth = false; /* don't scan authenticated users */ | | 28 | +bool auth = false; /* don't scan authenticated users */ |
27 | | | 29 | |
28 | // {{{ main() | | 30 | // {{{ main() |
29 | | | 31 | |
| @@ -150,45 +152,45 @@ authenticated users, from: | | | @@ -150,45 +152,45 @@ authenticated users, from: |
150 | // launch new SpamAssassin | | 152 | // launch new SpamAssassin |
151 | @@ -842,30 +817,19 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp | | 153 | @@ -842,30 +817,19 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp |
152 | /* open a pipe to sendmail so we can do address expansion */ | | 154 | /* open a pipe to sendmail so we can do address expansion */ |
153 | | | 155 | |
154 | char buf[1024]; | | 156 | char buf[1024]; |
155 | - char *fmt="%s -bv \"%s\" 2>&1"; | | 157 | - char *fmt="%s -bv \"%s\" 2>&1"; |
156 | - | | 158 | - |
157 | -#if defined(HAVE_SNPRINTF) | | 159 | -#if defined(HAVE_SNPRINTF) |
158 | - snprintf(buf, sizeof(buf)-1, fmt, SENDMAIL, envrcpt[0]); | | 160 | - snprintf(buf, sizeof(buf)-1, fmt, SENDMAIL, envrcpt[0]); |
159 | -#else | | 161 | -#else |
160 | - /* XXX possible buffer overflow here */ | | 162 | - /* XXX possible buffer overflow here */ |
161 | - sprintf(buf, fmt, SENDMAIL, envrcpt[0]); | | 163 | - sprintf(buf, fmt, SENDMAIL, envrcpt[0]); |
162 | -#endif | | 164 | -#endif |
163 | - | | | |
164 | - debug(D_RCPT, "calling %s", buf); | | | |
165 | + char *popen_argv[4]; | | 165 | + char *popen_argv[4]; |
166 | + | | 166 | + |
167 | + popen_argv[0] = SENDMAIL; | | 167 | + popen_argv[0] = SENDMAIL; |
168 | + popen_argv[1] = "-bv"; | | 168 | + popen_argv[1] = "-bv"; |
169 | + popen_argv[2] = envrcpt[0]; | | 169 | + popen_argv[2] = envrcpt[0]; |
170 | + popen_argv[3] = NULL; | | 170 | + popen_argv[3] = NULL; |
171 | | | 171 | |
| | | 172 | - debug(D_RCPT, "calling %s", buf); |
| | | 173 | + debug(D_RCPT, "calling %s -bv %s", SENDMAIL, envrcpt[0]); |
| | | 174 | |
172 | -#if defined(__FreeBSD__) /* popen bug - see PR bin/50770 */ | | 175 | -#if defined(__FreeBSD__) /* popen bug - see PR bin/50770 */ |
173 | - rv = pthread_mutex_lock(&popen_mutex); | | 176 | - rv = pthread_mutex_lock(&popen_mutex); |
174 | - if (rv) | | 177 | - if (rv) |
175 | - { | | 178 | - { |
176 | - debug(D_ALWAYS, "Could not lock popen mutex: %s", strerror(rv)); | | 179 | - debug(D_ALWAYS, "Could not lock popen mutex: %s", strerror(rv)); |
177 | - abort(); | | 180 | - abort(); |
178 | - } | | 181 | - } |
179 | -#endif | | 182 | -#endif |
180 | + debug(D_RCPT, "calling %s -bv %s", SENDMAIL, envrcpt[0]); | | 183 | - |
181 | | | | |
182 | - p = popen(buf, "r"); | | 184 | - p = popen(buf, "r"); |
183 | + p = popenv(popen_argv, "r"); | | 185 | + p = popenv(popen_argv, "r"); |
184 | if (!p) | | 186 | if (!p) |
185 | { | | 187 | { |
186 | - debug(D_RCPT, "popen failed(%s). Will not expand aliases", strerror(errno)); | | 188 | - debug(D_RCPT, "popen failed(%s). Will not expand aliases", strerror(errno)); |
187 | + debug(D_RCPT, "popenv failed(%s). Will not expand aliases", strerror(errno)); | | 189 | + debug(D_RCPT, "popenv failed(%s). Will not expand aliases", strerror(errno)); |
188 | assassin->expandedrcpt.push_back(envrcpt[0]); | | 190 | assassin->expandedrcpt.push_back(envrcpt[0]); |
189 | } else | | 191 | } else |
190 | { | | 192 | { |
191 | @@ -890,16 +854,8 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp | | 193 | @@ -890,16 +854,8 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp |
192 | assassin->expandedrcpt.push_back(p+7); | | 194 | assassin->expandedrcpt.push_back(p+7); |
193 | } | | 195 | } |
194 | } | | 196 | } |
| @@ -196,36 +198,95 @@ authenticated users, from: | | | @@ -196,36 +198,95 @@ authenticated users, from: |
196 | + fclose(p); p = NULL; | | 198 | + fclose(p); p = NULL; |
197 | } | | 199 | } |
198 | -#if defined(__FreeBSD__) | | 200 | -#if defined(__FreeBSD__) |
199 | - rv = pthread_mutex_unlock(&popen_mutex); | | 201 | - rv = pthread_mutex_unlock(&popen_mutex); |
200 | - if (rv) | | 202 | - if (rv) |
201 | - { | | 203 | - { |
202 | - debug(D_ALWAYS, "Could not unlock popen mutex: %s", strerror(rv)); | | 204 | - debug(D_ALWAYS, "Could not unlock popen mutex: %s", strerror(rv)); |
203 | - abort(); | | 205 | - abort(); |
204 | - } | | 206 | - } |
205 | -#endif | | 207 | -#endif |
206 | } else | | 208 | } else |
207 | { | | 209 | { |
208 | assassin->expandedrcpt.push_back(envrcpt[0]); | | 210 | assassin->expandedrcpt.push_back(envrcpt[0]); |
209 | @@ -2033,7 +1989,7 @@ cmp_nocase_partial(const string& s, cons | | 211 | @@ -1343,6 +1299,22 @@ SpamAssassin::~SpamAssassin() |
| | | 212 | |
| | | 213 | void SpamAssassin::Connect() |
| | | 214 | { |
| | | 215 | + int argc; |
| | | 216 | + char *argv[100]; |
| | | 217 | + char spamc_user[64]; |
| | | 218 | + |
| | | 219 | + if (expandedrcpt.size() != 1) { |
| | | 220 | + debug(D_RCPT, "%d recipients; spamc gets default username %s", (int)expandedrcpt.size(), defaultuser); |
| | | 221 | + strlcpy(spamc_user, defaultuser, sizeof(spamc_user)); |
| | | 222 | + } else { |
| | | 223 | + if (flag_full_email) |
| | | 224 | + strlcpy(spamc_user, full_user().c_str(), sizeof(spamc_user)); |
| | | 225 | + else |
| | | 226 | + strlcpy(spamc_user, local_user().c_str(), sizeof(spamc_user)); |
| | | 227 | + strlwr(spamc_user); |
| | | 228 | + debug(D_RCPT, "spamc gets %s", spamc_user); |
| | | 229 | + } |
| | | 230 | + |
| | | 231 | // set up pipes for in- and output |
| | | 232 | if (pipe(pipe_io[0])) |
| | | 233 | throw string(string("pipe error: ")+string(strerror(errno))); |
| | | 234 | @@ -1376,33 +1348,12 @@ void SpamAssassin::Connect() |
| | | 235 | // absolute path (determined in autoconf) |
| | | 236 | // should be a little more secure |
| | | 237 | // XXX arbitrary 100-argument max |
| | | 238 | - int argc = 0; |
| | | 239 | - char** argv = (char**) malloc(100*sizeof(char*)); |
| | | 240 | + argc = 0; |
| | | 241 | argv[argc++] = SPAMC; |
| | | 242 | if (flag_sniffuser) |
| | | 243 | { |
| | | 244 | argv[argc++] = "-u"; |
| | | 245 | - if ( expandedrcpt.size() != 1 ) |
| | | 246 | - { |
| | | 247 | - // More (or less?) than one recipient, so we pass the default |
| | | 248 | - // username to SPAMC. This way special rules can be defined for |
| | | 249 | - // multi recipient messages. |
| | | 250 | - debug(D_RCPT, "%d recipients; spamc gets default username %s", (int)expandedrcpt.size(), defaultuser); |
| | | 251 | - argv[argc++] = defaultuser; |
| | | 252 | - } else |
| | | 253 | - { |
| | | 254 | - // There is only 1 recipient so we pass the username |
| | | 255 | - // (converted to lowercase) to SPAMC. Don't worry about |
| | | 256 | - // freeing this memory as we're exec()ing anyhow. |
| | | 257 | - if (flag_full_email) |
| | | 258 | - argv[argc] = strlwr(strdup(full_user().c_str())); |
| | | 259 | - else |
| | | 260 | - argv[argc] = strlwr(strdup(local_user().c_str())); |
| | | 261 | - |
| | | 262 | - debug(D_RCPT, "spamc gets %s", argv[argc]); |
| | | 263 | - |
| | | 264 | - argc++; |
| | | 265 | - } |
| | | 266 | + argv[argc++] = spamc_user; |
| | | 267 | } |
| | | 268 | if (spamdhost) |
| | | 269 | { |
| | | 270 | @@ -2033,7 +1984,7 @@ cmp_nocase_partial(const string& s, cons |
210 | string::const_iterator p=s.begin(); | | 271 | string::const_iterator p=s.begin(); |
211 | string::const_iterator p2=s2.begin(); | | 272 | string::const_iterator p2=s2.begin(); |
212 | | | 273 | |
213 | - while ( p != s.end() && p2 <= s2.end() ) { | | 274 | - while ( p != s.end() && p2 <= s2.end() ) { |
214 | + while ( p != s.end() ) { | | 275 | + while ( p != s.end() ) { |
215 | if (toupper(*p) != toupper(*p2)) | | 276 | if (toupper(*p) != toupper(*p2)) |
216 | { | | 277 | { |
217 | debug(D_STR, "c_nc_p: <%s><%s> : miss", s.c_str(), s2.c_str()); | | 278 | debug(D_STR, "c_nc_p: <%s><%s> : miss", s.c_str(), s2.c_str()); |
218 | @@ -2157,5 +2113,71 @@ void warnmacro(char *macro, char *scope) | | 279 | @@ -2157,5 +2108,71 @@ void warnmacro(char *macro, char *scope) |
219 | warnedmacro = true; | | 280 | warnedmacro = true; |
220 | } | | 281 | } |
221 | | | 282 | |
222 | +/* | | 283 | +/* |
223 | + untrusted-argument-safe popen function - only supports "r" and "w" modes | | 284 | + untrusted-argument-safe popen function - only supports "r" and "w" modes |
224 | + for simplicity, and always reads stdout and stderr in "r" mode. Call | | 285 | + for simplicity, and always reads stdout and stderr in "r" mode. Call |
225 | + fclose to close the FILE. | | 286 | + fclose to close the FILE. |
226 | +*/ | | 287 | +*/ |
227 | +FILE *popenv(char *const argv[], const char *type) | | 288 | +FILE *popenv(char *const argv[], const char *type) |
228 | +{ | | 289 | +{ |
229 | + FILE *iop; | | 290 | + FILE *iop; |
230 | + int pdes[2]; | | 291 | + int pdes[2]; |
231 | + int save_errno; | | 292 | + int save_errno; |