[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1004116: ssmtp: ssmtp truncates headers longer than BUF_SZ



Package: ssmtp
Version: 2.64-10
Severity: normal

The function smtp_write fails to handle headers longer than BUF_SZ.
For example, the following email will be truncated, resulting in an
invalid email header:

https://lore.kernel.org/all/de35edd9-b85d-0ed7-98b6-7a41134c3ece@foss.st.com/

There is no reason why this limit should exist.  This patch fixes
it so that the length is practically unlimited (it is still limited
by the return value of vsnprintf which is INT_MAX).

diff --git a/ssmtp.c b/ssmtp.c
index dbb1437..f9d959a 100644
--- a/ssmtp.c
+++ b/ssmtp.c
@@ -1371,16 +1371,32 @@ smtp_write() -- A printf to an fd and append <CR/LF>
 */
 ssize_t smtp_write(int fd, char *format, ...)
 {
-	char buf[(BUF_SZ + 2)];
+	char stbuf[(BUF_SZ + 2)];
+	char *buf = stbuf;
 	va_list ap;
 	ssize_t outbytes = 0;
+	int sz;
 
 	va_start(ap, format);
-	if(vsnprintf(buf, (BUF_SZ - 1), format, ap) == -1) {
+	sz = vsnprintf(buf, (BUF_SZ), format, ap);
+	if(sz < 0) {
 		die("smtp_write() -- vsnprintf() failed");
 	}
 	va_end(ap);
 
+	if(sz >= (BUF_SZ)) {
+		buf = malloc(sz + 3);
+		if(!buf) {
+			die("smtp_write() -- malloc() failed");
+		}
+
+		va_start(ap, format);
+		if(vsnprintf(buf, sz + 1, format, ap) < 0) {
+			die("smtp_write() -- vsnprintf() failed");
+		}
+		va_end(ap);
+	}
+
 	if(log_level > 0) {
 		log_event(LOG_INFO, "%s\n", buf);
 	}
@@ -1391,6 +1407,10 @@ ssize_t smtp_write(int fd, char *format, ...)
 	(void)strcat(buf, "\r\n");
 
 	outbytes = fd_puts(fd, buf, strlen(buf));
+
+	if(buf != stbuf) {
+		free(buf);
+	}
 	
 	return (outbytes >= 0) ? outbytes : 0;
 }

--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Reply to: