--- clamav-devel-jm9/clamav-milter/clamav-milter.c	Tue Apr 20 15:30:04 2004
+++ clamav-devel-jm10/clamav-milter/clamav-milter.c	Tue Apr 20 15:45:08 2004
@@ -631,6 +631,27 @@
 typedef	unsigned short	in_port_t;
 #endif
 
+#define ALLOC_CHECK(_function_,_pointer_,_cleanup_)	{\
+	int save_errno = errno;				\
+	if(!_pointer_){					\
+		fprintf(stderr,"%s: %s() line %d, %s: ",\
+			__FILE__,			\
+			__func__,			\
+			__LINE__,			\
+			_function_ );			\
+		errno = save_errno;			\
+		perror("");				\
+		if(!_cleanup_)				\
+			exit(save_errno);		\
+		else {					\
+			ret_code = save_errno;		\
+			if(!ret_code)			\
+				ret_code = 1;		\
+			goto cleanup;			\
+		}					\
+	}						\
+}
+
 /*
  * TODO: optional: xmessage on console when virus stopped (SNMP would be real nice!)
  *	Having said that, with LogSysLog you can (on Linux) configure the system
@@ -841,6 +862,7 @@
 int
 main(int argc, char **argv)
 {
+	int	ret_code = 0;
 	extern char *optarg;
 	const char *cfgfile = CL_DEFAULT_CFG;
 	struct cfgstruct *cpt;
@@ -1206,6 +1228,8 @@
 		umask(077);
 
 		serverIPs = (long *)cli_malloc(sizeof(long));
+		ALLOC_CHECK("cli_malloc",serverIPs,0);
+			
 		serverIPs[0] = inet_addr("127.0.0.1");
 	} else if((cpt = cfgopt(copt, "TCPSocket")) != NULL) {
 		int i;
@@ -1236,6 +1260,7 @@
 		cli_dbgmsg("numServers: %d\n", numServers);
 
 		serverIPs = (long *)cli_malloc(numServers * sizeof(long));
+		ALLOC_CHECK("cli_malloc",serverIPs,0);
 
 		for(i = 0; i < numServers; i++) {
 			char *hostname;
@@ -1288,12 +1313,15 @@
 			default:	/* parent */
 				return EX_OK;
 		}
+#ifndef CL_DEBUG
 		close(0);
 		close(1);
 		close(2);
 		open("/dev/null", O_RDONLY);
 		if(open("/dev/console", O_WRONLY) == 1)
 			dup(1);
+#endif
+
 #ifdef HAVE_SETPGRP
 #ifdef SETPGRP_VOID
 		setpgrp();
@@ -1361,6 +1389,8 @@
 	signal(SIGPIPE, SIG_IGN);
 
 	return smfi_main();
+cleanup:
+	return(ret_code);
 }
 
 /*
@@ -1481,6 +1511,7 @@
 	fd_set rfds;
 	struct timeval tv;
 	int retval;
+	int ret_code = 0;
 
 	assert(tcpSocket != 0);
 	assert(numServers > 0);
@@ -1489,7 +1520,9 @@
 		return 0;
 
 	servers = (struct sockaddr_in *)cli_calloc(numServers, sizeof(struct sockaddr_in));
+	ALLOC_CHECK("cli_calloc",servers,1);
 	socks = (int *)cli_malloc(numServers * sizeof(int));
+	ALLOC_CHECK("cli_malloc",socks,1);
 
 	FD_ZERO(&rfds);
 
@@ -1566,7 +1599,15 @@
 	cli_dbgmsg("findServer: No response from any server\n");
 	if(use_syslog)
 		syslog(LOG_WARNING, "findServer: No response from any server");
+cleanup:
+	if(ret_code){
+		if(servers)
+			free(servers);
+		if(socks)
+			free(socks);
+	}
 	return 0;
+	
 }
 
 /*
@@ -1717,6 +1758,7 @@
 clamfi_envfrom(SMFICTX *ctx, char **argv)
 {
 	struct privdata *privdata;
+	int	ret_code = 0;
 
 	if(logVerbose)
 		syslog(LOG_DEBUG, "clamfi_envfrom: %s", argv[0]);
@@ -1775,9 +1817,7 @@
 	}
 
 	privdata = (struct privdata *)cli_calloc(1, sizeof(struct privdata));
-	if(privdata == NULL)
-		return cl_error;
-
+ 	ALLOC_CHECK("cli_calloc",privdata,1);
 	privdata->dataSocket = -1;	/* 0.4 */
 	privdata->cmdSocket = -1;	/* 0.4 */
 
