From 8bbd2407f0b07529fd09af63854776fb4ca43961 Mon Sep 17 00:00:00 2001 From: wk333 <13474090681@163.com> Date: Mon, 11 Dec 2023 14:17:27 +0800 Subject: [PATCH] Fix CVE-2022-26981,CVE-2022-31783,CVE-2023-26767,CVE-2023-26768 --- CVE-2022-26981.patch | 390 +++++++++++++++++++++++++++++++++++++++++++ CVE-2022-31783.patch | 39 +++++ CVE-2023-26767.patch | 45 +++++ CVE-2023-26768.patch | 40 +++++ liblouis.spec | 9 +- 5 files changed, 522 insertions(+), 1 deletion(-) create mode 100644 CVE-2022-26981.patch create mode 100644 CVE-2022-31783.patch create mode 100644 CVE-2023-26767.patch create mode 100644 CVE-2023-26768.patch diff --git a/CVE-2022-26981.patch b/CVE-2022-26981.patch new file mode 100644 index 0000000..7556016 --- /dev/null +++ b/CVE-2022-26981.patch @@ -0,0 +1,390 @@ +From 73751be7a5617bfff4a735ae095203a2d3ec50ef Mon Sep 17 00:00:00 2001 +From: Martin Gieseking +Date: Tue, 22 Mar 2022 15:31:04 +0100 +Subject: [PATCH] Prevent writing past CharString memory in compilePassOpcode + +Refer: https://github.com/liblouis/liblouis/commit/73751be + +--- + liblouis/compileTranslationTable.c | 199 ++++++++++++++++++++--------- + 1 file changed, 140 insertions(+), 59 deletions(-) + +diff --git a/liblouis/compileTranslationTable.c b/liblouis/compileTranslationTable.c +index 7e4b115..a2ba81e 100644 +--- a/liblouis/compileTranslationTable.c ++++ b/liblouis/compileTranslationTable.c +@@ -1640,6 +1640,17 @@ verifyStringOrDots(FileInfo *nested, TranslationTableOpcode opcode, int isString + return 0; + } + ++static int ++appendInstructionChar( ++ const FileInfo *file, widechar *passInstructions, int *passIC, widechar ch) { ++ if (*passIC >= MAXSTRING) { ++ compileError(file, "multipass operand too long"); ++ return 0; ++ } ++ passInstructions[(*passIC)++] = ch; ++ return 1; ++} ++ + static int + compilePassOpcode(FileInfo *nested, TranslationTableOpcode opcode, + CharacterClass *characterClasses, TranslationTableOffset *newRuleOffset, +@@ -1684,32 +1695,34 @@ compilePassOpcode(FileInfo *nested, TranslationTableOpcode opcode, + passLine.chars[endTest] = pass_endTest; + passLinepos = 0; + while (passLinepos <= endTest) { +- if (passIC >= MAXSTRING) { +- compileError(passNested, "Test part in multipass operand too long"); +- return 0; +- } + switch ((passSubOp = passLine.chars[passLinepos])) { + case pass_lookback: +- passInstructions[passIC++] = pass_lookback; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, pass_lookback)) ++ return 0; + passLinepos++; + passGetNumber(&passLine, &passLinepos, &passHoldNumber); + if (passHoldNumber == 0) passHoldNumber = 1; +- passInstructions[passIC++] = passHoldNumber; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, passHoldNumber)) ++ return 0; + break; + case pass_not: +- passInstructions[passIC++] = pass_not; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, pass_not)) ++ return 0; + passLinepos++; + break; + case pass_first: +- passInstructions[passIC++] = pass_first; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, pass_first)) ++ return 0; + passLinepos++; + break; + case pass_last: +- passInstructions[passIC++] = pass_last; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, pass_last)) ++ return 0; + passLinepos++; + break; + case pass_search: +- passInstructions[passIC++] = pass_search; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, pass_search)) ++ return 0; + passLinepos++; + break; + case pass_string: +@@ -1717,7 +1730,8 @@ compilePassOpcode(FileInfo *nested, TranslationTableOpcode opcode, + return 0; + } + passLinepos++; +- passInstructions[passIC++] = pass_string; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, pass_string)) ++ return 0; + passGetString(&passLine, &passLinepos, &passHoldString, passNested); + goto testDoCharsDots; + case pass_dots: +@@ -1725,20 +1739,28 @@ compilePassOpcode(FileInfo *nested, TranslationTableOpcode opcode, + return 0; + } + passLinepos++; +- passInstructions[passIC++] = pass_dots; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, pass_dots)) ++ return 0; + passGetDots(&passLine, &passLinepos, &passHoldString, passNested); + testDoCharsDots: + if (passHoldString.length == 0) return 0; +- passInstructions[passIC++] = passHoldString.length; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, passHoldString.length)) ++ return 0; + for (kk = 0; kk < passHoldString.length; kk++) +- passInstructions[passIC++] = passHoldString.chars[kk]; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, passHoldString.chars[kk])) ++ return 0; + break; + case pass_startReplace: +- passInstructions[passIC++] = pass_startReplace; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, pass_startReplace)) ++ return 0; + passLinepos++; + break; + case pass_endReplace: +- passInstructions[passIC++] = pass_endReplace; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, pass_endReplace)) ++ return 0; + passLinepos++; + break; + case pass_variable: +@@ -1747,26 +1769,37 @@ compilePassOpcode(FileInfo *nested, TranslationTableOpcode opcode, + return 0; + switch (passLine.chars[passLinepos]) { + case pass_eq: +- passInstructions[passIC++] = pass_eq; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, pass_eq)) ++ return 0; + goto doComp; + case pass_lt: + if (passLine.chars[passLinepos + 1] == pass_eq) { + passLinepos++; +- passInstructions[passIC++] = pass_lteq; +- } else +- passInstructions[passIC++] = pass_lt; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, pass_lteq)) ++ return 0; ++ } else if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, pass_lt)) ++ return 0; + goto doComp; + case pass_gt: + if (passLine.chars[passLinepos + 1] == pass_eq) { + passLinepos++; +- passInstructions[passIC++] = pass_gteq; +- } else +- passInstructions[passIC++] = pass_gt; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, pass_gteq)) ++ return 0; ++ } else if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, pass_gt)) ++ return 0; + doComp: +- passInstructions[passIC++] = passHoldNumber; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, passHoldNumber)) ++ return 0; + passLinepos++; + passGetNumber(&passLine, &passLinepos, &passHoldNumber); +- passInstructions[passIC++] = passHoldNumber; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, passHoldNumber)) ++ return 0; + break; + default: + compileError(passNested, "incorrect comparison operator"); +@@ -1778,25 +1811,34 @@ compilePassOpcode(FileInfo *nested, TranslationTableOpcode opcode, + if (!passGetAttributes(&passLine, &passLinepos, &passAttributes, passNested)) + return 0; + insertAttributes: +- passInstructions[passIC++] = pass_attributes; +- passInstructions[passIC++] = passAttributes >> 16; +- passInstructions[passIC++] = passAttributes & 0xffff; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, pass_attributes)) ++ return 0; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, (passAttributes >> 16) & 0xffff)) ++ return 0; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, passAttributes & 0xffff)) ++ return 0; + getRange: + if (passLine.chars[passLinepos] == pass_until) { + passLinepos++; +- passInstructions[passIC++] = 1; +- passInstructions[passIC++] = 0xffff; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, 1)) return 0; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, 0xffff)) ++ return 0; + break; + } + passGetNumber(&passLine, &passLinepos, &passHoldNumber); + if (passHoldNumber == 0) { +- passHoldNumber = passInstructions[passIC++] = 1; +- passInstructions[passIC++] = 1; /* This is not an error */ ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, 1)) return 0; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, 1)) return 0; + break; + } +- passInstructions[passIC++] = passHoldNumber; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, passHoldNumber)) ++ return 0; + if (passLine.chars[passLinepos] != pass_hyphen) { +- passInstructions[passIC++] = passHoldNumber; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, passHoldNumber)) ++ return 0; + break; + } + passLinepos++; +@@ -1805,7 +1847,8 @@ compilePassOpcode(FileInfo *nested, TranslationTableOpcode opcode, + compileError(passNested, "invalid range"); + return 0; + } +- passInstructions[passIC++] = passHoldNumber; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, passHoldNumber)) ++ return 0; + break; + case pass_groupstart: + case pass_groupend: +@@ -1815,9 +1858,14 @@ compilePassOpcode(FileInfo *nested, TranslationTableOpcode opcode, + if (ruleOffset) + rule = (TranslationTableRule *)&(*table)->ruleArea[ruleOffset]; + if (rule && rule->opcode == CTO_Grouping) { +- passInstructions[passIC++] = passSubOp; +- passInstructions[passIC++] = ruleOffset >> 16; +- passInstructions[passIC++] = ruleOffset & 0xffff; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, passSubOp)) ++ return 0; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, ruleOffset >> 16)) ++ return 0; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, ruleOffset & 0xffff)) ++ return 0; + break; + } else { + compileError(passNested, "%s is not a grouping name", +@@ -1836,16 +1884,22 @@ compilePassOpcode(FileInfo *nested, TranslationTableOpcode opcode, + rule = (TranslationTableRule *)&(*table)->ruleArea[ruleOffset]; + if (rule && (rule->opcode == CTO_SwapCc || rule->opcode == CTO_SwapCd || + rule->opcode == CTO_SwapDd)) { +- passInstructions[passIC++] = pass_swap; +- passInstructions[passIC++] = ruleOffset >> 16; +- passInstructions[passIC++] = ruleOffset & 0xffff; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, pass_swap)) ++ return 0; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, ruleOffset >> 16)) ++ return 0; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, ruleOffset & 0xffff)) ++ return 0; + goto getRange; + } + compileError(passNested, "%s is neither a class name nor a swap name.", + _lou_showString(&passHoldString.chars[0], passHoldString.length)); + return 0; + case pass_endTest: +- passInstructions[passIC++] = pass_endTest; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, pass_endTest)) ++ return 0; + passLinepos++; + break; + default: +@@ -1870,7 +1924,8 @@ compilePassOpcode(FileInfo *nested, TranslationTableOpcode opcode, + return 0; + } + passLinepos++; +- passInstructions[passIC++] = pass_string; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, pass_string)) ++ return 0; + passGetString(&passLine, &passLinepos, &passHoldString, passNested); + goto actionDoCharsDots; + case pass_dots: +@@ -1879,17 +1934,22 @@ compilePassOpcode(FileInfo *nested, TranslationTableOpcode opcode, + } + passLinepos++; + passGetDots(&passLine, &passLinepos, &passHoldString, passNested); +- passInstructions[passIC++] = pass_dots; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, pass_dots)) ++ return 0; + actionDoCharsDots: + if (passHoldString.length == 0) return 0; +- passInstructions[passIC++] = passHoldString.length; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, passHoldString.length)) ++ return 0; + for (kk = 0; kk < passHoldString.length; kk++) { + if (passIC >= MAXSTRING) { + compileError(passNested, + "@ operand in action part of multipass operand too long"); + return 0; + } +- passInstructions[passIC++] = passHoldString.chars[kk]; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, passHoldString.chars[kk])) ++ return 0; + } + break; + case pass_variable: +@@ -1898,16 +1958,25 @@ compilePassOpcode(FileInfo *nested, TranslationTableOpcode opcode, + return 0; + switch (passLine.chars[passLinepos]) { + case pass_eq: +- passInstructions[passIC++] = pass_eq; +- passInstructions[passIC++] = passHoldNumber; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, pass_eq)) ++ return 0; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, passHoldNumber)) ++ return 0; + passLinepos++; + passGetNumber(&passLine, &passLinepos, &passHoldNumber); +- passInstructions[passIC++] = passHoldNumber; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, passHoldNumber)) ++ return 0; + break; + case pass_plus: + case pass_hyphen: +- passInstructions[passIC++] = passLine.chars[passLinepos++]; +- passInstructions[passIC++] = passHoldNumber; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, ++ passLine.chars[passLinepos++])) ++ return 0; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, passHoldNumber)) ++ return 0; + break; + default: + compileError(passNested, "incorrect variable operator in action part"); +@@ -1915,11 +1984,13 @@ compilePassOpcode(FileInfo *nested, TranslationTableOpcode opcode, + } + break; + case pass_copy: +- passInstructions[passIC++] = pass_copy; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, pass_copy)) ++ return 0; + passLinepos++; + break; + case pass_omit: +- passInstructions[passIC++] = pass_omit; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, pass_omit)) ++ return 0; + passLinepos++; + break; + case pass_groupreplace: +@@ -1931,9 +2002,14 @@ compilePassOpcode(FileInfo *nested, TranslationTableOpcode opcode, + if (ruleOffset) + rule = (TranslationTableRule *)&(*table)->ruleArea[ruleOffset]; + if (rule && rule->opcode == CTO_Grouping) { +- passInstructions[passIC++] = passSubOp; +- passInstructions[passIC++] = ruleOffset >> 16; +- passInstructions[passIC++] = ruleOffset & 0xffff; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, passSubOp)) ++ return 0; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, ruleOffset >> 16)) ++ return 0; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, ruleOffset & 0xffff)) ++ return 0; + break; + } + compileError(passNested, "%s is not a grouping name", +@@ -1947,9 +2023,14 @@ compilePassOpcode(FileInfo *nested, TranslationTableOpcode opcode, + rule = (TranslationTableRule *)&(*table)->ruleArea[ruleOffset]; + if (rule && (rule->opcode == CTO_SwapCc || rule->opcode == CTO_SwapCd || + rule->opcode == CTO_SwapDd)) { +- passInstructions[passIC++] = pass_swap; +- passInstructions[passIC++] = ruleOffset >> 16; +- passInstructions[passIC++] = ruleOffset & 0xffff; ++ if (!appendInstructionChar(passNested, passInstructions, &passIC, pass_swap)) ++ return 0; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, ruleOffset >> 16)) ++ return 0; ++ if (!appendInstructionChar( ++ passNested, passInstructions, &passIC, ruleOffset & 0xffff)) ++ return 0; + break; + } + compileError(passNested, "%s is not a swap name.", +-- +2.33.0 + diff --git a/CVE-2022-31783.patch b/CVE-2022-31783.patch new file mode 100644 index 0000000..d09e166 --- /dev/null +++ b/CVE-2022-31783.patch @@ -0,0 +1,39 @@ +From 2e4772befb2b1c37cb4b9d6572945115ee28630a Mon Sep 17 00:00:00 2001 +From: Christian Egli +Date: Wed, 25 May 2022 18:08:36 +0200 +Subject: [PATCH] Prevent an invalid memory writes in compileRule + +Origin: https://github.com/liblouis/liblouis/commit/2e4772b + +--- + liblouis/compileTranslationTable.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/liblouis/compileTranslationTable.c b/liblouis/compileTranslationTable.c +index a2ba81e..50b86a9 100644 +--- a/liblouis/compileTranslationTable.c ++++ b/liblouis/compileTranslationTable.c +@@ -3244,12 +3244,14 @@ doOpcode: + case CTO_SeqAfterExpression: + + if (getRuleCharsText(nested, &ruleChars, &lastToken)) { +- for ((*table)->seqAfterExpressionLength = 0; +- (*table)->seqAfterExpressionLength < ruleChars.length; +- (*table)->seqAfterExpressionLength++) +- (*table)->seqAfterExpression[(*table)->seqAfterExpressionLength] = +- ruleChars.chars[(*table)->seqAfterExpressionLength]; +- (*table)->seqAfterExpression[(*table)->seqAfterExpressionLength] = 0; ++ if ((ruleChars.length + 1) > SEQPATTERNSIZE) { ++ compileError(nested, "More than %d characters", SEQPATTERNSIZE); ++ return 0; ++ } ++ for (int k = 0; k < ruleChars.length; k++) ++ (*table)->seqAfterExpression[k] = ruleChars.chars[k]; ++ (*table)->seqAfterExpression[ruleChars.length] = 0; ++ (*table)->seqAfterExpressionLength = ruleChars.length; + } + break; + +-- +2.33.0 + diff --git a/CVE-2023-26767.patch b/CVE-2023-26767.patch new file mode 100644 index 0000000..77e115e --- /dev/null +++ b/CVE-2023-26767.patch @@ -0,0 +1,45 @@ +From f432de31058b5a94874d47405216d07910c18a9a Mon Sep 17 00:00:00 2001 +From: Christian Egli +Date: Wed, 8 Feb 2023 11:18:27 +0100 +Subject: [PATCH] Check the length of path before copying into dataPath + +See https://lwn.net/Articles/507319/ for more background on the +security problems of strcpy. + +Origin: https://github.com/liblouis/liblouis/commit/f432de3 + +--- + liblouis/compileTranslationTable.c | 2 +- + liblouis/liblouis.h.in | 3 ++- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/liblouis/compileTranslationTable.c b/liblouis/compileTranslationTable.c +index 50b86a9..1efc57f 100644 +--- a/liblouis/compileTranslationTable.c ++++ b/liblouis/compileTranslationTable.c +@@ -58,7 +58,7 @@ char *EXPORT_CALL + lou_setDataPath(const char *path) { + static char dataPath[MAXSTRING]; + dataPathPtr = NULL; +- if (path == NULL) return NULL; ++ if (path == NULL || strlen(path) >= MAXSTRING) return NULL; + strcpy(dataPath, path); + dataPathPtr = dataPath; + return dataPathPtr; +diff --git a/liblouis/liblouis.h.in b/liblouis/liblouis.h.in +index cde3e8b..42d2770 100644 +--- a/liblouis/liblouis.h.in ++++ b/liblouis/liblouis.h.in +@@ -282,7 +282,8 @@ lou_getEmphClasses(const char *tableList); + /** + * Set the path used for searching for tables and liblouisutdml files. + * +- * Overrides the installation path. */ ++ * Overrides the installation path. Returns NULL if `path` is NULL or ++ * if the length of `path` is equal or longer than `MAXSTRING`. */ + LIBLOUIS_API + char *EXPORT_CALL + lou_setDataPath(const char *path); +-- +2.33.0 + diff --git a/CVE-2023-26768.patch b/CVE-2023-26768.patch new file mode 100644 index 0000000..47da75b --- /dev/null +++ b/CVE-2023-26768.patch @@ -0,0 +1,40 @@ +From 565ac66ec0c187ffb442226487de3db376702958 Mon Sep 17 00:00:00 2001 +From: Marsman1996 +Date: Thu, 9 Feb 2023 18:56:21 +0800 +Subject: [PATCH] Check filename before coping to initialLogFileName + +Origin: https://github.com/liblouis/liblouis/commit/565ac66 +https://github.com/liblouis/liblouis/commit/47822bb + +--- + liblouis/logging.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/liblouis/logging.c b/liblouis/logging.c +index bbffdcc..10f0d9f 100644 +--- a/liblouis/logging.c ++++ b/liblouis/logging.c +@@ -117,8 +117,10 @@ _lou_logMessage(logLevels level, const char *format, ...) { + } + } + ++#define FILENAMESIZE 256 ++ + static FILE *logFile = NULL; +-static char initialLogFileName[256] = ""; ++static char initialLogFileName[FILENAMESIZE] = ""; + + void EXPORT_CALL + lou_logFile(const char *fileName) { +@@ -126,7 +128,7 @@ lou_logFile(const char *fileName) { + fclose(logFile); + logFile = NULL; + } +- if (fileName == NULL || fileName[0] == 0) return; ++ if (fileName == NULL || fileName[0] == 0 || strlen(fileName) >= FILENAMESIZE) return; + if (initialLogFileName[0] == 0) strcpy(initialLogFileName, fileName); + logFile = fopen(fileName, "a"); + if (logFile == NULL && initialLogFileName[0] != 0) +-- +2.33.0 + diff --git a/liblouis.spec b/liblouis.spec index f16be03..291acfa 100644 --- a/liblouis.spec +++ b/liblouis.spec @@ -2,12 +2,16 @@ Name: liblouis Version: 3.7.0 -Release: 4 +Release: 5 Summary: Braille translation and back-translation library License: LGPLv3+ and GPLv3+ URL: http://liblouis.org Source0: https://github.com/%{name}/%{name}/releases/download/v%{version}/%{name}-%{version}.tar.gz Patch0001: CVE-2023-26769.patch +Patch0002: CVE-2022-26981.patch +Patch0003: CVE-2022-31783.patch +Patch0004: CVE-2023-26767.patch +Patch0005: CVE-2023-26768.patch Recommends: %{name}-help = %{version}-%{release} BuildRequires: chrpath gcc help2man texinfo texinfo-tex texlive-eurosym BuildRequires: texlive-xetex python2-devel python3-devel @@ -135,6 +139,9 @@ done %{python3_sitelib}/louis/ %changelog +* Mon Dec 11 2023 wangkai <13474090681@163.com> - 3.7.0-5 +- Fix CVE-2022-26981,CVE-2022-31783,CVE-2023-26767,CVE-2023-26768 + * Wed Mar 22 2023 yaoxin - 3.7.0-4 - Fix CVE-2023-26769 -- Gitee