espeak-ng/espeak-ng-1.51-CVE-2023-49990-4.patch
Jaroslav Škarvada dcfb052d1a Fixed buffer overflow in SetUpPhonemeTable function at synthdata.c
Resolves: CVE-2023-49990
Fixed buffer underflow in CountVowelPosition function at synthdata.c
  Resolves: CVE-2023-49991
Fixed buffer overflow in RemoveEnding at dictionary.c
  Resolves: CVE-2023-49992
Fixed buffer overflow in ReadClause function at readclause.c
  Resolves: CVE-2023-49993
Fixed floating point exception in PeaksToHarmspect at wavegen.c
  Resolves: CVE-2023-49994
2024-01-03 21:55:51 +01:00

250 lines
9.2 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

diff --git a/tests/crash.test b/tests/crash.test
new file mode 100755
index 0000000000..184faf6eb8
--- /dev/null
+++ b/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
diff --git a/tests/crash_vectors/cve-2023-49990.txt b/tests/crash_vectors/cve-2023-49990.txt
new file mode 100644
index 0000000000..6708ca8895
--- /dev/null
+++ b/tests/crash_vectors/cve-2023-49990.txt
@@ -0,0 +1 @@
+ã¦à»Vñ€¦ñ
€¦V
€ä€ãÂà¦æsññâñþâññà¶æØØsññâñþâññeeeeeeeeseee€ññûñ
\ No newline at end of file
diff --git a/tests/crash_vectors/cve-2023-49991.txt b/tests/crash_vectors/cve-2023-49991.txt
new file mode 100644
index 0000000000..118f5b6131
--- /dev/null
+++ b/tests/crash_vectors/cve-2023-49991.txt
@@ -0,0 +1 @@
+€¦
€ñVðÕhñùâÿñVDíZ»»ÕöÖÖÖÖÖÖÖÖÖì»»º»Ö¾ÖÖÖÖÖÖ´ÖÖÖ»þþ÷ÜÖÖÖ»»º»Õª»»®îÿÿ€ê`v
\ No newline at end of file
diff --git a/tests/crash_vectors/cve-2023-49992.txt b/tests/crash_vectors/cve-2023-49992.txt
new file mode 100644
--- /dev/null
+++ b/tests/crash_vectors/cve-2023-49992.txt
@@ -0,0 +1 @@
+ÿÿÿÿÿè!ÿÿÿÿÿbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbIbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbÿ !ôÿÿÿ
\ No newline at end of file
diff --git a/tests/crash_vectors/cve-2023-49993.txt b/tests/crash_vectors/cve-2023-49993.txt
new file mode 100644
--- /dev/null
+++ b/tests/crash_vectors/cve-2023-49993.txt
@@ -0,0 +1,5 @@
+hV
+$
+V
+$
+B:\\lA:\@\“\Œ\HŒ\\“???T??%?\“\Œ\\Œ\000000000000000000000000000000000000000000000000000000000@000000000000000000000000000000??0$? æ#???æ ?-0?…000000L00„??ý?\HŒ\\“???T?? ?\“\Œ\\Œ\¤\u\D:\@\000L00„?“\Œ\HŒ\\“???T??%?\“\Œ\\Œ\0000000000000000200000000000000000000000000000000000000000000000000000000??0$? ? æ????æ ?-0?-…00000L00„???000E+0%!!?
\ No newline at end of file
diff --git a/tests/crash_vectors/cve-2023-49994.txt b/tests/crash_vectors/cve-2023-49994.txt
new file mode 100644
index 0000000000..72c0813d49
--- /dev/null
+++ b/tests/crash_vectors/cve-2023-49994.txt
@@ -0,0 +1 @@
+"[[-#,- -1-2.
r--ª#--O)C--!ÿE-1@5-!-V-1--
\ No newline at end of file
diff --git a/Makefile.am b/Makefile.am
index 0f4ba7a..354518f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -289,7 +289,8 @@ check: tests/encoding.check \
tests/windows-installer.check \
tests/bom.check \
tests/voices.check \
- tests/cmd_options.check
+ tests/cmd_options.check \
+ tests/crash.check
##### fuzzer:
diff --git a/src/libespeak-ng/dictionary.c b/src/libespeak-ng/dictionary.c
index a98caf5..43f9f6f 100644
--- a/src/libespeak-ng/dictionary.c
+++ b/src/libespeak-ng/dictionary.c
@@ -1062,6 +1062,9 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
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 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy)
*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);
diff --git a/src/libespeak-ng/readclause.c b/src/libespeak-ng/readclause.c
index de6cea5..5af40eb 100644
--- a/src/libespeak-ng/readclause.c
+++ b/src/libespeak-ng/readclause.c
@@ -665,7 +665,7 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_
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++] = ' ';
diff --git a/src/libespeak-ng/synthdata.c b/src/libespeak-ng/synthdata.c
index 3870edf..e990912 100644
--- a/src/libespeak-ng/synthdata.c
+++ b/src/libespeak-ng/synthdata.c
@@ -75,8 +75,15 @@ static espeak_ng_STATUS ReadPhFile(void **ptr, const char *fname, int *size, esp
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 @@ static espeak_ng_STATUS ReadPhFile(void **ptr, const char *fname, int *size, esp
int error = errno;
fclose(f_in);
free(*ptr);
+ *ptr = NULL;
return create_file_error_context(context, error, buf);
}
@@ -119,9 +127,11 @@ espeak_ng_STATUS LoadPhData(int *srate, espeak_ng_ERROR_CONTEXT *context)
// 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)
diff --git a/src/libespeak-ng/translate.c b/src/libespeak-ng/translate.c
index 0914619..9cf9503 100644
--- a/src/libespeak-ng/translate.c
+++ b/src/libespeak-ng/translate.c
@@ -2630,6 +2630,7 @@ void TranslateClause(Translator *tr, int *tone_out, char **voice_change)
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);
diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c
index add6b94..c8dd5aa 100644
--- a/src/libespeak-ng/voices.c
+++ b/src/libespeak-ng/voices.c
@@ -557,6 +557,10 @@ voice_t *LoadVoice(const char *vname, int control)
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);
@@ -940,14 +944,14 @@ voice_t *LoadVoice(const char *vname, int control)
if (!tone_only) {
if (!!(control & 8/*compiling phonemes*/)) {
- /* Set by espeak_ng_CompilePhonemeDataPath when it
- * calls LoadVoice("", 8) to set up a dummy(?) voice.
- * As phontab may not yet exist this avoids the spurious
- * error message and guarantees consistent results by
- * not actually reading a potentially bogus phontab...
- */
- ix = 0;
- } else if ((ix = SelectPhonemeTableName(phonemes_name)) < 0) {
+ /* Set by espeak_ng_CompilePhonemeDataPath when it
+ * calls LoadVoice("", 8) to set up a dummy(?) voice.
+ * As phontab may not yet exist this avoids the spurious
+ * error message and guarantees consistent results by
+ * not actually reading a potentially bogus phontab...
+ */
+ ix = 0;
+ } else if ((ix = SelectPhonemeTableName(phonemes_name)) < 0) {
fprintf(stderr, "Unknown phoneme table: '%s'\n", phonemes_name);
ix = 0;
}
diff --git a/src/libespeak-ng/wavegen.c b/src/libespeak-ng/wavegen.c
index 17d65f7..9d3b1ee 100644
--- a/src/libespeak-ng/wavegen.c
+++ b/src/libespeak-ng/wavegen.c
@@ -537,14 +537,14 @@ static void AdvanceParameters()
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;
@@ -560,7 +560,7 @@ static void AdvanceParameters()
if(const_f0)
wdata.pitch = (const_f0<<12);
-
+
if (wdata.pitch < 102400)
wdata.pitch = 102400; // min pitch, 25 Hz (25 << 12)
@@ -1268,6 +1268,9 @@ static int WavegenFill2()
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) {