diff options
author | Jesper Juhl <jj@chaosbits.net> | 2010-10-29 15:35:25 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-11-02 02:38:21 -0400 |
commit | fd0977d0f42d3e73121b88f57c7d48ca9b861a58 (patch) | |
tree | 6a851561a7a67d660f5ce5260f6e6429fed0eccc /sound/pci | |
parent | f7467452291f7c9e5e1271e8c8e45b77f34b1257 (diff) |
ALSA: asihpi - Unsafe memory management when allocating control cache
I noticed that sound/pci/asihpi/hpicmn.c::hpi_alloc_control_cache() does
not check the return value from kmalloc(), which may fail.
If kmalloc() fails we'll dereference a null pointer and things will go bad
fast.
There are two memory allocations in that function and there's also the
problem that the first may succeed and the second may fail and nothing is
done about that either which will also go wrong down the line.
Signed-off-by: Jesper Juhl <jj@chaosbits.net>
Acked-by: Eliot Blennerhassett <linux@audioscience.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/asihpi/hpi6000.c | 2 | ||||
-rw-r--r-- | sound/pci/asihpi/hpi6205.c | 2 | ||||
-rw-r--r-- | sound/pci/asihpi/hpicmn.c | 12 |
3 files changed, 13 insertions, 3 deletions
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c index f7e374ec4414..1b9bf9395cfe 100644 --- a/sound/pci/asihpi/hpi6000.c +++ b/sound/pci/asihpi/hpi6000.c | |||
@@ -625,6 +625,8 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao, | |||
625 | control_cache_size, (struct hpi_control_cache_info *) | 625 | control_cache_size, (struct hpi_control_cache_info *) |
626 | &phw->control_cache[0] | 626 | &phw->control_cache[0] |
627 | ); | 627 | ); |
628 | if (!phw->p_cache) | ||
629 | pao->has_control_cache = 0; | ||
628 | } else | 630 | } else |
629 | pao->has_control_cache = 0; | 631 | pao->has_control_cache = 0; |
630 | 632 | ||
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index 22c5fc625533..2672f6591ceb 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c | |||
@@ -644,6 +644,8 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, | |||
644 | interface->control_cache.size_in_bytes, | 644 | interface->control_cache.size_in_bytes, |
645 | (struct hpi_control_cache_info *) | 645 | (struct hpi_control_cache_info *) |
646 | p_control_cache_virtual); | 646 | p_control_cache_virtual); |
647 | if (!phw->p_cache) | ||
648 | err = HPI_ERROR_MEMORY_ALLOC; | ||
647 | } | 649 | } |
648 | if (!err) { | 650 | if (!err) { |
649 | err = hpios_locked_mem_get_phys_addr(&phw-> | 651 | err = hpios_locked_mem_get_phys_addr(&phw-> |
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c index dda4f1c6f658..d67f4d3db911 100644 --- a/sound/pci/asihpi/hpicmn.c +++ b/sound/pci/asihpi/hpicmn.c | |||
@@ -571,14 +571,20 @@ struct hpi_control_cache *hpi_alloc_control_cache(const u32 | |||
571 | { | 571 | { |
572 | struct hpi_control_cache *p_cache = | 572 | struct hpi_control_cache *p_cache = |
573 | kmalloc(sizeof(*p_cache), GFP_KERNEL); | 573 | kmalloc(sizeof(*p_cache), GFP_KERNEL); |
574 | if (!p_cache) | ||
575 | return NULL; | ||
576 | p_cache->p_info = | ||
577 | kmalloc(sizeof(*p_cache->p_info) * number_of_controls, | ||
578 | GFP_KERNEL); | ||
579 | if (!p_cache->p_info) { | ||
580 | kfree(p_cache); | ||
581 | return NULL; | ||
582 | } | ||
574 | p_cache->cache_size_in_bytes = size_in_bytes; | 583 | p_cache->cache_size_in_bytes = size_in_bytes; |
575 | p_cache->control_count = number_of_controls; | 584 | p_cache->control_count = number_of_controls; |
576 | p_cache->p_cache = | 585 | p_cache->p_cache = |
577 | (struct hpi_control_cache_single *)pDSP_control_buffer; | 586 | (struct hpi_control_cache_single *)pDSP_control_buffer; |
578 | p_cache->init = 0; | 587 | p_cache->init = 0; |
579 | p_cache->p_info = | ||
580 | kmalloc(sizeof(*p_cache->p_info) * p_cache->control_count, | ||
581 | GFP_KERNEL); | ||
582 | return p_cache; | 588 | return p_cache; |
583 | } | 589 | } |
584 | 590 | ||