Fix undefined behavior caused by invalid XM volume envelopes.

This commit is contained in:
AliceLR
2021-12-02 21:35:33 -07:00
parent 8209978cb3
commit 06a32248b0
5 changed files with 32 additions and 0 deletions

View File

@@ -156,6 +156,18 @@ static void check_envelope(struct xmp_envelope *env)
}
}
static void clamp_volume_envelope(struct module_data *m, struct xmp_envelope *env)
{
/* Clamp broken values in the volume envelope to the expected range. */
if (env->flg & XMP_ENVELOPE_ON) {
int i;
for (i = 0; i < env->npt; i++) {
int16 *data = &env->data[i * 2 + 1];
CLAMP(*data, 0, m->volbase);
}
}
}
void libxmp_load_prologue(struct context_data *ctx)
{
struct module_data *m = &ctx->m;
@@ -251,6 +263,7 @@ void libxmp_load_epilogue(struct context_data *ctx)
check_envelope(&mod->xxi[i].aei);
check_envelope(&mod->xxi[i].fei);
check_envelope(&mod->xxi[i].pei);
clamp_volume_envelope(m, &mod->xxi[i].aei);
}
p->filter = 0;

View File

@@ -516,6 +516,7 @@ FUZZER = misc \
play_mod_bad_invloop \
play_xm_bad_env_sustain \
play_xm_bad_instrument \
play_xm_vol_env_clamp \
play_it_bad_env_sustain \
play_it_bad_set_nna \
play_it_row_0_loop_row_delay \

View File

@@ -724,6 +724,7 @@ test_fuzzer_depack_zip_truncated
test_fuzzer_play_mod_bad_invloop
test_fuzzer_play_xm_bad_env_sustain
test_fuzzer_play_xm_bad_instrument
test_fuzzer_play_xm_vol_env_clamp
test_fuzzer_play_it_bad_env_sustain
test_fuzzer_play_it_bad_set_nna
test_fuzzer_play_it_row_0_loop_row_delay

Binary file not shown.

View File

@@ -0,0 +1,17 @@
#include "test.h"
/* This XM has a volume envelope with extreme values -32768 and 32767.
* These should be clamped to the range [0,64]. Not doing this causes
* weird and undefined behavior (e.g. integer overflows found by UBSan).
*/
TEST(test_fuzzer_play_xm_vol_env_clamp)
{
static const struct playback_sequence sequence[] =
{
{ PLAY_FRAMES, 8, 0 },
{ PLAY_END, 0, 0 }
};
compare_playback("data/f/play_xm_vol_env_clamp.xm", sequence, 4000, 0, 0);
}
END_TEST