Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 310049 | Differences between
and this patch

Collapse All | Expand All

(-)spamass-milter.cpp (-77 / +85 lines)
Lines 171-180 Link Here
171
bool flag_expand = false;	/* alias/virtusertable expansion */
171
bool flag_expand = false;	/* alias/virtusertable expansion */
172
bool warnedmacro = false;	/* have we logged that we couldn't fetch a macro? */
172
bool warnedmacro = false;	/* have we logged that we couldn't fetch a macro? */
173
173
174
#if defined(__FreeBSD__) /* popen bug - see PR bin/50770 */
175
static pthread_mutex_t popen_mutex = PTHREAD_MUTEX_INITIALIZER;
176
#endif
177
178
// {{{ main()
174
// {{{ main()
179
175
180
int
176
int
Lines 461-519 Link Here
461
			   send another copy.  The milter API will not let you send the
457
			   send another copy.  The milter API will not let you send the
462
			   message AND return a failure code to the sender, so this is
458
			   message AND return a failure code to the sender, so this is
463
			   the only way to do it. */
459
			   the only way to do it. */
464
#if defined(__FreeBSD__)
460
			char *popen_argv[3];
465
			int rv;
466
#endif
467
			
468
#if defined(HAVE_ASPRINTF)
469
			char *buf;
470
#else
471
			char buf[1024];
472
#endif
473
			char *fmt="%s \"%s\"";
474
			FILE *p;
461
			FILE *p;
475
462
476
#if defined(HAVE_ASPRINTF)
463
			popen_argv[0] = SENDMAIL;
477
			asprintf(&buf, fmt, SENDMAIL, spambucket);
464
			popen_argv[1] = spambucket;
478
#else
465
			popen_argv[2] = NULL;
479
#if defined(HAVE_SNPRINTF)
466
			
480
			snprintf(buf, sizeof(buf)-1, fmt, SENDMAIL, spambucket);
467
			debug(D_COPY, "calling %s %s", SENDMAIL, spambucket);
481
#else
468
			p = popenv(popen_argv, "w");
482
			/* XXX possible buffer overflow here */
483
			sprintf(buf, fmt, SENDMAIL, spambucket);
484
#endif
485
#endif
486
487
			debug(D_COPY, "calling %s", buf);
488
#if defined(__FreeBSD__) /* popen bug - see PR bin/50770 */
489
			rv = pthread_mutex_lock(&popen_mutex);
490
			if (rv)
491
			{
492
				debug(D_ALWAYS, "Could not lock popen mutex: %s", strerror(rv));
493
				abort();
494
			}		
495
#endif
496
			p = popen(buf, "w");
497
			if (!p)
469
			if (!p)
498
			{
470
			{
499
				debug(D_COPY, "popen failed(%s).  Will not send a copy to spambucket", strerror(errno));
471
				debug(D_COPY, "popenv failed(%s).  Will not send a copy to spambucket", strerror(errno));
500
			} else
472
			} else
501
			{
473
			{
502
				// Send message provided by SpamAssassin
474
				// Send message provided by SpamAssassin
503
				fwrite(assassin->d().c_str(), assassin->d().size(), 1, p);
475
				fwrite(assassin->d().c_str(), assassin->d().size(), 1, p);
504
				pclose(p); p = NULL;
476
				fclose(p); p = NULL;
505
			}
477
			}
506
#if defined(__FreeBSD__)
507
			rv = pthread_mutex_unlock(&popen_mutex);
508
			if (rv)
509
			{
510
				debug(D_ALWAYS, "Could not unlock popen mutex: %s", strerror(rv));
511
				abort();
512
			}		
513
#endif
514
#if defined(HAVE_ASPRINTF)
515
			free(buf);
516
#endif 
517
		}
478
		}
518
		return SMFIS_REJECT;
479
		return SMFIS_REJECT;
519
	}
480
	}
Lines 842-871 Link Here
842
		/* open a pipe to sendmail so we can do address expansion */
803
		/* open a pipe to sendmail so we can do address expansion */
843
804
844
		char buf[1024];
805
		char buf[1024];
845
		char *fmt="%s -bv \"%s\" 2>&1";
806
		char *popen_argv[4];
846
807
		
847
#if defined(HAVE_SNPRINTF)
808
		popen_argv[0] = SENDMAIL;
848
		snprintf(buf, sizeof(buf)-1, fmt, SENDMAIL, envrcpt[0]);
809
		popen_argv[1] = "-bv";
849
#else
810
		popen_argv[2] = envrcpt[0];
850
		/* XXX possible buffer overflow here */
811
		popen_argv[3] = NULL;
851
		sprintf(buf, fmt, SENDMAIL, envrcpt[0]);
852
#endif
853
812
854
		debug(D_RCPT, "calling %s", buf);
813
		debug(D_RCPT, "calling %s -bv %s", SENDMAIL, envrcpt[0]);
