Fix CVE-2022-26981,CVE-2022-31783,CVE-2023-26767,CVE-2023-26768

This commit is contained in:
wk333 2023-12-11 14:49:40 +08:00
parent 66d6564a49
commit 7aa4345cd6
5 changed files with 522 additions and 1 deletions

390
CVE-2022-26981.patch Normal file
View File

@ -0,0 +1,390 @@
From 73751be7a5617bfff4a735ae095203a2d3ec50ef Mon Sep 17 00:00:00 2001
From: Martin Gieseking <martin.gieseking@uos.de>
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

39
CVE-2022-31783.patch Normal file
View File

@ -0,0 +1,39 @@
From 2e4772befb2b1c37cb4b9d6572945115ee28630a Mon Sep 17 00:00:00 2001
From: Christian Egli <christian.egli@sbs.ch>
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

45
CVE-2023-26767.patch Normal file
View File

@ -0,0 +1,45 @@
From f432de31058b5a94874d47405216d07910c18a9a Mon Sep 17 00:00:00 2001
From: Christian Egli <christian.egli@sbs.ch>
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

40
CVE-2023-26768.patch Normal file
View File

@ -0,0 +1,40 @@
From 565ac66ec0c187ffb442226487de3db376702958 Mon Sep 17 00:00:00 2001
From: Marsman1996 <lqliuyuwei@outlook.com>
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

View File

@ -2,13 +2,17 @@
Name: liblouis
Version: 3.7.0
Release: 5
Release: 6
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
Patch0000: 0001-fix-memory-issue-introduced-with-GCC9.patch
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
BuildRequires: chrpath gcc help2man texinfo texinfo-tex texlive-eurosym
BuildRequires: texlive-xetex python3-devel
Provides: bundled(gnulib) = 20130621
@ -116,6 +120,9 @@ done
%{python3_sitelib}/louis/
%changelog
* Mon Dec 11 2023 wangkai <13474090681@163.com> - 3.7.0-6
- Fix CVE-2022-26981,CVE-2022-31783,CVE-2023-26767,CVE-2023-26768
* Wed Mar 22 2023 yaoxin <yaoxin30@h-partners.com> - 3.7.0-5
- Fix CVE-2023-26769