pcm_hw_close: avoid SIGSEGV when pcm_hw_open fail

Prevent the call to pcm->ops-close() if pcm->ops->open() fail.
Fix memory leak in pcm_hw_open() in case of failure.

* thread #1, name = 'ut', stop reason = signal SIGSEGV: invalid address (fault address: 0x8)
    frame #0: 0x00007ffff7f863e8 libtinyalsa.so.1`pcm_hw_close(data=0x0000000000000000) at pcm_hw.c:61:21
   58  	{
   59  	    struct pcm_hw_data *hw_data = data;
   60
-> 61  	    if (hw_data->fd > 0)
   62  	        close(hw_data->fd);
   63
   64  	    free(hw_data);
(lldb) bt
* thread #1, name = 'ut', stop reason = signal SIGSEGV: invalid address (fault address: 0x8)
  * frame #0: 0x00007ffff7f863e8 libtinyalsa.so.1`pcm_hw_close(data=0x0000000000000000) at pcm_hw.c:61:21
    frame #1: 0x00007ffff7f8491c libtinyalsa.so.1`pcm_close(pcm=0x0000000000a9eba0) at pcm.c:820:5
    frame #2: 0x00007ffff7f84e0a libtinyalsa.so.1`pcm_open(card=128, device=0, flags=13, config=0x00007fffffffd000) at pcm.c:957:5

Signed-off-by: Miguel GAIO <mgaio35@gmail.com>
This commit is contained in:
Miguel GAIO
2020-04-18 08:40:41 +02:00
parent 1d10cd9b81
commit 0ab70fcc95
2 changed files with 6 additions and 3 deletions
+5 -3
View File
@@ -898,7 +898,7 @@ struct pcm *pcm_open(unsigned int card, unsigned int device,
if (!pcm->snd_node || pcm_type != SND_NODE_TYPE_PLUGIN) {
oops(pcm, -ENODEV, "no device (hw/plugin) for card(%u), device(%u)",
card, device);
goto fail_close;
goto fail_close_dev_node;
}
pcm->ops = &plug_ops;
pcm->fd = pcm->ops->open(card, device, flags, &pcm->data, pcm->snd_node);
@@ -907,7 +907,7 @@ struct pcm *pcm_open(unsigned int card, unsigned int device,
if (pcm->fd < 0) {
oops(pcm, errno, "cannot open device (%u) for card (%u)",
device, card);
goto fail_close;
goto fail_close_dev_node;
}
pcm->flags = flags;
@@ -950,11 +950,13 @@ fail:
if (flags & PCM_MMAP)
munmap(pcm->mmap_buffer, pcm_frames_to_bytes(pcm, pcm->buffer_size));
fail_close:
pcm->ops->close(pcm->data);
fail_close_dev_node:
#ifdef TINYALSA_USES_PLUGINS
if (pcm->snd_node)
snd_utils_close_dev_node(pcm->snd_node);
#endif
pcm_close(pcm);
free(pcm);
return &bad_pcm;
}
+1
View File
@@ -97,6 +97,7 @@ static int pcm_hw_open(unsigned int card, unsigned int device,
fd = open(fn, O_RDWR);
if (fd < 0) {
free(hw_data);
return fd;
}