CVE-2017-1000211: Use After Free (CWE-416)
value: Lynx before 2.8.9dev.16 is vulnerable to a use after free in the HTML parser resulting in memory disclosure, because HTML_put_string() can append a chunk onto itself.
CWE description: The product reuses or references memory after it has been freed. At some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. Any operations using the original pointer are no longer valid because the memory "belongs" to the code that operates on the new pointer.
CVSS v3 base score: 5.3
Published: 2017-11-17T15:29Z
Repository: https://github.com/ThomasDickey/lynx-snapshots
Language: Other
Files changed: CHANGES, PACKAGE/debian/lynx-dev.lintian-overrides, src/HTML.c
Commit date: 2017-07-05 23:19:21 +0000
Commit message: snapshot of project "lynx", label v2-8-9dev_15b

Diff: diff --git a/CHANGES b/CHANGES
index 7f06e953..641bd277 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,11 +1,13 @@
--- $LynxId: CHANGES,v 1.910 2017/07/05 20:39:40 tom Exp $
+-- $LynxId: CHANGES,v 1.911 2017/07/05 22:23:00 tom Exp $
 ===============================================================================
 Changes since Lynx 2.8 release
 ===============================================================================
 
 2017-07-05 (2.8.9dev.16)
+* add a check to ensure that HTML_put_string() will not append a chunk onto
+  itself (report by Ned Williamson) -TD
 * update et.po, tr.po from
     http://translationproject.org/latest/lynx
 
 2017-07-04 (2.8.9dev.15)
 * add note in lynx.cfg about default values (Debian #408448) -TD
diff --git a/PACKAGE/debian/lynx-dev.lintian-overrides b/PACKAGE/debian/lynx-dev.lintian-overrides
index 280b562d..a2345b7e 100644
--- a/PACKAGE/debian/lynx-dev.lintian-overrides
+++ b/PACKAGE/debian/lynx-dev.lintian-overrides
@@ -1,7 +1,7 @@
 # Lynx's version-numbering is not understood by lintian, though legal.
-lynx-dev: rc-version-greater-than-expected-version 2.8.9dev.15 > 2.8.9 (consider using 2.8.9~dev.15)
+lynx-dev: rc-version-greater-than-expected-version
 
 # This is intentional because it is referenced from the documentation.
 lynx-dev: extra-license-file usr/share/doc/lynx-dev/COPYING
 
 # These are intentional, part of the sample files:
diff --git a/src/HTML.c b/src/HTML.c
index c9ab9395..63d67206 100644
--- a/src/HTML.c
+++ b/src/HTML.c
@@ -1,7 +1,7 @@
 /*
- * $LynxId: HTML.c,v 1.173 2017/07/04 20:05:01 tom Exp $
+ * $LynxId: HTML.c,v 1.174 2017/07/05 22:48:09 tom Exp $
  *
  *		Structured stream to Rich hypertext converter
  *		============================================
  *
  *	This generates a hypertext object.  It converts from the
@@ -503,10 +503,12 @@ void HTML_put_character(HTStructured * me, int c)
  *	This is written separately from put_character because the loop can
  *	in some cases be promoted to a higher function call level for speed.
  */
 void HTML_put_string(HTStructured * me, const char *s)
 {
+    HTChunk *target = NULL;
+
 #ifdef USE_PRETTYSRC
     char *translated_string = NULL;
 #endif
 
     if (s == NULL || (LYMapsOnly && me->sp[0].tag_number != HTML_OBJECT))
@@ -523,19 +525,19 @@ void HTML_put_string(HTStructured * me, const char *s)
 
     case HTML_COMMENT:
 	break;			/* Do Nothing */
 
     case HTML_TITLE:
-	HTChunkPuts(&me->title, s);
+	target = &me->title;
 	break;
 
     case HTML_STYLE:
-	HTChunkPuts(&me->style_block, s);
+	target = &me->style_block;
 	break;
 
     case HTML_SCRIPT:
-	HTChunkPuts(&me->script, s);
+	target = &me->script;
 	break;
 
     case HTML_PRE:		/* Formatted text */
     case HTML_LISTING:		/* Literal text */
     case HTML_XMP:
@@ -545,24 +547,24 @@ void HTML_put_string(HTStructured * me, const char *s)
 	 */
 	HText_appendText(me->text, s);
 	break;
 
     case HTML_OBJECT:
-	HTChunkPuts(&me->object, s);
+	target = &me->object;
 	break;
 
     case HTML_TEXTAREA:
-	HTChunkPuts(&me->textarea, s);
+	target = &me->textarea;
 	break;
 
     case HTML_SELECT:
     case HTML_OPTION:
-	HTChunkPuts(&me->option, s);
+	target = &me->option;
 	break;
 
     case HTML_MATH:
-	HTChunkPuts(&me->math, s);
+	target = &me->math;
 	break;
 
     default:			/* Free format text? */
 	if (!me->sp->style->freeFormat) {
 	    /*
@@ -649,10 +651,19 @@ void HTML_put_string(HTStructured * me, const char *s)
 		}
 
 	    }			/* for */
 	}
     }				/* end switch */
+
+    if (target != NULL) {
+	if (target->data == s) {
+	    CTRACE((tfp, "BUG: appending chunk to itself: `%.*s'\n",
+		    target->size, target->data));
+	} else {
+	    HTChunkPuts(target, s);
+	}
+    }
 #ifdef USE_PRETTYSRC
     if (psrc_convert_string) {
 	psrc_convert_string = FALSE;
 	FREE(translated_string);
     }

Vulnerable code: lynx-dev: rc-version-greater-than-expected-version 2.8.9dev.15 > 2.8.9 (consider using 2.8.9~dev.15)
 * $LynxId: HTML.c,v 1.173 2017/07/04 20:05:01 tom Exp $
	HTChunkPuts(&me->title, s);
	HTChunkPuts(&me->style_block, s);
	HTChunkPuts(&me->script, s);
	HTChunkPuts(&me->object, s);
	HTChunkPuts(&me->textarea, s);
	HTChunkPuts(&me->option, s);
	HTChunkPuts(&me->math, s);
Fixed code: -- $LynxId: CHANGES,v 1.911 2017/07/05 22:23:00 tom Exp $
* add a check to ensure that HTML_put_string() will not append a chunk onto
  itself (report by Ned Williamson) -TD
lynx-dev: rc-version-greater-than-expected-version
 * $LynxId: HTML.c,v 1.174 2017/07/05 22:48:09 tom Exp $
    HTChunk *target = NULL;

	target = &me->title;
	target = &me->style_block;
	target = &me->script;
	target = &me->object;
	target = &me->textarea;
	target = &me->option;
	target = &me->math;

    if (target != NULL) {
	if (target->data == s) {
	    CTRACE((tfp, "BUG: appending chunk to itself: `%.*s'\n",
		    target->size, target->data));
	} else {
	    HTChunkPuts(target, s);
	}
    }