Sync from SUSE:SLFO:Main espeak-ng revision d862222785e42c47df9cffc3ac495579
This commit is contained in:
parent
8ee178b4e5
commit
e8da50f8dd
BIN
espeak-ng-1.51.1.tar.gz
(Stored with Git LFS)
Normal file
BIN
espeak-ng-1.51.1.tar.gz
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
espeak-ng-1.51.tar.gz
(Stored with Git LFS)
BIN
espeak-ng-1.51.tar.gz
(Stored with Git LFS)
Binary file not shown.
290
espeak-ng-CVE-2023-49990-49991-49992-49993-49994.patch
Normal file
290
espeak-ng-CVE-2023-49990-49991-49992-49993-49994.patch
Normal file
@ -0,0 +1,290 @@
|
||||
commit 58f1e0b6a4e6aa55621c6f01118994d01fd6f68c
|
||||
Merge: f983e445 e7bcd3cc
|
||||
Author: Alexander Epaneshnikov <aarnaarn2@gmail.com>
|
||||
Date: Sun Dec 17 15:29:30 2023 +0300
|
||||
|
||||
tests: fix CVE crashes (#1846)
|
||||
|
||||
Fixes: #1823, #1824, #1825, #1826, #1827
|
||||
|
||||
- Add crash test and vectors provided by @SEU-SSL
|
||||
- Disallow dummy/null voice load (that causes incorrect translator
|
||||
initialization)
|
||||
- Fix empty `phondata` file load (that causes unitialized memory access)
|
||||
- Limit max word length for RemoveEnding (causes buffer overflow)
|
||||
- Limit punctlist initialization from embedded commands (buffer
|
||||
overflow)
|
||||
- Fix unitialized pitch in wavegen (DBZ and indexing problems)
|
||||
- Properly zeroize stack variables before use in TranslateClause and
|
||||
SetWordStress
|
||||
|
||||
TODO (in nextup PR): add & fix more vectors from fuzzer.
|
||||
|
||||
--- espeak-ng-1.51.1/src/libespeak-ng/dictionary.c
|
||||
+++ espeak-ng-1.51.1_new/src/libespeak-ng/dictionary.c
|
||||
@@ -1062,6 +1062,9 @@
|
||||
|
||||
static char consonant_types[16] = { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
+ memset(syllable_weight, 0, sizeof(syllable_weight));
|
||||
+ memset(vowel_length, 0, sizeof(vowel_length));
|
||||
+
|
||||
stressflags = tr->langopts.stress_flags;
|
||||
|
||||
if (dictionary_flags != NULL)
|
||||
@@ -3070,6 +3073,7 @@
|
||||
*word_end = 'e';
|
||||
}
|
||||
i = word_end - word;
|
||||
+ if (i >= N_WORD_BYTES) i = N_WORD_BYTES-1;
|
||||
|
||||
if (word_copy != NULL) {
|
||||
memcpy(word_copy, word, i);
|
||||
|
||||
--- espeak-ng-1.51.1/src/libespeak-ng/readclause.c
|
||||
+++ espeak-ng-1.51.1_new/src/libespeak-ng/readclause.c
|
||||
@@ -665,7 +665,7 @@
|
||||
if (c2 != '1') {
|
||||
// a list of punctuation characters to be spoken, terminated by space
|
||||
j = 0;
|
||||
- while (!iswspace(c2) && !Eof()) {
|
||||
+ while (!Eof() && !iswspace(c2) && (j < N_PUNCTLIST-1)) {
|
||||
option_punctlist[j++] = c2;
|
||||
c2 = GetC();
|
||||
buf[ix++] = ' ';
|
||||
|
||||
--- espeak-ng-1.51.1/src/libespeak-ng/synthdata.c
|
||||
+++ espeak-ng-1.51.1_new/src/libespeak-ng/synthdata.c
|
||||
@@ -75,8 +75,15 @@
|
||||
if ((f_in = fopen(buf, "rb")) == NULL)
|
||||
return create_file_error_context(context, errno, buf);
|
||||
|
||||
- if (*ptr != NULL)
|
||||
+ if (*ptr != NULL) {
|
||||
free(*ptr);
|
||||
+ *ptr = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (length == 0) {
|
||||
+ *ptr = NULL;
|
||||
+ return 0;
|
||||
+ }
|
||||
|
||||
if ((*ptr = malloc(length)) == NULL) {
|
||||
fclose(f_in);
|
||||
@@ -86,6 +93,7 @@
|
||||
int error = errno;
|
||||
fclose(f_in);
|
||||
free(*ptr);
|
||||
+ *ptr = NULL;
|
||||
return create_file_error_context(context, error, buf);
|
||||
}
|
||||
|
||||
@@ -119,9 +127,11 @@
|
||||
// read the version number and sample rate from the first 8 bytes of phondata
|
||||
version = 0; // bytes 0-3, version number
|
||||
rate = 0; // bytes 4-7, sample rate
|
||||
- for (ix = 0; ix < 4; ix++) {
|
||||
- version += (wavefile_data[ix] << (ix*8));
|
||||
- rate += (wavefile_data[ix+4] << (ix*8));
|
||||
+ if (wavefile_data) {
|
||||
+ for (ix = 0; ix < 4; ix++) {
|
||||
+ version += (wavefile_data[ix] << (ix*8));
|
||||
+ rate += (wavefile_data[ix+4] << (ix*8));
|
||||
+ }
|
||||
}
|
||||
|
||||
if (version != version_phdata)
|
||||
|
||||
--- espeak-ng-1.51.1/src/libespeak-ng/translate.c
|
||||
+++ espeak-ng-1.51.1_new/src/libespeak-ng/translate.c
|
||||
@@ -2630,6 +2630,7 @@
|
||||
if (dict_flags & FLAG_SPELLWORD) {
|
||||
// redo the word, speaking single letters
|
||||
for (pw = word; *pw != ' ';) {
|
||||
+ memset(number_buf, 0, sizeof(number_buf));
|
||||
memset(number_buf, ' ', 9);
|
||||
nx = utf8_in(&c_temp, pw);
|
||||
memcpy(&number_buf[2], pw, nx);
|
||||
|
||||
--- espeak-ng-1.51.1/src/libespeak-ng/voices.c
|
||||
+++ espeak-ng-1.51.1_new/src/libespeak-ng/voices.c
|
||||
@@ -557,6 +557,10 @@
|
||||
static char voice_name[40]; // voice name for current_voice_selected
|
||||
static char voice_languages[100]; // list of languages and priorities for current_voice_selected
|
||||
|
||||
+ if ((vname == NULL || vname[0] == 0) && !(control & 8)) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
strncpy0(voicename, vname, sizeof(voicename));
|
||||
if (control & 0x10) {
|
||||
strcpy(buf, vname);
|
||||
|
||||
--- espeak-ng-1.51.1/src/libespeak-ng/wavegen.c
|
||||
+++ espeak-ng-1.51.1_new/src/libespeak-ng/wavegen.c
|
||||
@@ -537,14 +537,14 @@
|
||||
if (wvoice == NULL)
|
||||
return;
|
||||
|
||||
- int x;
|
||||
+ int x = 0;
|
||||
int ix;
|
||||
static int Flutter_ix = 0;
|
||||
|
||||
// advance the pitch
|
||||
wdata.pitch_ix += wdata.pitch_inc;
|
||||
if ((ix = wdata.pitch_ix>>8) > 127) ix = 127;
|
||||
- x = wdata.pitch_env[ix] * wdata.pitch_range;
|
||||
+ if (wdata.pitch_env) x = wdata.pitch_env[ix] * wdata.pitch_range;
|
||||
wdata.pitch = (x>>8) + wdata.pitch_base;
|
||||
|
||||
|
||||
@@ -1268,6 +1268,10 @@
|
||||
static bool resume = false;
|
||||
static int echo_complete = 0;
|
||||
|
||||
+
|
||||
+ if (wdata.pitch < 102400)
|
||||
+ wdata.pitch = 102400; // min pitch, 25 Hz (25 << 12)
|
||||
+
|
||||
while (out_ptr < out_end) {
|
||||
if (WcmdqUsed() <= 0) {
|
||||
if (echo_complete > 0) {
|
||||
|
||||
--- espeak-ng-1.51.1/tests/CMakeLists.txt
|
||||
+++ espeak-ng-1.51.1_new/tests/CMakeLists.txt
|
||||
@@ -0,0 +1,78 @@
|
||||
+include(CTest)
|
||||
+
|
||||
+list(APPEND _binary_tests)
|
||||
+
|
||||
+macro(compiled_test _test_name)
|
||||
+ add_executable(test_${_test_name}
|
||||
+ $<TARGET_OBJECTS:espeak-ng>
|
||||
+ ${_test_name}.c
|
||||
+ )
|
||||
+ target_link_libraries(test_${_test_name} PRIVATE
|
||||
+ $<TARGET_PROPERTY:espeak-ng,LINK_LIBRARIES>
|
||||
+ )
|
||||
+ target_compile_definitions(test_${_test_name} PRIVATE LIBESPEAK_NG_EXPORT=1)
|
||||
+ target_include_directories(
|
||||
+ test_${_test_name} PRIVATE
|
||||
+ $<TARGET_PROPERTY:espeak-ng,SOURCE_DIR>
|
||||
+ $<TARGET_PROPERTY:espeak-ng,SOURCE_DIR>/include/compat
|
||||
+ $<TARGET_PROPERTY:espeak-ng,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
+ $<TARGET_PROPERTY:espeak-ng-config,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
+ )
|
||||
+ if (MINGW)
|
||||
+ target_link_options(test_${_test_name} PUBLIC "-static" "-static-libstdc++")
|
||||
+ endif()
|
||||
+ add_dependencies(test_${_test_name} data)
|
||||
+ add_test(
|
||||
+ NAME ${_test_name}
|
||||
+ COMMAND ${ESPEAK_RUN_ENV} $<TARGET_FILE:test_${_test_name}>
|
||||
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/..
|
||||
+ )
|
||||
+ list(APPEND _binary_tests test_${_test_name})
|
||||
+endmacro(compiled_test)
|
||||
+
|
||||
+find_program(SHELL bash)
|
||||
+
|
||||
+macro(shell_test _test_name)
|
||||
+ add_test(
|
||||
+ NAME ${_test_name}
|
||||
+ COMMAND ${ESPEAK_RUN_ENV} ESPEAK_BIN=$<TARGET_FILE:espeak-ng-bin> ${SHELL} ${CMAKE_CURRENT_SOURCE_DIR}/${_test_name}.test
|
||||
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/..
|
||||
+ )
|
||||
+endmacro(shell_test)
|
||||
+
|
||||
+compiled_test(api)
|
||||
+compiled_test(encoding)
|
||||
+compiled_test(ieee80)
|
||||
+compiled_test(readclause)
|
||||
+
|
||||
+if (SHELL AND UNIX)
|
||||
+
|
||||
+shell_test(bom)
|
||||
+shell_test(non-executable-files-with-executable-bit)
|
||||
+
|
||||
+shell_test(cmd_options)
|
||||
+shell_test(dictionary)
|
||||
+shell_test(language-numbers-cardinal)
|
||||
+shell_test(language-numbers-ordinal)
|
||||
+shell_test(language-phonemes)
|
||||
+shell_test(language-pronunciation)
|
||||
+shell_test(language-replace)
|
||||
+shell_test(ssml)
|
||||
+shell_test(translate)
|
||||
+shell_test(variants)
|
||||
+shell_test(voices)
|
||||
+shell_test(crash)
|
||||
+
|
||||
+# shell_test(windows-data)
|
||||
+# shell_test(windows-installer)
|
||||
+
|
||||
+if (USE_KLATT)
|
||||
+ shell_test(klatt)
|
||||
+endif()
|
||||
+if (USE_MBROLA)
|
||||
+ shell_test(mbrola)
|
||||
+endif()
|
||||
+
|
||||
+endif()
|
||||
+
|
||||
+add_custom_target(tests DEPENDS ${_binary_tests})
|
||||
|
||||
--- espeak-ng-1.51.1/tests/crash.test
|
||||
+++ espeak-ng-1.51.1_new/tests/crash.test
|
||||
@@ -0,0 +1,17 @@
|
||||
+#!/bin/sh
|
||||
+# include common script
|
||||
+. "`dirname $0`/common"
|
||||
+
|
||||
+test_crash() {
|
||||
+ TEST_NAME=$1
|
||||
+
|
||||
+ echo "testing CVE-${TEST_NAME}"
|
||||
+ ESPEAK_DATA_PATH=`pwd` LD_LIBRARY_PATH=src:${LD_LIBRARY_PATH} \
|
||||
+ $VALGRIND src/espeak-ng -f "$(dirname $0)/crash_vectors/${TEST_NAME}.txt" -w /dev/null || exit 1
|
||||
+}
|
||||
+
|
||||
+test_crash cve-2023-49990
|
||||
+test_crash cve-2023-49991
|
||||
+test_crash cve-2023-49992
|
||||
+test_crash cve-2023-49993
|
||||
+test_crash cve-2023-49994
|
||||
|
||||
--- espeak-ng-1.51.1/tests/crash_vectors/cve-2023-49990.txt
|
||||
+++ espeak-ng-1.51.1_new/tests/crash_vectors/cve-2023-49990.txt
|
||||
@@ -0,0 +1 @@
|
||||
+ã¦à»Vñ€¦ñ
€¦V
€äVñ€ãÂà¦æsññâñþâññà¶æØØsññâñþâññeeeeeeeeseee€ññûñ
|
||||
\ 文件末尾没有æ<E280B0>¢è¡Œç¬¦
|
||||
|
||||
--- espeak-ng-1.51.1/tests/crash_vectors/cve-2023-49991.txt
|
||||
+++ espeak-ng-1.51.1_new/tests/crash_vectors/cve-2023-49991.txt
|
||||
@@ -0,0 +1 @@
|
||||
+€¦Vñ
€ñVðÕhñùâÿñVDíZ»»ÕöÖÖÖÖÖÖÖÖÖì»»º»Ö¾ÖÖÖÖÖÖ´ÖÖÖ»þþ÷ÜÖÖÖ»»º»Õª»»®îÿÿ€ê`v
|
||||
\ 文件末尾没有æ<E280B0>¢è¡Œç¬¦
|
||||
|
||||
--- espeak-ng-1.51.1/tests/crash_vectors/cve-2023-49992.txt
|
||||
+++ espeak-ng-1.51.1_new/tests/crash_vectors/cve-2023-49992.txt
|
||||
@@ -0,0 +1 @@
|
||||
+ÿÿÿÿÿè!ÿÿÿÿÿbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbIbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbÿ |