| From 5f40697e37e195069f55528fc7a1d77e619ad104 Mon Sep 17 00:00:00 2001 |
| From: Dan Tran <dantran@microsoft.com> |
| Date: Fri, 13 May 2022 13:28:41 -0700 |
| Subject: [PATCH] ncurses 6.3 before patch 20220416 has an out-of-bounds read |
| and segmentation violation in convert_strings in tinfo/read_entry.c in the |
| terminfo library. |
| |
| CVE: CVE-2022-29458 |
| Upstream-Status: Backport |
| [https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1009870] |
| |
| Signed-off-by: Gustavo Lima Chaves <gustavo.chaves@microsoft.com> |
| Signed-off-by: Dan Tran <dantran@microsoft.com> |
| --- |
| ncurses/tinfo/alloc_entry.c | 14 ++++++-------- |
| ncurses/tinfo/read_entry.c | 25 +++++++++++++++++++------ |
| 2 files changed, 25 insertions(+), 14 deletions(-) |
| |
| diff --git a/ncurses/tinfo/alloc_entry.c b/ncurses/tinfo/alloc_entry.c |
| index 4bf7d6c8..b49ad6aa 100644 |
| --- a/ncurses/tinfo/alloc_entry.c |
| +++ b/ncurses/tinfo/alloc_entry.c |
| @@ -48,13 +48,11 @@ |
| |
| #include <tic.h> |
| |
| -MODULE_ID("$Id: alloc_entry.c,v 1.64 2020/02/02 23:34:34 tom Exp $") |
| +MODULE_ID("$Id: alloc_entry.c,v 1.69 2022/04/16 22:46:53 tom Exp $") |
| |
| #define ABSENT_OFFSET -1 |
| #define CANCELLED_OFFSET -2 |
| |
| -#define MAX_STRTAB 4096 /* documented maximum entry size */ |
| - |
| static char *stringbuf; /* buffer for string capabilities */ |
| static size_t next_free; /* next free character in stringbuf */ |
| |
| @@ -71,8 +69,8 @@ _nc_init_entry(ENTRY * const tp) |
| } |
| #endif |
| |
| - if (stringbuf == 0) |
| - TYPE_MALLOC(char, (size_t) MAX_STRTAB, stringbuf); |
| + if (stringbuf == NULL) |
| + TYPE_MALLOC(char, (size_t) MAX_ENTRY_SIZE, stringbuf); |
| |
| next_free = 0; |
| |
| @@ -108,11 +106,11 @@ _nc_save_str(const char *const string) |
| * Cheat a little by making an empty string point to the end of the |
| * previous string. |
| */ |
| - if (next_free < MAX_STRTAB) { |
| + if (next_free < MAX_ENTRY_SIZE) { |
| result = (stringbuf + next_free - 1); |
| } |
| - } else if (next_free + len < MAX_STRTAB) { |
| - _nc_STRCPY(&stringbuf[next_free], string, MAX_STRTAB); |
| + } else if (next_free + len < MAX_ENTRY_SIZE) { |
| + _nc_STRCPY(&stringbuf[next_free], string, MAX_ENTRY_SIZE); |
| DEBUG(7, ("Saved string %s", _nc_visbuf(string))); |
| DEBUG(7, ("at location %d", (int) next_free)); |
| next_free += len; |
| diff --git a/ncurses/tinfo/read_entry.c b/ncurses/tinfo/read_entry.c |
| index 5b570b0f..23c2cebc 100644 |
| --- a/ncurses/tinfo/read_entry.c |
| +++ b/ncurses/tinfo/read_entry.c |
| @@ -1,5 +1,5 @@ |
| /**************************************************************************** |
| - * Copyright 2018-2019,2020 Thomas E. Dickey * |
| + * Copyright 2018-2021,2022 Thomas E. Dickey * |
| * Copyright 1998-2016,2017 Free Software Foundation, Inc. * |
| * * |
| * Permission is hereby granted, free of charge, to any person obtaining a * |
| @@ -42,7 +42,7 @@ |
| |
| #include <tic.h> |
| |
| -MODULE_ID("$Id: read_entry.c,v 1.157 2020/02/02 23:34:34 tom Exp $") |
| +MODULE_ID("$Id: read_entry.c,v 1.162 2022/04/16 21:00:00 tom Exp $") |
| |
| #define TYPE_CALLOC(type,elts) typeCalloc(type, (unsigned)(elts)) |
| |
| @@ -145,6 +145,7 @@ convert_strings(char *buf, char **Strings, int count, int size, char *table) |
| { |
| int i; |
| char *p; |
| + bool corrupt = FALSE; |
| |
| for (i = 0; i < count; i++) { |
| if (IS_NEG1(buf + 2 * i)) { |
| @@ -154,8 +155,20 @@ convert_strings(char *buf, char **Strings, int count, int size, char *table) |
| } else if (MyNumber(buf + 2 * i) > size) { |
| Strings[i] = ABSENT_STRING; |
| } else { |
| - Strings[i] = (MyNumber(buf + 2 * i) + table); |
| - TR(TRACE_DATABASE, ("Strings[%d] = %s", i, _nc_visbuf(Strings[i]))); |
| + int nn = MyNumber(buf + 2 * i); |
| + if (nn >= 0 && nn < size) { |
| + Strings[i] = (nn + table); |
| + TR(TRACE_DATABASE, ("Strings[%d] = %s", i, |
| + _nc_visbuf(Strings[i]))); |
| + } else { |
| + if (!corrupt) { |
| + corrupt = TRUE; |
| + TR(TRACE_DATABASE, |
| + ("ignore out-of-range index %d to Strings[]", nn)); |
| + _nc_warning("corrupt data found in convert_strings"); |
| + } |
| + Strings[i] = ABSENT_STRING; |
| + } |
| } |
| |
| /* make sure all strings are NUL terminated */ |
| @@ -776,7 +789,7 @@ _nc_read_tic_entry(char *filename, |
| * looking for compiled (binary) terminfo data. |
| * |
| * cgetent uses a two-level lookup. On the first it uses the given |
| - * name to return a record containing only the aliases for an entry. |
| + * name to return a record containing only the aliases for an entry. |
| * On the second (using that list of aliases as a key), it returns the |
| * content of the terminal description. We expect second lookup to |
| * return data beginning with the same set of aliases. |
| @@ -833,7 +846,7 @@ _nc_read_tic_entry(char *filename, |
| #endif /* NCURSES_USE_DATABASE */ |
| |
| /* |
| - * Find and read the compiled entry for a given terminal type, if it exists. |
| + * Find and read the compiled entry for a given terminal type, if it exists. |
| * We take pains here to make sure no combination of environment variables and |
| * terminal type name can be used to overrun the file buffer. |
| */ |
| -- |
| 2.36.1 |
| |