@@ -1787,13 +1827,13 @@
 		privdata->envid = "Uknown";
 
 	if(hflag)
-		privdata->headers = header_list_new();
+		if(!(privdata->headers = header_list_new()))
+			goto cleanup;
 
 	if(smfi_setpriv(ctx, privdata) == MI_SUCCESS)
 		return SMFIS_CONTINUE;
-
+cleanup:
 	clamfi_free(privdata);
-
 	return cl_error;
 }
 
@@ -1801,19 +1841,26 @@
 clamfi_envrcpt(SMFICTX *ctx, char **argv)
 {
 	struct privdata *privdata = (struct privdata *)smfi_getpriv(ctx);
+	int ret_code = 0;
+	void * p = NULL;
 
 	if(logVerbose)
 		syslog(LOG_DEBUG, "clamfi_envrcpt: %s", argv[0]);
-
 	cli_dbgmsg("clamfi_envrcpt: %s\n", argv[0]);
 
+ 	if(!privdata)
+ 		return cl_error;
+
 	if(privdata->to == NULL) {
 		privdata->to = cli_malloc(sizeof(char *) * 2);
+		ALLOC_CHECK("cli_malloc",privdata->to,1);
 
 		assert(privdata->numTo == 0);
-	} else
-		privdata->to = cli_realloc(privdata->to, sizeof(char *) * (privdata->numTo + 2));
-
+	} else {
+		p = cli_realloc(privdata->to, (sizeof(char *) * (privdata->numTo + 2)));
+		ALLOC_CHECK("cli_realloc",p,1);
+		privdata->to = p;
+	}
 	if(privdata->to == NULL)
 		return cl_error;
 
@@ -1821,6 +1868,8 @@
 	privdata->to[++privdata->numTo] = NULL;
 
 	return SMFIS_CONTINUE;
+cleanup:
+	return cl_error;
 }
 
 static sfsistat
@@ -1939,12 +1988,16 @@
 clamfi_body(SMFICTX *ctx, u_char *bodyp, size_t len)
 {
 	struct privdata *privdata = (struct privdata *)smfi_getpriv(ctx);
+	void * p = NULL;
+	int ret_code = 0;
 
 	if(logVerbose)
 		syslog(LOG_DEBUG, "clamfi_envbody: %u bytes", len);
 #ifdef	CL_DEBUG
 	cli_dbgmsg("clamfi_envbody: %u bytes\n", len);
 #endif
+	if(!privdata)
+		return cl_error;
 
 	if(clamfi_send(privdata, len, (char *)bodyp) < 0) {
 		clamfi_cleanup(ctx);	/* not needed, but just to be safe */
@@ -1953,17 +2006,22 @@
 	if(Sflag) {
 		if(privdata->body) {
 			assert(privdata->bodyLen > 0);
-			privdata->body = realloc(privdata->body, privdata->bodyLen + len);
+			p = realloc(privdata->body, privdata->bodyLen + len);
+			ALLOC_CHECK("realloc",p,1);
+			privdata->body = p;
 			memcpy(&privdata->body[privdata->bodyLen], bodyp, len);
 			privdata->bodyLen += len;
 		} else {
 			assert(privdata->bodyLen == 0);
 			privdata->body = cli_malloc(len);
+			ALLOC_CHECK("cli_malloc",privdata->body,1);
 			memcpy(privdata->body, bodyp, len);
 			privdata->bodyLen = len;
 		}
 	}
 	return SMFIS_CONTINUE;
+cleanup:
+	return cl_error;
 }
 
 static sfsistat
@@ -1973,9 +2031,12 @@
 	char *ptr;
 	struct privdata *privdata = (struct privdata *)smfi_getpriv(ctx);
 	char mess[128];
+	int ret_code = 0;
+	void * p = NULL;
 
 	if(logVerbose)
 		syslog(LOG_DEBUG, "clamfi_eom");
+
 #ifdef	CL_DEBUG
 	cli_dbgmsg("clamfi_eom\n");
 	assert(privdata != NULL);
@@ -1983,6 +2044,8 @@
 	assert(!((privdata->cmdSocket >= 0) && (privdata->filename != NULL)));
 	assert(privdata->dataSocket >= 0);
 #endif
+	if(!privdata)
+		goto cleanup;
 
 	close(privdata->dataSocket);
 	privdata->dataSocket = -1;
@@ -2094,9 +2157,13 @@
 			off_t len = updateSigFile();
 
 			if(len) {
+				void * p = NULL;
+
 				assert(Sflag != 0);
 
-				privdata->body = realloc(privdata->body, privdata->bodyLen + len);
+				p = realloc(privdata->body, privdata->bodyLen + len);
+				ALLOC_CHECK("realloc",p,1);
+				privdata->body = p;
 				memcpy(&privdata->body[privdata->bodyLen], signature, len);
 
 				smfi_replacebody(ctx, privdata->body, privdata->bodyLen + len);
@@ -2104,7 +2171,8 @@
 		}
 	} else {
 		int i;
-		char **to, *err;
+		char **to, *err = NULL;
+		int ret = 0;
 		char reject[1024];
 
 		if(!nflag)
@@ -2113,38 +2181,21 @@
 		/*
 		 * Setup err as a list of recipients
 		 */
-		err = (char *)cli_malloc(1024);
-
-		if(err == NULL) {
-			clamfi_cleanup(ctx);
-			return cl_error;
-		}
 
-		/*
-		 * Use snprintf rather than printf since we don't know the
-		 * length of privdata->from and may get a buffer overrun
-		 */
-		snprintf(err, 1023, "Intercepted virus from %s to",
+		sprintf_alloc(&err,"Intercepted virus from %s to",
 			privdata->from);
 
-		ptr = strchr(err, '\0');
-
-		i = 1024;
-
 		for(to = privdata->to; *to; to++) {
-			/*
-			 * Re-alloc if we are about run out of buffer space
-			 */
-			if(&ptr[strlen(*to) + 2] >= &err[i]) {
-				i += 1024;
-				err = realloc(err, i);
-				ptr = strchr(err, '\0');
-			}
-			ptr = strrcpy(ptr, " ");
-			ptr = strrcpy(ptr, *to);
+			ptr = NULL;
+			sprintf_alloc(&ptr,"%s %s",err,*to);
+			free(err);
+ 			err = ptr;
 		}
-		(void)strcpy(ptr, "\n");
 
+		err = NULL;
+		sprintf_alloc(&err,"%s\n",ptr);
+		free(ptr);
+		ptr = NULL;
 		if(use_syslog)
 			/* Include the sendmail queue ID in the log */
 			syslog(LOG_NOTICE, "%s: %s %s", privdata->envid, mess, err);
@@ -2286,8 +2337,10 @@
 		snprintf(reject, sizeof(reject) - 1, "Virus detected by ClamAV - http://www.clamav.net - %s", mess);
 		smfi_setreply(ctx, "550", "5.7.1", reject);
 	}
+cleanup:
 	clamfi_cleanup(ctx);
-
+	if(ret_code)
+		return(cl_error);
 	return rc;
 }
 
@@ -2439,9 +2492,10 @@
 static size_t
 clamfi_send(struct privdata *privdata, size_t len, const char *format, ...)
 {
-	char output[BUFSIZ];
+	char * output = NULL;
 	const char *ptr;
 	size_t numBytes = 0;
+	size_t ret_code = 0;
 
 	assert(format != NULL);
 
@@ -2455,7 +2509,9 @@
 		va_list argp;
 
 		va_start(argp, format);
-		vsnprintf(output, sizeof(output), format, argp);
+		vsprintf_alloc(&output, format, argp);
+		ALLOC_CHECK("vsprintf_alloc",output,1);
+			
 		va_end(argp);
 
 		len = strlen(output);
@@ -2515,14 +2571,23 @@
 #endif
 			}
 			checkClamd();
