#1004116 ssmtp: ssmtp truncates headers longer than BUF_SZ

Package:
ssmtp
Source:
ssmtp
Description:
extremely simple MTA to get mail off the system to a mail hub
Submitter:
Date:
2026-02-25 21:45:03 UTC
Severity:
normal
#1004116#5
Date:
2022-01-21 03:24:05 UTC
From:
To:
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;
 }