]> git.alsa-project.org Git - alsa-plugins.git/commitdiff
maemo: Fix a few crashing bugs
authorStian Skjelstad <stian.skjelstad@gmail.com>
Thu, 2 May 2019 21:26:15 +0000 (23:26 +0200)
committerTakashi Iwai <tiwai@suse.de>
Sun, 5 May 2019 07:43:31 +0000 (09:43 +0200)
maemo plugin has two crashes I was able to see in a valgrind log from
another user:

* maximum write size was calculated in words (16bit), but checked against
  byte-size length. This causes memcpy later to overflow the buffer
  (normally by up to 12KB).
* remove a double free (by marking free'd data with NULL)

* mmap returns MMAP_FAILED on error, not NULL

I suspect that this plugin/driver might have other issues aswell, since I
am unable to find any logic for checking DSP buffer status, and no
implementation for odelay reporting.

Signed-off-by: Stian Skjelstad <stian.skjelstad@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
maemo/alsa-dsp.c
maemo/dsp-ctl.c
maemo/dsp-protocol.c

index 7e04f6afb4b7f7aff6b3ac21d9b073255bcd2a2f..330738472056693cb8e06758660edf9628a1114c 100644 (file)
@@ -135,18 +135,18 @@ static snd_pcm_sframes_t alsa_dsp_transfer(snd_pcm_ioplug_t * io,
        snd_pcm_alsa_dsp_t *alsa_dsp = io->private_data;
        DENTER();
        char *buf;
-       int words;
+       int bytes, words;
        ssize_t result;
 
-       words = size * alsa_dsp->bytes_per_frame;
-       words /= 2;
-       DPRINT("***** Info: words %d size %lu bpf: %d\n", words, size,
-              alsa_dsp->bytes_per_frame);
-       if (words > alsa_dsp->dsp_protocol->mmap_buffer_size) {
-               DERROR("Requested too much data transfer (playing only %d)\n",
-                      alsa_dsp->dsp_protocol->mmap_buffer_size);
-               words = alsa_dsp->dsp_protocol->mmap_buffer_size;
+       bytes = size * alsa_dsp->bytes_per_frame;
+       DPRINT("***** Info: samples %lu * bpf %d => bytes %d\n",
+              size, alsa_dsp->bytes_per_frame, bytes);
+       if (bytes > alsa_dsp->dsp_protocol->mmap_buffer_size) {
+               DERROR("Requested too much data transfer (requested %d, playing only %d)\n",
+                      bytes, alsa_dsp->dsp_protocol->mmap_buffer_size);
+               bytes = alsa_dsp->dsp_protocol->mmap_buffer_size;
        }
+       words = bytes / 2;
        if (alsa_dsp->dsp_protocol->state != STATE_PLAYING) {
                DPRINT("I did nothing - No start sent\n");
                alsa_dsp_start(io);
index 5bcda3642debb9035acd451db34652db0dce52f1..ac05942722878e892394907ddd422d0e66acb6f9 100644 (file)
@@ -93,6 +93,7 @@ static void dsp_ctl_close(snd_ctl_ext_t * ext)
        snd_ctl_dsp_t *dsp_ctl = ext->private_data;
        DENTER();
        free(dsp_ctl->controls);
+       dsp_ctl->controls = NULL;
        free_control_list(&(dsp_ctl->playback_devices));
        free_control_list(&(dsp_ctl->recording_devices));
 //      free(dsp_ctl);
index af672518550fbae5ea772f0fd70a7e32edb5bc8b..32193d31473994e1eb690e326c24ccc52238ebf7 100644 (file)
@@ -194,7 +194,7 @@ int dsp_protocol_open_node(dsp_protocol_t * dsp_protocol, const char *device)
            mmap((void *)0, dsp_protocol->mmap_buffer_size,
                 PROT_READ | PROT_WRITE, MAP_SHARED, dsp_protocol->fd, 0);
 
-       if (dsp_protocol->mmap_buffer == NULL) {
+       if (dsp_protocol->mmap_buffer == MAP_FAILED) {
                report_dsp_protocol("Cannot mmap data buffer", dsp_protocol);
                ret = -ENOMEM;
                goto unlock;