Speex issueshttps://gitlab.xiph.org/xiph/speex/-/issues2023-11-14T16:39:37Zhttps://gitlab.xiph.org/xiph/speex/-/issues/2046Leakage of uninitialized stack content in FIXED_POINT speex_decode()2023-11-14T16:39:37ZGeorgios VasilakopoulosLeakage of uninitialized stack content in FIXED_POINT speex_decode()The "speex.o" module provides several high level API functions for
managing encoding and decoding procedures with speex. One of these functions
is speex_decode, defined in libspeex/speex.c in line 115. It is a general
purpose function...The "speex.o" module provides several high level API functions for
managing encoding and decoding procedures with speex. One of these functions
is speex_decode, defined in libspeex/speex.c in line 115. It is a general
purpose function for decoding data from a bit stream and placing them in
an "out" buffer:
115: EXPORT int speex_decode(void *state, SpeexBits *bits, float *out)
{
int i, ret;
spx_int32_t N;
spx_int16_t short_out[MAX_IN_SAMPLES];
speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
121: ret = (*((SpeexMode**)state))->dec(state, bits, short_out);
122:for (i=0;i<N;i++)
out[i] = short_out[i];
return ret;
}
It is worth noting that this definition of speex_decode is used in the "fixed
point" implementation (libspeex/speex.c line 85).
The issue with this function is that if the call to
(*((SpeexMode**)state))->dec at line 121 fails prematurely, the "for" loop at
line 122 will copy the uninitialized "short_out" buffer directly into the
output buffer (after performing a cast from a short to a float).
By examining the definition of the invoked structure-member function, one can
see that it directly calls the decode function (see "dec") of the mode
selected upon initialization (nb_decode/sb_decode):
include/speex.h:
/** Struct defining a Speex mode */
250:typedef struct SpeexMode {
/** Pointer to the low-level mode data */
const void *mode;
...
/** Pointer to frame decoding function */
283:decode_func dec;
/** ioctl-like requests for encoder */
encoder_ctl_func enc_ctl;
/** ioctl-like requests for decoder */
decoder_ctl_func dec_ctl;
} SpeexMode;
If the selected mode is narrowband, then the execution at
libspeex/speex.c:121 will proceed at nb_decode, which is defined
at libspeex/nb_celp.c:1333
1333: int nb_decode(void *state, SpeexBits *bits, void *vout)
{
...
spx_word16_t *out = (spx_word16_t*)vout;
...
do {
1379:if (speex_bits_remaining(bits)<5)
return -1;
...
m = speex_bits_unpack_unsigned(bits, 4);
...
1438:} else if (m>8) /* Invalid mode */
{
speex_notify("Invalid mode encountered. The stream is corrupted.");
return -2;
}
...
iir_mem16(st->exc, lpc, out, NB_FRAME_SIZE, NB_ORDER, st->mem_sp, stack);
...
}
Notice that there are several user-induced cases where the call to nb_decode
(and hence to (*((SpeexMode**)state))->dec ) will fail before anything is
written to the "vout" buffer. One case, at line 1379, is to provide an
unexpectedly small bit stream. Another, at line 1438, is to provide an
invalid mode.
Because of the fact that speex_decode is such a general purpose, high level
function of the API, even simple programs that utilize the API are prone
to trigger this bug. The following code is from sampledec.c which is a
simple demo program that was included in the speex distribution as well as the
speex manual:
int main(int argc, char **argv)
{
...
/*Create a new decoder state in narrowband mode*/
state = speex_decoder_init(&speex_nb_mode);
...
outFile = argv[1];
fout = fopen(outFile, "w");
/*Initialization of the structure that holds the bits*/
speex_bits_init(&bits);
while (1)
{
...
/*Read the "packet" encoded by sampleenc*/
fread(cbits, 1, nbBytes, stdin);
/*Copy the data into the bit-stream struct*/
speex_bits_read_from(&bits, cbits, nbBytes);
/*Decode the data*/
49:speex_decode(state, &bits, output);
/*Copy from float to short (16 bits) for output*/
52:for (i=0;i<FRAME_SIZE;i++)
out[i]=output[i];
/*Write the decoded audio to file*/
56:fwrite(out, sizeof(short), FRAME_SIZE, fout);
}
...
return 0;
}
One can observe that if a user supplies invalid data, that will cause the
indirect call to nb_decode to fail prematurely and as explained, the output
buffer will contain leaked stack content. Furthermore, this leaked content
will be transported directly to the output (lines 52 - 56).
It is true that checking the return value of speex_decode would
be sufficient to protect a program from using and further propagating the
leaked stack content.
However we would like to point out two important factors here:
- Firstly, the program linking to the speex library might have initialized
the "out" buffer with zeroes so as to proactively prevent any
buffer leakage to the output audio. The abovementioned bug in speex_decode
would essentially nullify this proactive defense.
- Secondly, there is a significant number of programs that use speex
and which do not check for speex_decode's return value:
https://github.com/WPMGPRoSToTeMa/VoiceTranscoder/blob/a9ae70b436e26f6589ac7841749ce281c227bb2c/VoiceCodec_Speex.cpp#L118
https://github.com/rhuitl/uClinux/blob/0486e80a025dccbe4a2213715a2ab8a5063ea86b/lib/libopenh323/plugins/audio/Speex/speexcodec.cxx#L207
https://github.com/Garey27/revoice-plus/blob/f286851ff9e54fc2beef72a5b5dd267f8fbd08ba/revoice/src/VoiceEncoder_Speex.cpp#L90
...
Therefore, we feel that the Speex code is sharing some of the responsibility
for this stack content leak, and that is why we are raising
this as a code quality issue on Speex rather than a Speex vulnerability.
A possible remediation would be to add return value checks immediately
after the function call of line 121 at libspeex/speex.c. Alternatively,
one could initialize the "short_out" buffer with zeroes prior to the dec()
function call.
For a proof-of-concept please see the files in [issue3_poc.tar.gz](/uploads/47693cec3f488ba3f1817dcb72ab0a0f/issue3_poc.tar.gz)https://gitlab.xiph.org/xiph/speex/-/issues/2043Echo canceller removing low frequencies2023-10-10T08:45:03ZMassimo BEcho canceller removing low frequenciesHi, is this the official Speex repo?
Coming from https://github.com/wwmm/easyeffects/issues/2479
EasyEffects has recently migrated to using Speex filters.
Enabling "Echo canceller" removes a lot of low frequencies. I'm using the defaul...Hi, is this the official Speex repo?
Coming from https://github.com/wwmm/easyeffects/issues/2479
EasyEffects has recently migrated to using Speex filters.
Enabling "Echo canceller" removes a lot of low frequencies. I'm using the default settings.
I only have effects for the input using a USB condenser microphone, no effects on output side. I'm testing with headphones and the monitor-button on bottom right of the EasyEffects gui. So actually the Echo Canceller has nothing to cancel right now.
The default settings are:
Filter length 100ms
Residual Echo Suppression -7https://gitlab.xiph.org/xiph/speex/-/issues/1832Encoding state on the fly2018-01-21T13:05:26ZGitlab BotEncoding state on the flyWhen i create and destroy my encoding state and my Bits for each frame i get a "tick" between each of them. Since it's not in the documention i though i will give you the feedback. A lot of people are not supposed to know that, specially...When i create and destroy my encoding state and my Bits for each frame i get a "tick" between each of them. Since it's not in the documention i though i will give you the feedback. A lot of people are not supposed to know that, specially C++ programmers who usually create objects as needed.Jean-Marc ValinJean-Marc Valinhttps://gitlab.xiph.org/xiph/speex/-/issues/1739Speex uses GCC specific compile option2018-01-21T13:05:26ZBrian CameronSpeex uses GCC specific compile option
Speex will not compile with the Sun Studio compiler because it uses a GCC-specific compile option. Can this be removed, or can the configure script be made smarter so it only adds this sort of compile option when GCC is actually being ...
Speex will not compile with the Sun Studio compiler because it uses a GCC-specific compile option. Can this be removed, or can the configure script be made smarter so it only adds this sort of compile option when GCC is actually being used. See attached patch to see the issue.Jean-Marc ValinJean-Marc Valinhttps://gitlab.xiph.org/xiph/speex/-/issues/1616Problem configuring speex 1.2rc12018-01-21T13:05:26ZPierreProblem configuring speex 1.2rc1[...]
checking for main in -lwinmm... yes
checking for pkg-config... /usr/local/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
checking for short... yes
checking size of short... configure: error: cannot compute size...[...]
checking for main in -lwinmm... yes
checking for pkg-config... /usr/local/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
checking for short... yes
checking size of short... configure: error: cannot compute sizeof (short)
See `config.log' for more details.
Jean-Marc ValinJean-Marc Valinhttps://gitlab.xiph.org/xiph/speex/-/issues/1511add Haiku types in speex_types.h2018-01-21T13:05:26ZGitlab Botadd Haiku types in speex_types.hPatch to add Haiku types for speex.Patch to add Haiku types for speex.Jean-Marc ValinJean-Marc Valinhttps://gitlab.xiph.org/xiph/speex/-/issues/1349[PATCH] --enable/--disable-ogg configure.ac flags2022-04-13T21:39:13Zdrac[PATCH] --enable/--disable-ogg configure.ac flagsIf user has libogg installed, but he wants speex without ogg support there is no way to do that currently, so here we add --enable-ogg and --disable-ogg to control them (did a copycat from current
--enable-sse flag to keep it constant)
...If user has libogg installed, but he wants speex without ogg support there is no way to do that currently, so here we add --enable-ogg and --disable-ogg to control them (did a copycat from current
--enable-sse flag to keep it constant)
The patch also removes -O3 from CFLAGS when --enable-sse is called, I'm not sure what compiler optimizations has to do with SSE.
Kindly review and apply the parts accepted.Jean-Marc ValinJean-Marc Valin