Package: release.debian.org Severity: normal Tags: stretch User: release.debian....@packages.debian.org Usertags: pu
Recently a few flaws in the tic program and the tic library have been detected: null pointer dereference, buffer overflow, stack smashing, you name it. Six bugs have been reported in the Red Hat bugtracker and four CVEs assigned. Fortunately there are rather few users who would run affected programs at all, so it was decided that no DSA would be necessary. Upstream has fixed these problems in the latest patchlevels (already in sid), and I would like to address them in a stable upload. I have verified that the testcases in the reported Red Hat bugs no longer cause crashes (if anybody wants to verify that, I can send them). Cheers, Sven
diff -Nru ncurses-6.0+20161126/debian/changelog ncurses-6.0+20161126/debian/changelog --- ncurses-6.0+20161126/debian/changelog 2016-11-29 21:19:08.000000000 +0100 +++ ncurses-6.0+20161126/debian/changelog 2017-07-09 15:32:26.000000000 +0200 @@ -1,3 +1,11 @@ +ncurses (6.0+20161126-1+deb9u1) stretch; urgency=medium + + * Cherry-pick upstream fixes from the 20170701 and 20170708 patchlevels + for various crash bugs in the tic library and the tic binary + (CVE-2017-10684, CVE-2017-10685, CVE-2017-11112, CVE-2017-11113). + + -- Sven Joachim <svenj...@gmx.de> Sun, 09 Jul 2017 15:32:26 +0200 + ncurses (6.0+20161126-1) unstable; urgency=low * New upstream patchlevel. diff -Nru ncurses-6.0+20161126/debian/patches/cve-fixes.diff ncurses-6.0+20161126/debian/patches/cve-fixes.diff --- ncurses-6.0+20161126/debian/patches/cve-fixes.diff 1970-01-01 01:00:00.000000000 +0100 +++ ncurses-6.0+20161126/debian/patches/cve-fixes.diff 2017-07-09 15:32:26.000000000 +0200 @@ -0,0 +1,185 @@ +Author: Sven Joachim <svenj...@gmx.de> +Description: Fixes for four CVEs + Fixes for CVE 2017-10684, CVE-2017-10685, CVE-2017-11112, + CVE-2017-11113 cherry-picked from upstream patchlevels 20170701 and + 20170708. +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1464684 +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1464685 +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1464686 +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1464687 +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1464691 +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1464692 +Forwarded: not-needed +Last-Update: 2017-07-09 + +--- + ncurses/tinfo/alloc_entry.c | 6 +++++- + ncurses/tinfo/parse_entry.c | 22 ++++++++++++---------- + progs/dump_entry.c | 34 +++++++++++++++++++++------------- + 3 files changed, 38 insertions(+), 24 deletions(-) + +--- a/ncurses/tinfo/alloc_entry.c ++++ b/ncurses/tinfo/alloc_entry.c +@@ -96,7 +96,11 @@ _nc_save_str(const char *const string) + { + char *result = 0; + size_t old_next_free = next_free; +- size_t len = strlen(string) + 1; ++ size_t len; ++ ++ if (string == 0) ++ return _nc_save_str(""); ++ len = strlen(string) + 1; + + if (len == 1 && next_free != 0) { + /* +--- a/ncurses/tinfo/parse_entry.c ++++ b/ncurses/tinfo/parse_entry.c +@@ -236,13 +236,14 @@ _nc_parse_entry(struct entry *entryp, in + * implemented it. Note that the resulting terminal type was never the + * 2-character name, but was instead the first alias after that. + */ ++#define ok_TC2(s) (isgraph(UChar(s)) && (s) != '|') + ptr = _nc_curr_token.tk_name; + if (_nc_syntax == SYN_TERMCAP + #if NCURSES_XNAMES + && !_nc_user_definable + #endif + ) { +- if (ptr[2] == '|') { ++ if (ok_TC2(ptr[0]) && ok_TC2(ptr[1]) && (ptr[2] == '|')) { + ptr += 3; + _nc_curr_token.tk_name[2] = '\0'; + } +@@ -284,9 +285,11 @@ _nc_parse_entry(struct entry *entryp, in + if (is_use || is_tc) { + entryp->uses[entryp->nuses].name = _nc_save_str(_nc_curr_token.tk_valstring); + entryp->uses[entryp->nuses].line = _nc_curr_line; +- entryp->nuses++; +- if (entryp->nuses > 1 && is_tc) { +- BAD_TC_USAGE ++ if (VALID_STRING(entryp->uses[entryp->nuses].name)) { ++ entryp->nuses++; ++ if (entryp->nuses > 1 && is_tc) { ++ BAD_TC_USAGE ++ } + } + } else { + /* normal token lookup */ +@@ -572,7 +575,7 @@ append_acs0(string_desc * dst, int code, + static void + append_acs(string_desc * dst, int code, char *src) + { +- if (src != 0 && strlen(src) == 1) { ++ if (VALID_STRING(src) && strlen(src) == 1) { + append_acs0(dst, code, *src); + } + } +@@ -833,15 +836,14 @@ postprocess_termcap(TERMTYPE *tp, bool h + } + + if (tp->Strings[to_ptr->nte_index]) { ++ const char *s = tp->Strings[from_ptr->nte_index]; ++ const char *t = tp->Strings[to_ptr->nte_index]; + /* There's no point in warning about it if it's the same + * string; that's just an inefficiency. + */ +- if (strcmp( +- tp->Strings[from_ptr->nte_index], +- tp->Strings[to_ptr->nte_index]) != 0) ++ if (VALID_STRING(s) && VALID_STRING(t) && strcmp(s, t) != 0) + _nc_warning("%s (%s) already has an explicit value %s, ignoring ko", +- ap->to, ap->from, +- _nc_visbuf(tp->Strings[to_ptr->nte_index])); ++ ap->to, ap->from, t); + continue; + } + +--- a/progs/dump_entry.c ++++ b/progs/dump_entry.c +@@ -817,9 +817,10 @@ fmt_entry(TERMTYPE *tterm, + PredIdx num_strings = 0; + bool outcount = 0; + +-#define WRAP_CONCAT \ +- wrap_concat(buffer); \ +- outcount = TRUE ++#define WRAP_CONCAT1(s) wrap_concat(s); outcount = TRUE ++#define WRAP_CONCAT2(a,b) wrap_concat(a); WRAP_CONCAT1(b) ++#define WRAP_CONCAT3(a,b,c) wrap_concat(a); WRAP_CONCAT2(b,c) ++#define WRAP_CONCAT WRAP_CONCAT1(buffer) + + len = 12; /* terminfo file-header */ + +@@ -978,9 +979,9 @@ fmt_entry(TERMTYPE *tterm, + set_attributes = save_sgr; + + trimmed_sgr0 = _nc_trim_sgr0(tterm); +- if (strcmp(capability, trimmed_sgr0)) ++ if (strcmp(capability, trimmed_sgr0)) { + capability = trimmed_sgr0; +- else { ++ } else { + if (trimmed_sgr0 != exit_attribute_mode) + free(trimmed_sgr0); + } +@@ -1017,13 +1018,21 @@ fmt_entry(TERMTYPE *tterm, + _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer)) + "%s=!!! %s WILL NOT CONVERT !!!", + name, srccap); ++ WRAP_CONCAT; + } else if (suppress_untranslatable) { + continue; + } else { + char *s = srccap, *d = buffer; +- _nc_SPRINTF(d, _nc_SLIMIT(sizeof(buffer)) "..%s=", name); +- d += strlen(d); ++ WRAP_CONCAT3("..", name, "="); + while ((*d = *s++) != 0) { ++ if ((d - buffer + 1) >= (int) sizeof(buffer)) { ++ fprintf(stderr, ++ "%s: value for %s is too long\n", ++ _nc_progname, ++ name); ++ *d = '\0'; ++ break; ++ } + if (*d == ':') { + *d++ = '\\'; + *d = ':'; +@@ -1032,13 +1041,12 @@ fmt_entry(TERMTYPE *tterm, + } + d++; + } ++ WRAP_CONCAT; + } + } else { +- _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer)) +- "%s=%s", name, cv); ++ WRAP_CONCAT3(name, "=", cv); + } + len += (int) strlen(capability) + 1; +- WRAP_CONCAT; + } else { + char *src = _nc_tic_expand(capability, + outform == F_TERMINFO, numbers); +@@ -1054,8 +1062,7 @@ fmt_entry(TERMTYPE *tterm, + strcpy_DYN(&tmpbuf, src); + } + len += (int) strlen(capability) + 1; +- wrap_concat(tmpbuf.text); +- outcount = TRUE; ++ WRAP_CONCAT1(tmpbuf.text); + } + } + /* e.g., trimmed_sgr0 */ +@@ -1491,7 +1498,8 @@ dump_entry(TERMTYPE *tterm, + } + if (len > critlen) { + (void) fprintf(stderr, +- "warning: %s entry is %d bytes long\n", ++ "%s: %s entry is %d bytes long\n", ++ _nc_progname, + _nc_first_name(tterm->term_names), + len); + SHOW_WHY("# WARNING: this entry, %d bytes long, may core-dump %s libraries!\n", diff -Nru ncurses-6.0+20161126/debian/patches/series ncurses-6.0+20161126/debian/patches/series --- ncurses-6.0+20161126/debian/patches/series 2016-11-28 18:50:38.000000000 +0100 +++ ncurses-6.0+20161126/debian/patches/series 2017-07-09 15:32:26.000000000 +0200 @@ -1,3 +1,4 @@ 01-debian-no-ada-doc.diff 02-debian-backspace.diff 03-debian-ncursesconfig-omit-L.diff +cve-fixes.diff