-
-			return -1;
+			ret_code = -1;
+			goto cleanup;
 		}
 		numBytes += nbytes;
 		privdata->numBytes += nbytes;
 		len -= nbytes;
 		ptr = &ptr[nbytes];
 	}
+cleanup:
+	if(output)
+		free(output);
+	if(ret_code){
+#ifdef CL_DEBUG
+		cli_dbgmsg("vsprintf_alloc: %s\n",output);
+#endif
+		return(-1);
+	}
 	return numBytes;
 }
 
@@ -2581,6 +2646,8 @@
 {
 	struct stat statb;
 	int fd;
+	int ret_code = 0;
+	void * p = NULL;
 
 	if(sigFilename == NULL)
 		/* nothing to read */
@@ -2606,24 +2673,32 @@
 
 	signatureStamp = statb.st_mtime;
 
-	signature = realloc(signature, statb.st_size);
+	p = realloc(signature, statb.st_size + 1);
+	ALLOC_CHECK("realloc",p,1);
+	signature = p;
 	read(fd, signature, statb.st_size);
+	signature[statb.st_size] = '\0';
 	close(fd);
 
 	return statb.st_size;
+cleanup:
+	return strlen(signature);
 }
 
 static header_list_t
 header_list_new(void)
 {
 	header_list_t ret;
+	int ret_code = 0;
+	void * p = NULL;
 
 	ret = (header_list_t)cli_malloc(sizeof(struct header_list_struct));
-	if(ret) {
+	ALLOC_CHECK("cli_malloc",ret,1);
 		ret->first = NULL;
 		ret->last = NULL;
-	}
 	return ret;
+cleanup:
+	return NULL;
 }
 
 static void
@@ -2647,19 +2722,16 @@
 	char *header;
 	size_t len;
 	struct header_node_t *new_node;
+	int ret_code = 0;
 
 	len = strlen(headerf) + strlen(headerv) + 3;
 
 	header = (char *)cli_malloc(len);
-	if(header == NULL)
-		return;
+	ALLOC_CHECK("cli_malloc",header,1);
 
 	sprintf(header, "%s: %s", headerf, headerv);
 	new_node = (struct header_node_t *)cli_malloc(sizeof(struct header_node_t));
-	if(new_node == NULL) {
-		free(header);
-		return;
-	}
+	ALLOC_CHECK("cli_malloc",new_node,1);
 	new_node->header = header;
 	new_node->next = NULL;
 	if(!list->first)
@@ -2668,6 +2740,13 @@
 		list->last->next = new_node;
 
 	list->last = new_node;
+cleanup:
+	if(ret_code){
+		if(header)
+			free(header);
+		if(new_node)
+			free(new_node);
+	}	
 }
 
 static void
@@ -2687,7 +2766,11 @@
 connect2clamd(struct privdata *privdata)
 {
 	char **to;
+	int  ret = 0;
+	int	ret_code = 0;
 
+
+	assert(privdata);
 	assert(privdata->dataSocket == -1);
 	assert(privdata->from != NULL);
 	assert(privdata->to != NULL);
@@ -2721,7 +2804,7 @@
 		DD = tm->tm_mday;
 
 		privdata->filename = (char *)cli_malloc(strlen(quarantine_dir) + 19);
-
+		ALLOC_CHECK("cli_malloc",privdata->filename,1);
 		sprintf(privdata->filename, "%s/%02d%02d%02d", quarantine_dir,
 			YY, MM, DD); 
 
@@ -2891,6 +2974,8 @@
 	cli_dbgmsg("connect2clamd OK\n");
 
 	return 1;
+cleanup:
+	return 0;
 }
 
 /*
