Check for NULL pointers before deferencing delay and state variable pointers in audio_alsa.c's delay and delay_and_status functions.

This commit is contained in:
Mike Brady
2022-03-04 10:02:40 +11:00
parent 0e7312de73
commit 9bac04e2d7
+30 -14
View File
@@ -1430,27 +1430,38 @@ static void start(__attribute__((unused)) int i_sample_rate,
int standard_delay_and_status(snd_pcm_state_t *state, snd_pcm_sframes_t *delay,
yndk_type *using_update_timestamps) {
int ret = 0;
snd_pcm_state_t state_temp;
snd_pcm_sframes_t delay_temp;
if (using_update_timestamps)
*using_update_timestamps = YNDK_NO;
*state = snd_pcm_state(alsa_handle);
if ((*state == SND_PCM_STATE_RUNNING) || (*state == SND_PCM_STATE_DRAINING)) {
ret = snd_pcm_delay(alsa_handle, delay);
state_temp = snd_pcm_state(alsa_handle);
if ((state_temp == SND_PCM_STATE_RUNNING) || (state_temp == SND_PCM_STATE_DRAINING)) {
ret = snd_pcm_delay(alsa_handle, &delay_temp);
} else {
// not running, thus no delay information, thus can't check for frame
// rates
// frame_index = 0; // we'll be starting over...
// measurement_data_is_valid = 0;
*delay = 0;
delay_temp = 0;
}
stall_monitor_start_time = 0; // zero if not initialised / not started / zeroed by flush
stall_monitor_frame_count = 0; // set to delay at start of time, incremented by any writes
if (delay != NULL)
*delay = delay_temp;
if (state != NULL)
*state = state_temp;
return ret;
}
int precision_delay_and_status(snd_pcm_state_t *state, snd_pcm_sframes_t *delay,
yndk_type *using_update_timestamps) {
snd_pcm_state_t state_temp = SND_PCM_STATE_DISCONNECTED; // just to stop a compiler warning
snd_pcm_sframes_t delay_temp;
snd_pcm_status_t *alsa_snd_pcm_status;
snd_pcm_status_alloca(&alsa_snd_pcm_status);
@@ -1477,9 +1488,9 @@ int precision_delay_and_status(snd_pcm_state_t *state, snd_pcm_sframes_t *delay,
#endif
*/
*state = snd_pcm_status_get_state(alsa_snd_pcm_status);
state_temp = snd_pcm_status_get_state(alsa_snd_pcm_status);
if ((*state == SND_PCM_STATE_RUNNING) || (*state == SND_PCM_STATE_DRAINING)) {
if ((state_temp == SND_PCM_STATE_RUNNING) || (state_temp == SND_PCM_STATE_DRAINING)) {
// uint64_t update_timestamp_ns =
// update_timestamp.tv_sec * (uint64_t)1000000000 + update_timestamp.tv_nsec;
@@ -1514,9 +1525,9 @@ int precision_delay_and_status(snd_pcm_state_t *state, snd_pcm_sframes_t *delay,
}
if (update_timestamp_ns == 0) {
ret = snd_pcm_delay(alsa_handle, delay);
ret = snd_pcm_delay(alsa_handle, &delay_temp);
} else {
snd_pcm_sframes_t delay_temp = snd_pcm_status_get_delay(alsa_snd_pcm_status);
delay_temp = snd_pcm_status_get_delay(alsa_snd_pcm_status);
/*
// It seems that the alsa library uses CLOCK_REALTIME before 1.0.28, even though
@@ -1585,11 +1596,10 @@ int precision_delay_and_status(snd_pcm_state_t *state, snd_pcm_sframes_t *delay,
frames_played_since_last_interrupt, frames_played_since_last_interrupt_sized);
delay_temp = delay_temp - frames_played_since_last_interrupt_sized;
}
*delay = delay_temp;
}
} else { // not running, thus no delay information, thus can't check for
// stall
*delay = 0;
delay_temp = 0;
stall_monitor_start_time = 0; // zero if not initialised / not started / zeroed by flush
stall_monitor_frame_count = 0; // set to delay at start of time, incremented by any writes
@@ -1601,6 +1611,12 @@ int precision_delay_and_status(snd_pcm_state_t *state, snd_pcm_sframes_t *delay,
} else {
debug(1, "alsa: can't get device's status.");
}
if (delay != NULL)
*delay = delay_temp;
if (state != NULL)
*state = state_temp;
return ret;
}
@@ -1615,12 +1631,11 @@ int delay(long *the_delay) {
// the sps_extra_code_output_stalled or the
// sps_extra_code_output_state_cannot_make_ready codes
int ret = 0;
*the_delay = 0;
snd_pcm_sframes_t my_delay = 0;
int oldState;
snd_pcm_state_t state;
snd_pcm_sframes_t my_delay = 0; // this initialisation is to silence a clang warning
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); // make this un-cancellable
pthread_cleanup_debug_mutex_lock(&alsa_mutex, 10000, 0);
@@ -1634,7 +1649,8 @@ int delay(long *the_delay) {
pthread_cleanup_pop(0);
pthread_setcancelstate(oldState, NULL);
*the_delay = my_delay; // note: snd_pcm_sframes_t is a long
if (the_delay != NULL) // can't imagine why this might happen
*the_delay = my_delay; // note: snd_pcm_sframes_t is a long
return ret;
}
@@ -1840,7 +1856,7 @@ int sub_flush() {
"disconnected");
int derr = 0;
if (alsa_handle) {
debug(2,"alsa: do_flush() -- flushing the output device");
debug(2, "alsa: do_flush() -- flushing the output device");
frames_sent_break_occurred = 1;
if ((derr = snd_pcm_drop(alsa_handle)))
debug(1, "Error %d (\"%s\") dropping output device.", derr, snd_strerror(derr));