855
814
856
#if defined(__FreeBSD__) /* popen bug - see PR bin/50770 */
815
		p = popenv(popen_argv, "r");
857
		rv = pthread_mutex_lock(&popen_mutex);
858
		if (rv)
859
		{
860
			debug(D_ALWAYS, "Could not lock popen mutex: %s", strerror(rv));
861
			abort();
862
		}		
863
#endif
864
865
		p = popen(buf, "r");
866
		if (!p)
816
		if (!p)
867
		{
817
		{
868
			debug(D_RCPT, "popen failed(%s).  Will not expand aliases", strerror(errno));
818
			debug(D_RCPT, "popenv failed(%s).  Will not expand aliases", strerror(errno));
869
			assassin->expandedrcpt.push_back(envrcpt[0]);
819
			assassin->expandedrcpt.push_back(envrcpt[0]);
870
		} else
820
		} else
871
		{
821
		{
Lines 890-905 Link Here
890
					assassin->expandedrcpt.push_back(p+7);
840
					assassin->expandedrcpt.push_back(p+7);
891
				}
841
				}
892
			}
842
			}
893
			pclose(p); p = NULL;
843
			fclose(p); p = NULL;
894
		}
844
		}
895
#if defined(__FreeBSD__)
896
		rv = pthread_mutex_unlock(&popen_mutex);
897
		if (rv)
898
		{
899
			debug(D_ALWAYS, "Could not unlock popen mutex: %s", strerror(rv));
900
			abort();
901
		}		
902
#endif
903
	} else
845
	} else
904
	{
846
	{
905
		assassin->expandedrcpt.push_back(envrcpt[0]);
847
		assassin->expandedrcpt.push_back(envrcpt[0]);
Lines 2157-2161 Link Here
2157
	warnedmacro = true;
2099
	warnedmacro = true;
2158
}
2100
}
2159
2101
2102
/*
2103
   untrusted-argument-safe popen function - only supports "r" and "w" modes
2104
   for simplicity, and always reads stdout and stderr in "r" mode.  Call
2105
   fclose to close the FILE.
2106
*/
2107
FILE *popenv(char *const argv[], const char *type)
2108
{
2109
	FILE *iop;
2110
	int pdes[2];
2111
	int save_errno;
2112
	if ((*type != 'r' && *type != 'w') || type[1])
2113
	{
2114
		errno = EINVAL;
2115
		return (NULL);
2116
	}
2117
	if (pipe(pdes) < 0)
2118
		return (NULL);
2119
	switch (fork()) {
2120
	
2121
	case -1:			/* Error. */
2122
		save_errno = errno;
2123
		(void)close(pdes[0]);
2124
		(void)close(pdes[1]);
2125
		errno = save_errno;
2126
		return (NULL);
2127
		/* NOTREACHED */
2128
	case 0:				/* Child. */
2129
		if (*type == 'r') {
2130
			/*
2131
			 * The dup2() to STDIN_FILENO is repeated to avoid
2132
			 * writing to pdes[1], which might corrupt the
2133
			 * parent's copy.  This isn't good enough in
2134
			 * general, since the exit() is no return, so
2135
			 * the compiler is free to corrupt all the local
2136
			 * variables.
2137
			 */
2138
			(void)close(pdes[0]);
2139
			(void)dup2(pdes[1], STDOUT_FILENO);
2140
			(void)dup2(pdes[1], STDERR_FILENO);
2141
			if (pdes[1] != STDOUT_FILENO && pdes[1] != STDERR_FILENO) {
2142
				(void)close(pdes[1]);
2143
			} 
2144
		} else {
2145
			if (pdes[0] != STDIN_FILENO) {
2146
				(void)dup2(pdes[0], STDIN_FILENO);
2147
				(void)close(pdes[0]);
2148
			}
2149
			(void)close(pdes[1]);
2150
		}
2151
		execv(argv[0], argv);
2152
		exit(127);
2153
		/* NOTREACHED */
2154
	}
2155
2156
	/* Parent; assume fdopen can't fail. */
2157
	if (*type == 'r') {
2158
		iop = fdopen(pdes[0], type);
2159
		(void)close(pdes[1]);
2160
	} else {
2161
		iop = fdopen(pdes[1], type);
2162
		(void)close(pdes[0]);
2163
	}
2164
2165
	return (iop);
2166
}
2167
2160
// }}}
2168
// }}}
2161
// vim6:ai:noexpandtab
2169
// vim6:ai:noexpandtab
(-)spamass-milter.h (+1 lines)
Lines 186-190 Link Here
186
void parse_debuglevel(char* string);
186
void parse_debuglevel(char* string);
187
char *strlwr(char *str);
187
char *strlwr(char *str);
188
void warnmacro(char *macro, char *scope);
188
void warnmacro(char *macro, char *scope);
189
FILE *popenv(char *const argv[], const char *type);
189
190
190
#endif
191
#endif

Return to bug 310049