diff options
author | Miguel GAIO <mgaio35@gmail.com> | 2020-04-18 08:40:41 +0200 |
---|---|---|
committer | Miguel GAIO <mgaio35@gmail.com> | 2020-04-18 09:15:16 +0200 |
commit | 859adb2d2f4cd38d264d018404da5b8d09fd854a (patch) | |
tree | 9433f9639378e460c829f86aa737388e4ca633f8 /src | |
parent | 2feb925cedc25a761d35e32edc37a54a11ebad1d (diff) |
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/pcm.c | 8 | ||||
-rw-r--r-- | src/pcm_hw.c | 1 |
2 files changed, 6 insertions, 3 deletions
@@ -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; } diff --git a/src/pcm_hw.c b/src/pcm_hw.c index 1e67e9b..e25cdae 100644 --- a/src/pcm_hw.c +++ b/src/pcm_hw.c @@ -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; } |