Control: tags -1 - moreinfo On 2017-07-15 12:54 +0200, Sven Joachim wrote:
> On 2017-07-15 11:38 +0100, Adam D. Barratt wrote: > >> Control: tags -1 + confirmed >> >> On Sun, 2017-07-09 at 19:40 +0200, Sven Joachim wrote: >>> The same problem as in #867814 for stretch and almost the same fix, >>> except that one inapplicable hunk has been removed from the patch. >> >> Please go ahead. > > Same answer as in #867814, the fallout from #868266 needs to be sorted > out first → no upload this weekend, defer for 8.10. Unfortunately the fixes from the 20170715 patchlevel were rather large and not easily backportable to jessie, but finally openSUSE[1] has come up with a patch that I have stolen. The output of "infocmp -C" slightly differs from the one in currently in jessie, but I think there are no functional differences. At least perldoc works fine. Cheers, Sven 1. https://bugzilla.opensuse.org/show_bug.cgi?id=1049344
diff -Nru ncurses-5.9+20140913/debian/changelog ncurses-5.9+20140913/debian/changelog --- ncurses-5.9+20140913/debian/changelog 2014-09-17 19:00:57.000000000 +0200 +++ ncurses-5.9+20140913/debian/changelog 2017-07-09 16:26:16.000000000 +0200 @@ -1,3 +1,13 @@ +ncurses (5.9+20140913-1+deb8u1) UNRELEASED; 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). + * Apply termcap-format fix from openSUSE's ncurses-5.9-55.6.1 package, + repairing a regression from the above security fixes (see #868266). + + -- Sven Joachim <svenj...@gmx.de> Sun, 09 Jul 2017 16:26:16 +0200 + ncurses (5.9+20140913-1) unstable; urgency=low * New upstream patchlevel. diff -Nru ncurses-5.9+20140913/debian/patches/cve-fixes.diff ncurses-5.9+20140913/debian/patches/cve-fixes.diff --- ncurses-5.9+20140913/debian/patches/cve-fixes.diff 1970-01-01 01:00:00.000000000 +0100 +++ ncurses-5.9+20140913/debian/patches/cve-fixes.diff 2017-07-09 16:26:16.000000000 +0200 @@ -0,0 +1,173 @@ +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 | 30 +++++++++++++++++++----------- + 3 files changed, 36 insertions(+), 22 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 */ +@@ -571,7 +574,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); + } + } +@@ -829,15 +832,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 +@@ -609,9 +609,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 */ + +@@ -802,13 +803,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 = ':'; +@@ -817,13 +826,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); +@@ -839,8 +847,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 */ +@@ -1203,7 +1210,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-5.9+20140913/debian/patches/series ncurses-5.9+20140913/debian/patches/series --- ncurses-5.9+20140913/debian/patches/series 2014-09-15 20:01:33.000000000 +0200 +++ ncurses-5.9+20140913/debian/patches/series 2017-07-09 16:26:16.000000000 +0200 @@ -1,3 +1,5 @@ 01-debian-no-ada-doc.diff 02-debian-backspace.diff 03-debian-ncursesconfig-omit-L.diff +cve-fixes.diff +termcap-fix.diff diff -Nru ncurses-5.9+20140913/debian/patches/termcap-fix.diff ncurses-5.9+20140913/debian/patches/termcap-fix.diff --- ncurses-5.9+20140913/debian/patches/termcap-fix.diff 1970-01-01 01:00:00.000000000 +0100 +++ ncurses-5.9+20140913/debian/patches/termcap-fix.diff 2017-07-09 16:26:16.000000000 +0200 @@ -0,0 +1,63 @@ +Author: Sven Joachim <svenj...@gmx.de> +Description: Apply termcap-format fix from openSUSE +Bug-Debian: https://bugs.debian.org/868266 +Forwarded: not-needed +Last-Update: 2017-08-12 + +--- + progs/dump_entry.c | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +--- a/progs/dump_entry.c ++++ b/progs/dump_entry.c +@@ -427,6 +427,22 @@ wrap_concat(const char *src) + column += (int) need; + } + ++static void ++wrap_termap(const char *a, const char *b, const char *c) ++{ ++ size_t need = strlen(a)+strlen(b)+strlen(c); ++ size_t want = strlen(separator)+need; ++ if (column > INDENT ++ && column + (int) want > width) { ++ force_wrap(); ++ } ++ strcpy_DYN(&outbuf, a); ++ strcpy_DYN(&outbuf, b); ++ strcpy_DYN(&outbuf, c); ++ strcpy_DYN(&outbuf, separator); ++ column += (int) need; ++} ++ + #define IGNORE_SEP_TRAIL(first,last,sep_trail) \ + if ((size_t)(last - first) > sizeof(sep_trail)-1 \ + && !strncmp(first, sep_trail, sizeof(sep_trail)-1)) \ +@@ -808,7 +824,12 @@ fmt_entry(TERMTYPE *tterm, + continue; + } else { + char *s = srccap, *d = buffer; +- WRAP_CONCAT3("..", name, "="); ++ if (infodump) { ++ WRAP_CONCAT3("..", name, "="); ++ } else { ++ wrap_termap("..", name, "="); ++ outcount = TRUE; ++ } + while ((*d = *s++) != 0) { + if ((d - buffer + 1) >= (int) sizeof(buffer)) { + fprintf(stderr, +@@ -829,7 +850,12 @@ fmt_entry(TERMTYPE *tterm, + WRAP_CONCAT; + } + } else { +- WRAP_CONCAT3(name, "=", cv); ++ if (infodump) { ++ WRAP_CONCAT3(name, "=", cv); ++ } else { ++ wrap_termap(name, "=", cv); ++ outcount = TRUE; ++ } + } + len += (int) strlen(capability) + 1; + } else {