File ncurses-5.9-bsc10561xxx.patch of Package ncurses.31895
For the bugs
bsc#1056127 CVE-2017-13733
bsc#1056128 CVE-2017-13732
bsc#1056129 CVE-2017-13731
bsc#1056131 CVE-2017-13730
bsc#1056132 CVE-2017-13729
bsc#1056136 CVE-2017-13728
---
ncurses/tinfo/alloc_entry.c | 2
ncurses/tinfo/comp_parse.c | 6 +-
ncurses/tinfo/comp_scan.c | 4 +
ncurses/tinfo/parse_entry.c | 90 +++++++++++++++++++++++++++++---------------
ncurses/tinfo/strings.c | 5 +-
ncurses/tinfo/trim_sgr0.c | 2
progs/dump_entry.c | 19 ++++-----
progs/tic.c | 4 +
progs/tput.c | 2
9 files changed, 87 insertions(+), 47 deletions(-)
--- ncurses/tinfo/alloc_entry.c
+++ ncurses/tinfo/alloc_entry.c 2017-11-30 09:57:16.247619007 +0000
@@ -98,7 +98,7 @@ _nc_save_str(const char *const string)
size_t old_next_free = next_free;
size_t len;
- if (string == 0)
+ if (!VALID_STRING(string))
return _nc_save_str("");
len = strlen(string) + 1;
--- ncurses/tinfo/comp_parse.c
+++ ncurses/tinfo/comp_parse.c 2017-11-30 09:57:16.247619007 +0000
@@ -520,9 +520,9 @@ static void
fixup_acsc(TERMTYPE *tp, int literal)
{
if (!literal) {
- if (acs_chars == 0
- && enter_alt_charset_mode != 0
- && exit_alt_charset_mode != 0)
+ if (acs_chars == ABSENT_STRING
+ && PRESENT(enter_alt_charset_mode)
+ && PRESENT(exit_alt_charset_mode))
acs_chars = strdup(VT_ACSC);
}
}
--- ncurses/tinfo/comp_scan.c
+++ ncurses/tinfo/comp_scan.c 2017-11-30 09:57:16.251618932 +0000
@@ -168,6 +168,8 @@ next_char(void)
if (result != 0) {
FreeAndNull(result);
FreeAndNull(pushname);
+ bufptr = 0;
+ bufstart = 0;
allocated = 0;
}
/*
@@ -223,6 +225,8 @@ next_char(void)
}
if ((bufptr = bufstart) != 0) {
used = strlen(bufptr);
+ if (used == 0)
+ return (EOF);
while (iswhite(*bufptr)) {
if (*bufptr == '\t') {
_nc_curr_col = (_nc_curr_col | 7) + 1;
--- ncurses/tinfo/parse_entry.c
+++ ncurses/tinfo/parse_entry.c 2017-11-30 09:57:16.251618932 +0000
@@ -180,6 +180,21 @@ _nc_extend_names(ENTRY * entryp, char *n
}
#endif /* NCURSES_XNAMES */
+static bool
+valid_entryname(const char *name)
+{
+ bool result = TRUE;
+ int ch;
+ while ((ch = UChar(*name++)) != '\0') {
+ if (ch <= ' ' || ch > '~' || ch == '/') {
+ result = FALSE;
+ break;
+ }
+ }
+ return result;
+}
+
+
/*
* int
* _nc_parse_entry(entry, literal, silent)
@@ -211,6 +226,7 @@ _nc_parse_entry(struct entry *entryp, in
int token_type;
struct name_table_entry const *entry_ptr;
char *ptr, *base;
+ const char *name;
bool bad_tc_usage = FALSE;
token_type = _nc_get_token(silent);
@@ -261,7 +277,12 @@ _nc_parse_entry(struct entry *entryp, in
* results in the terminal type getting prematurely set to correspond
* to that of the next entry.
*/
- _nc_set_type(_nc_first_name(entryp->tterm.term_names));
+ name = _nc_first_name(entryp->tterm.term_names);
+ if (!valid_entryname(name)) {
+ _nc_warning("invalid entry name \"%s\"", name);
+ name = "invalid";
+ }
+ _nc_set_type(name);
/* check for overly-long names and aliases */
for (base = entryp->tterm.term_names; (ptr = strchr(base, '|')) != 0;
@@ -283,13 +304,24 @@ _nc_parse_entry(struct entry *entryp, in
bool is_use = (strcmp(_nc_curr_token.tk_name, "use") == 0);
bool is_tc = !is_use && (strcmp(_nc_curr_token.tk_name, "tc") == 0);
if (is_use || is_tc) {
+ if (!VALID_STRING(_nc_curr_token.tk_valstring)
+ || _nc_curr_token.tk_valstring[0] == '\0') {
+ _nc_warning("missing name for use-clause");
+ continue;
+ } else if (!valid_entryname(_nc_curr_token.tk_valstring)) {
+ _nc_warning("invalid name for use-clause \"%s\"",
+ _nc_curr_token.tk_valstring);
+ continue;
+ } else if (entryp->nuses >= MAX_USES) {
+ _nc_warning("too many use-clauses, ignored \"%s\"",
+ _nc_curr_token.tk_valstring);
+ continue;
+ }
entryp->uses[entryp->nuses].name = _nc_save_str(_nc_curr_token.tk_valstring);
entryp->uses[entryp->nuses].line = _nc_curr_line;
- if (VALID_STRING(entryp->uses[entryp->nuses].name)) {
- entryp->nuses++;
- if (entryp->nuses > 1 && is_tc) {
- BAD_TC_USAGE
- }
+ entryp->nuses++;
+ if (entryp->nuses > 1 && is_tc) {
+ BAD_TC_USAGE
}
} else {
/* normal token lookup */
@@ -624,13 +656,6 @@ static const char C_BS[] = "\b";
static const char C_HT[] = "\t";
/*
- * Note that WANTED and PRESENT are not simple inverses! If a capability
- * has been explicitly cancelled, it's not considered WANTED.
- */
-#define WANTED(s) ((s) == ABSENT_STRING)
-#define PRESENT(s) (((s) != ABSENT_STRING) && ((s) != CANCELLED_STRING))
-
-/*
* This bit of legerdemain turns all the terminfo variable names into
* references to locations in the arrays Booleans, Numbers, and Strings ---
* precisely what's needed.
@@ -655,10 +680,10 @@ postprocess_termcap(TERMTYPE *tp, bool h
/* if there was a tc entry, assume we picked up defaults via that */
if (!has_base) {
- if (WANTED(init_3string) && termcap_init2)
+ if (WANTED(init_3string) && PRESENT(termcap_init2))
init_3string = _nc_save_str(termcap_init2);
- if (WANTED(reset_2string) && termcap_reset)
+ if (WANTED(reset_2string) && PRESENT(termcap_reset))
reset_2string = _nc_save_str(termcap_reset);
if (WANTED(carriage_return)) {
@@ -773,7 +798,7 @@ postprocess_termcap(TERMTYPE *tp, bool h
if (init_tabs != 8 && init_tabs != ABSENT_NUMERIC)
_nc_warning("hardware tabs with a width other than 8: %d", init_tabs);
else {
- if (tab && _nc_capcmp(tab, C_HT))
+ if (PRESENT(tab) && _nc_capcmp(tab, C_HT))
_nc_warning("hardware tabs with a non-^I tab string %s",
_nc_visbuf(tab));
else {
@@ -847,17 +872,22 @@ postprocess_termcap(TERMTYPE *tp, bool h
* The magic moment -- copy the mapped key string over,
* stripping out padding.
*/
- for (dp = buf2, bp = tp->Strings[from_ptr->nte_index]; *bp; bp++) {
- if (bp[0] == '$' && bp[1] == '<') {
- while (*bp && *bp != '>') {
- ++bp;
- }
- } else
- *dp++ = *bp;
- }
- *dp = '\0';
+ bp = tp->Strings[from_ptr->nte_index];
+ if (VALID_STRING(bp)) {
+ for (dp = buf2; *bp; bp++) {
+ if (bp[0] == '$' && bp[1] == '<') {
+ while (*bp && *bp != '>') {
+ ++bp;
+ }
+ } else
+ *dp++ = *bp;
+ }
+ *dp = '\0';
- tp->Strings[to_ptr->nte_index] = _nc_save_str(buf2);
+ tp->Strings[to_ptr->nte_index] = _nc_save_str(buf2);
+ } else {
+ tp->Strings[to_ptr->nte_index] = bp;
+ }
}
/*
@@ -866,7 +896,7 @@ postprocess_termcap(TERMTYPE *tp, bool h
* got mapped to kich1 and im to kIC to avoid a collision.
* If the description has im but not ic, hack kIC back to kich1.
*/
- if (foundim && WANTED(key_ic) && key_sic) {
+ if (foundim && WANTED(key_ic) && PRESENT(key_sic)) {
key_ic = key_sic;
key_sic = ABSENT_STRING;
}
@@ -918,9 +948,9 @@ postprocess_termcap(TERMTYPE *tp, bool h
acs_chars = _nc_save_str(buf2);
_nc_warning("acsc string synthesized from XENIX capabilities");
}
- } else if (acs_chars == 0
- && enter_alt_charset_mode != 0
- && exit_alt_charset_mode != 0) {
+ } else if (acs_chars == ABSENT_STRING
+ && PRESENT(enter_alt_charset_mode)
+ && PRESENT(exit_alt_charset_mode)) {
acs_chars = _nc_save_str(VT_ACSC);
}
}
--- ncurses/tinfo/strings.c
+++ ncurses/tinfo/strings.c 2017-11-30 09:57:16.251618932 +0000
@@ -35,6 +35,7 @@
**/
#include <curses.priv.h>
+#include <tic.h>
MODULE_ID("$Id: strings.c,v 1.8 2012/02/22 22:34:31 tom Exp $")
@@ -105,7 +106,7 @@ _nc_str_copy(string_desc * dst, string_d
NCURSES_EXPORT(bool)
_nc_safe_strcat(string_desc * dst, const char *src)
{
- if (src != 0) {
+ if (PRESENT(src)) {
size_t len = strlen(src);
if (len < dst->s_size) {
@@ -126,7 +127,7 @@ _nc_safe_strcat(string_desc * dst, const
NCURSES_EXPORT(bool)
_nc_safe_strcpy(string_desc * dst, const char *src)
{
- if (src != 0) {
+ if (PRESENT(src)) {
size_t len = strlen(src);
if (len < dst->s_size) {
--- ncurses/tinfo/trim_sgr0.c
+++ ncurses/tinfo/trim_sgr0.c 2017-11-30 09:57:16.251618932 +0000
@@ -263,7 +263,7 @@ _nc_trim_sgr0(TERMTYPE *tp)
/*
* If rmacs is a substring of sgr(0), remove that chunk.
*/
- if (exit_alt_charset_mode != 0) {
+ if (PRESENT(exit_alt_charset_mode)) {
TR(TRACE_DATABASE, ("scan for rmacs %s", _nc_visbuf(exit_alt_charset_mode)));
j = strlen(off);
k = strlen(exit_alt_charset_mode);
--- progs/dump_entry.c
+++ progs/dump_entry.c 2017-11-30 09:57:16.251618932 +0000
@@ -722,12 +722,12 @@ fmt_entry(TERMTYPE *tterm,
#undef CUR
#define CUR tterm->
if (outform == F_TERMCAP) {
- if (termcap_reset != ABSENT_STRING) {
- if (init_3string != ABSENT_STRING
+ if (VALID_STRING(termcap_reset)) {
+ if (VALID_STRING(init_3string)
&& !strcmp(init_3string, termcap_reset))
DISCARD(init_3string);
- if (reset_2string != ABSENT_STRING
+ if (VALID_STRING(reset_2string)
&& !strcmp(reset_2string, termcap_reset))
DISCARD(reset_2string);
}
@@ -799,7 +799,7 @@ fmt_entry(TERMTYPE *tterm,
buffer[0] = '\0';
if (predval != FAIL) {
- if (capability != ABSENT_STRING
+ if (VALID_STRING(capability)
&& i + 1 > num_strings)
num_strings = i + 1;
@@ -877,8 +877,7 @@ fmt_entry(TERMTYPE *tterm,
}
}
/* e.g., trimmed_sgr0 */
- if (capability != ABSENT_STRING &&
- capability != CANCELLED_STRING &&
+ if (VALID_STRING(capability) &&
capability != tterm->Strings[i])
free(capability);
}
@@ -1047,7 +1046,8 @@ kill_labels(TERMTYPE *tterm, int target)
for (n = 0; n <= 10; ++n) {
_nc_SPRINTF(name, _nc_SLIMIT(sizeof(name)) "lf%d", n);
- if ((cap = find_string(tterm, name)) != ABSENT_STRING
+ cap = find_string(tterm, name);
+ if (VALID_STRING(cap)
&& kill_string(tterm, cap)) {
target -= (int) (strlen(cap) + 5);
++result;
@@ -1072,7 +1072,8 @@ kill_fkeys(TERMTYPE *tterm, int target)
for (n = 60; n >= 0; --n) {
_nc_SPRINTF(name, _nc_SLIMIT(sizeof(name)) "kf%d", n);
- if ((cap = find_string(tterm, name)) != ABSENT_STRING
+ cap = find_string(tterm, name);
+ if (VALID_STRING(cap)
&& kill_string(tterm, cap)) {
target -= (int) (strlen(cap) + 5);
++result;
@@ -1094,7 +1095,7 @@ one_one_mapping(const char *mapping)
{
bool result = TRUE;
- if (mapping != ABSENT_STRING) {
+ if (VALID_STRING(mapping)) {
int n = 0;
while (mapping[n] != '\0') {
if (isLine(mapping[n]) &&
--- progs/tic.c
+++ progs/tic.c 2017-11-30 09:57:16.251618932 +0000
@@ -1963,8 +1963,12 @@ check_termtype(TERMTYPE *tp, bool litera
for (k = j + 1; given[k].keycode; k++) {
const char *b = given[k].value;
+
+ if (!VALID_STRING(b))
+ continue;
if (check[k])
continue;
+
if (!_nc_capcmp(a, b)) {
check[j] = 1;
check[k] = 1;
--- progs/tput.c
+++ progs/tput.c 2017-11-30 09:58:23.430340881 +0000
@@ -300,7 +300,7 @@ tput(int argc, char *argv[])
}
#endif
quit(4, "unknown terminfo capability '%s'", name);
- } else if (s != ABSENT_STRING) {
+ } else if (VALID_STRING(s)) {
if (argc > 1) {
int k;
int ignored;