From d30d662307d0930b5a8f62329bd58dec08d22c80 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sun, 18 Feb 2024 16:14:06 +0100 Subject: [PATCH] Avoid large buffer on stack, to prevent stack overflows This affectes: * demodulation in libfsk * audio processing in libmobile --- src/libfsk/fsk.c | 16 ++++++++++++---- src/libmobile/main_mobile.c | 17 ++++++++++++++++- src/libmobile/sender.c | 8 +------- src/libmobile/sender.h | 2 +- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/libfsk/fsk.c b/src/libfsk/fsk.c index 2d8879e..475ea88 100644 --- a/src/libfsk/fsk.c +++ b/src/libfsk/fsk.c @@ -361,6 +361,8 @@ void fsk_demod_cleanup(fsk_demod_t *fsk) //#define DEBUG_MODULATOR //#define DEBUG_FILTER +#define CHUNK 1024 + /* Demodulates bits * * If bit is received, callback function send_bit() is called. @@ -375,15 +377,21 @@ void fsk_demod_cleanup(fsk_demod_t *fsk) */ void fsk_demod_receive(fsk_demod_t *fsk, sample_t *sample, int length) { - sample_t I[length], Q[length], frequency[length], f; + sample_t I[CHUNK], Q[CHUNK], frequency[CHUNK], f; int i; int bit; double level, quality; - /* demod samples to offset around center frequency */ - fm_demodulate_real(&fsk->demod, frequency, length, sample, I, Q); - for (i = 0; i < length; i++) { + /* this is called on first sample and subsequently every sample defined by CHUNK */ + if (i % CHUNK == 0) { + length -= i; + i = 0; + /* demod CHUNK samples to offset around center frequency */ + fm_demodulate_real(&fsk->demod, frequency, (length > CHUNK) ? CHUNK : length, sample, I, Q); + sample += CHUNK; + } + f = frequency[i]; if (f < 0) bit = fsk->low_bit; diff --git a/src/libmobile/main_mobile.c b/src/libmobile/main_mobile.c index 0b6a6b0..9047c59 100644 --- a/src/libmobile/main_mobile.c +++ b/src/libmobile/main_mobile.c @@ -617,6 +617,7 @@ void main_mobile_loop(const char *name, int *quit, void (*myhandler)(void), cons sender_t *sender; double last_time_call = 0, begin_time, now, sleep; struct termios term, term_orig; + int num_chan, i; int c; int rc; @@ -693,6 +694,15 @@ void main_mobile_loop(const char *name, int *quit, void (*myhandler)(void), cons if (console_open_audio(buffer_size, dsp_interval)) return; + /* alloc memory for audio processing */ + for (num_chan = 0, sender = sender_head; sender; num_chan++, sender = sender->next); + sample_t *samples[num_chan]; + uint8_t *powers[num_chan]; + for (i = 0; i < num_chan; i++) { + samples[i] = calloc(buffer_size, sizeof(**samples)); + powers[i] = calloc(buffer_size, sizeof(**powers)); + } + /* real time priority */ if (rt_prio > 0) { struct sched_param schedp; @@ -739,7 +749,7 @@ void main_mobile_loop(const char *name, int *quit, void (*myhandler)(void), cons /* do not process audio for an audio slave, since it is done by audio master */ if (sender->master) /* if master is set, we are an audio slave */ continue; - process_sender_audio(sender, quit, buffer_size); + process_sender_audio(sender, quit, samples, powers, buffer_size); } /* process audio for call instances */ @@ -855,6 +865,11 @@ next_char: signal(SIGTERM, SIG_DFL); signal(SIGPIPE, SIG_DFL); + for (i = 0; i < num_chan; i++) { + free(samples[i]); + free(powers[i]); + } + /* reset terminal */ tcsetattr(0, TCSANOW, &term_orig); diff --git a/src/libmobile/sender.c b/src/libmobile/sender.c index 5ef31c0..9ae9b5b 100644 --- a/src/libmobile/sender.c +++ b/src/libmobile/sender.c @@ -331,7 +331,7 @@ static void gain_samples(sample_t *samples, int length, double gain) } /* Handle audio streaming of one transceiver. */ -void process_sender_audio(sender_t *sender, int *quit, int buffer_size) +void process_sender_audio(sender_t *sender, int *quit, sample_t **samples, uint8_t **power, int buffer_size) { sender_t *inst; int rc, count; @@ -342,15 +342,9 @@ void process_sender_audio(sender_t *sender, int *quit, int buffer_size) /* count instances for audio channel */ for (num_chan = 0, inst = sender; inst; num_chan++, inst = inst->slave); - sample_t buff[num_chan][buffer_size], *samples[num_chan]; - uint8_t pbuff[num_chan][buffer_size], *power[num_chan]; enum paging_signal paging_signal[num_chan]; int on[num_chan]; double rf_level_db[num_chan]; - for (i = 0; i < num_chan; i++) { - samples[i] = buff[i]; - power[i] = pbuff[i]; - } #ifdef DEBUG_TIME_CONSUMPTION t1 = get_time(); diff --git a/src/libmobile/sender.h b/src/libmobile/sender.h index 944ae75..ab1b687 100644 --- a/src/libmobile/sender.h +++ b/src/libmobile/sender.h @@ -100,7 +100,7 @@ void sender_set_fm(sender_t *sender, double max_deviation, double max_modulation void sender_set_am(sender_t *sender, double max_modulation, double speech_deviation, double max_display, double modulation_index); int sender_open_audio(int buffer_size, double interval); int sender_start_audio(void); -void process_sender_audio(sender_t *sender, int *quit, int buffer_size); +void process_sender_audio(sender_t *sender, int *quit, sample_t **samples, uint8_t **power, int buffer_size); void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int count); void sender_receive(sender_t *sender, sample_t *samples, int count, double rf_level_db); void sender_paging(sender_t *sender, int on);