[tin-bugs] Heap Buffer Overflow in tin 2.6.6 via Header Display-Name Quoting

Urs Janßen urs at tin.org
Mon Aug 24 17:21:26 CEST 2026


On Sun, Aug 23, 2026 at 11:24:15PM +0200, Tristan wrote:
> A malicious Usenet article with backslashes or double-quote
> characters in the display-name portion of a From header can trigger
> a heap buffer overflow when the victim reads the article. The

using the dynamic tin_fgets() buffer (>= 512 bytes) should
be "safe" for regular articles, but with malicious input it
may ovefflow (I failed to trigger it, even with 2k of \ in From).
the following should fix the possible issue:

--- a/src/rfc2046.c
+++ b/src/rfc2046.c
@@ -1274,7 +1274,7 @@ parse_mb_list_header(
 	char name[HEADER_LEN];
 	char *tmp, *new_name, *disp_name, *ret, *curr_from, *next_from;
 	int type, c_needed = 0;
-	size_t plen = strlen(pat);
+	size_t ptr_pos, name_len, ret_len, plen = strlen(pat);
 	char *ptr = buf + plen;
 
 	/*
@@ -1296,7 +1296,9 @@ parse_mb_list_header(
 		return NULL;
 
 	tmp = curr_from = my_strdup(ptr);
-	ret = ptr;
+	ret = my_strdup(ptr);
+	ret_len = strlen(ret) + 1;
+	ptr = ret;
 	*ptr = '\0';
 
 	do {
@@ -1318,6 +1320,13 @@ parse_mb_list_header(
 				else {
 					/* check for problematic strings */
 					if ((new_name = quote_display_name(disp_name))) {
+						if ((name_len = strlen(new_name) - strlen(disp_name)) > 0) {
+							ret_len += name_len;
+							/* save and restore position in case realloc() creates a new allocation */
+							ptr_pos = ptr - ret;
+							ret = my_realloc(ret, ret_len);
+							ptr = ret + ptr_pos;
+						}
 						sprintf(ptr, "%s <%s>", new_name, addr);
 						free(new_name);
 					} else
@@ -1398,22 +1407,22 @@ parse_rfc822_headers(
 		unfold_header(line);
 		if ((ptr = parse_mb_list_header(line, "From"))) {
 			FreeIfNeeded(hdr->from);
-			hdr->from = my_strdup(ptr);
+			hdr->from = ptr;
 			continue;
 		}
 		if ((ptr = parse_mb_list_header(line, "To"))) {
 			FreeIfNeeded(hdr->to);
-			hdr->to = my_strdup(ptr);
+			hdr->to = ptr;
 			continue;
 		}
 		if ((ptr = parse_mb_list_header(line, "Cc"))) {
 			FreeIfNeeded(hdr->cc);
-			hdr->cc = my_strdup(ptr);
+			hdr->cc = ptr;
 			continue;
 		}
 		if ((ptr = parse_mb_list_header(line, "Bcc"))) {
 			FreeIfNeeded(hdr->bcc);
-			hdr->bcc = my_strdup(ptr);
+			hdr->bcc = ptr;
 			continue;
 		}
 		if ((ptr = parse_header(line, "Date", FALSE, FALSE, FALSE))) {
@@ -1433,7 +1442,7 @@ parse_rfc822_headers(
 		}
 		if ((ptr = parse_mb_list_header(line, "Reply-To"))) {
 			FreeIfNeeded(hdr->replyto);
-			hdr->replyto = my_strdup(ptr);
+			hdr->replyto = ptr;
 			continue;
 		}
 		if ((ptr = parse_header(line, "Newsgroups", FALSE, FALSE, FALSE))) {





More information about the tin-bugs mailing list