diff --git a/less-590-CVE-2024-32487.patch b/less-590-CVE-2024-32487.patch new file mode 100644 index 0000000..61bbd0e --- /dev/null +++ b/less-590-CVE-2024-32487.patch @@ -0,0 +1,57 @@ +diff -up less-643/filename.c.CVE-2024-32487 less-643/filename.c +--- less-643/filename.c.CVE-2024-32487 2023-07-21 00:43:14.000000000 +0200 ++++ less-643/filename.c 2024-08-21 08:10:28.949475521 +0200 +@@ -134,6 +134,15 @@ static int metachar(char c) + } + + /* ++ * Must use quotes rather than escape char for this metachar? ++ */ ++static int must_quote(char c) ++{ ++ /* {{ Maybe the set of must_quote chars should be configurable? }} */ ++ return (c == '\n'); ++} ++ ++/* + * Insert a backslash before each metacharacter in a string. + */ + public char * shell_quote(char *s) +@@ -164,6 +173,9 @@ public char * shell_quote(char *s) + * doesn't support escape chars. Use quotes. + */ + use_quotes = 1; ++ } else if (must_quote(*p)) ++ { ++ len += 3; /* open quote + char + close quote */ + } else + { + /* +@@ -193,15 +205,22 @@ public char * shell_quote(char *s) + { + while (*s != '\0') + { +- if (metachar(*s)) ++ if (!metachar(*s)) + { +- /* +- * Add the escape char. +- */ ++ *p++ = *s++; ++ } else if (must_quote(*s)) ++ { ++ /* Surround the char with quotes. */ ++ *p++ = openquote; ++ *p++ = *s++; ++ *p++ = closequote; ++ } else ++ { ++ /* Insert an escape char before the char. */ + strcpy(p, esc); + p += esclen; ++ *p++ = *s++; + } +- *p++ = *s++; + } + *p = '\0'; + } diff --git a/less-633-control-char-in-filename-regrfix.patch b/less-633-control-char-in-filename-regrfix.patch new file mode 100644 index 0000000..d0c7fec --- /dev/null +++ b/less-633-control-char-in-filename-regrfix.patch @@ -0,0 +1,73 @@ +diff -up less-633/prompt.c.cve2024_32487regrfix less-633/prompt.c +--- less-633/prompt.c.cve2024_32487regrfix 2024-07-27 00:32:28.945249829 +0200 ++++ less-633/prompt.c 2024-07-27 00:34:36.456908956 +0200 +@@ -79,23 +79,44 @@ public void init_prompt(void) + + /* + * Append a string to the end of the message. +- */ +-static void ap_str(char *s) +-{ +- constant char *es = s + strlen(s); +- while (*s != '\0') +- { +- LWCHAR ch = step_char(&s, +1, es); +- constant char *ps = utf_mode ? prutfchar(ch) : prchar(ch); +- size_t plen = strlen(ps); +- if (mp + plen >= message + PROMPT_SIZE) +- break; +- strcpy(mp, ps); ++ * nprt means the character *may* be nonprintable ++ * and should be converted to printable form. ++ */ ++static void ap_estr(char *s, lbool nprt) ++ { ++ constant char *es = s + strlen(s); ++ while (*s != '\0') ++ { ++ LWCHAR ch = step_char(&s, +1, es); ++ constant char *ps; ++ char ubuf[MAX_UTF_CHAR_LEN+1]; ++ size_t plen; ++ ++ if (nprt) ++ { ++ ps = utf_mode ? prutfchar(ch) : prchar(ch); ++ } else ++ { ++ char *up = ubuf; ++ put_wchar(&up, ch); ++ *up = '\0'; ++ ps = ubuf; ++ } ++ plen = strlen(ps); ++ if (mp + plen >= message + PROMPT_SIZE) ++ break; ++ strcpy(mp, ps); + mp += plen; + } + *mp = '\0'; + } + ++static void ap_str(char *s) ++{ ++ ap_estr(s, FALSE); ++} ++ ++ + /* + * Append a character to the end of the message. + */ +@@ -289,10 +310,10 @@ static void protochar(int c, int where, + break; + #endif + case 'f': /* File name */ +- ap_str(get_filename(curr_ifile)); ++ ap_estr(get_filename(curr_ifile), TRUE); + break; + case 'F': /* Last component of file name */ +- ap_str(last_component(get_filename(curr_ifile))); ++ ap_estr(last_component(get_filename(curr_ifile)), TRUE); + break; + case 'g': /* Shell-escaped file name */ + s = shell_quote(get_filename(curr_ifile)); diff --git a/less-654-control-char-in-filename-prereq.patch b/less-654-control-char-in-filename-prereq.patch new file mode 100644 index 0000000..c0b2a8a --- /dev/null +++ b/less-654-control-char-in-filename-prereq.patch @@ -0,0 +1,17 @@ +diff -up less-633/prompt.c.cve_prereq less-633/prompt.c +--- less-633/prompt.c.cve_prereq 2024-07-27 00:44:40.347267609 +0200 ++++ less-633/prompt.c 2024-07-27 00:45:26.575783719 +0200 +@@ -36,6 +36,13 @@ extern char *editor; + extern char *editproto; + #endif + ++typedef enum lbool { LFALSE, LTRUE } lbool; ++ ++#undef TRUE ++#define TRUE LTRUE ++#undef FALSE ++#define FALSE LFALSE ++ + /* + * Prototypes for the three flavors of prompts. + * These strings are expanded by pr_expand(). diff --git a/less-654-control-char-in-filename.patch b/less-654-control-char-in-filename.patch new file mode 100644 index 0000000..b7412ca --- /dev/null +++ b/less-654-control-char-in-filename.patch @@ -0,0 +1,75 @@ +diff -up less-633/output.c.cve2024_32487fix less-633/output.c +--- less-633/output.c.cve2024_32487fix 2023-05-03 20:43:01.000000000 +0200 ++++ less-633/output.c 2024-07-27 00:28:05.420820950 +0200 +@@ -31,6 +31,7 @@ extern int so_s_width, so_e_width; + extern int screen_trashed; + extern int is_tty; + extern int oldbot; ++extern int utf_mode; + extern char intr_char; + + #if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC +@@ -537,6 +538,7 @@ IPRINT_FUNC(iprint_linenum, LINENUM, lin + public int less_printf(char *fmt, PARG *parg) + { + char *s; ++ constant char *es; + int col; + + col = 0; +@@ -553,11 +555,17 @@ public int less_printf(char *fmt, PARG * + { + case 's': + s = parg->p_string; ++ es = s + strlen(s); + parg++; + while (*s != '\0') + { +- putchr(*s++); +- col++; ++ LWCHAR ch = step_char(&s, +1, es); ++ constant char *ps = utf_mode ? prutfchar(ch) : prchar(ch); ++ while (*ps != '\0') ++ { ++ putchr(*ps++); ++ col++; ++ } + } + break; + case 'd': +diff -up less-633/prompt.c.cve2024_32487fix less-633/prompt.c +--- less-633/prompt.c.cve2024_32487fix 2024-07-27 00:26:13.217361006 +0200 ++++ less-633/prompt.c 2024-07-27 00:31:37.965586499 +0200 +@@ -30,6 +30,7 @@ extern int sc_height; + extern int jump_sline; + extern int less_is_more; + extern int header_lines; ++extern int utf_mode; + extern IFILE curr_ifile; + #if EDITOR + extern char *editor; +@@ -81,13 +82,17 @@ public void init_prompt(void) + */ + static void ap_str(char *s) + { +- int len; +- +- len = (int) strlen(s); +- if (mp + len >= message + PROMPT_SIZE) +- len = (int) (message + PROMPT_SIZE - mp - 1); +- strncpy(mp, s, len); +- mp += len; ++ constant char *es = s + strlen(s); ++ while (*s != '\0') ++ { ++ LWCHAR ch = step_char(&s, +1, es); ++ constant char *ps = utf_mode ? prutfchar(ch) : prchar(ch); ++ size_t plen = strlen(ps); ++ if (mp + plen >= message + PROMPT_SIZE) ++ break; ++ strcpy(mp, ps); ++ mp += plen; ++ } + *mp = '\0'; + } + diff --git a/less.spec b/less.spec index f664226..dc79be6 100644 --- a/less.spec +++ b/less.spec @@ -1,7 +1,7 @@ Summary: A text file browser similar to more, but better Name: less Version: 633 -Release: 2%{?dist} +Release: 4%{?dist} License: GPLv3+ or BSD Source0: https://www.greenwoodsoftware.com/less/%{name}-%{version}.tar.gz Source1: lesspipe.sh @@ -14,6 +14,12 @@ Patch8: less-458-lessecho-usage.patch Patch9: less-458-less-filters-man.patch Patch10: less-458-lesskey-usage.patch Patch11: less-458-old-bot-in-help.patch +# 3x from upstream, for less < 654, fix for filenames containing control chars +Patch12: less-654-control-char-in-filename-prereq.patch +Patch13: less-654-control-char-in-filename.patch +Patch14: less-633-control-char-in-filename-regrfix.patch +# from upstream, for less < 654, rhbz#2274980 +Patch15: less-590-CVE-2024-32487.patch URL: https://www.greenwoodsoftware.com/less/ BuildRequires: ncurses-devel BuildRequires: autoconf automake libtool @@ -31,14 +37,17 @@ files, and you'll use it frequently. %prep %setup -q -%patch4 -p1 -b .time -%patch5 -p1 -b .fsync -%patch6 -p1 -b .manpage-add-old-bot-option -%patch8 -p1 -b .lessecho-usage -%patch9 -p1 -b .less-filters-man -%patch10 -p1 -b .lesskey-usage -%patch11 -p1 -b .old-bot - +%patch -P 4 -p1 -b .time +%patch -P 5 -p1 -b .fsync +%patch -P 6 -p1 -b .manpage-add-old-bot-option +%patch -P 8 -p1 -b .lessecho-usage +%patch -P 9 -p1 -b .less-filters-man +%patch -P 10 -p1 -b .lesskey-usage +%patch -P 11 -p1 -b .old-bot +%patch -P 12 -p1 -b .ctrl-char-fname-prereq +%patch -P 13 -p1 -b .ctrl-char-fname +%patch -P 14 -p1 -b .ctrl-char-fname-regrfix +%patch -P 15 -p1 -b .CVE-2024-32487 %build rm -f ./configure @@ -61,6 +70,12 @@ install -p -m 644 %{SOURCE3} $RPM_BUILD_ROOT/etc/profile.d %{_mandir}/man1/* %changelog +* Wed Aug 21 2024 Michal Hlavinka - 643-6 +- fix CVE-2024-32487 - less with LESSOPEN mishandles \n in paths (#2274981) + +* Sun Jul 28 2024 Michal Hlavinka - 633-3 +- fix incorrect display when filename contains control chars + * Thu Jul 20 2023 Fedora Release Engineering - 633-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild