Sophie

Sophie

distrib > CentOS > 5 > x86_64 > by-pkgid > ea32411352494358b8d75a78402a4713 > files > 4849

kernel-2.6.18-238.19.1.el5.centos.plus.src.rpm

From: Jerome Marchand <jmarchan@redhat.com>
Date: Fri, 15 Oct 2010 14:12:10 -0400
Subject: [sound] core: prevent heap corruption in snd_ctl_new
Message-id: <4CB8613A.802@redhat.com>
Patchwork-id: 28763
O-Subject: [PATCH RHEL5.6] CVE-2010-3442 kernel: prevent heap corruption in
	snd_ctl_new()
Bugzilla: 638484
CVE: CVE-2010-3442
RH-Acked-by: Jiri Olsa <jolsa@redhat.com>
RH-Acked-by: Bob Picco <bpicco@redhat.com>

Bugzilla:
https://bugzilla.redhat.com/show_bug.cgi?id=638484

This is a backport from:

commit 5591bf07225523600450edd9e6ad258bb877b779
Author: Dan Rosenberg <drosenberg@vsecurity.com>
Date:   Tue Sep 28 14:18:20 2010 -0400

    ALSA: prevent heap corruption in snd_ctl_new()

    The snd_ctl_new() function in sound/core/control.c allocates space for a
    snd_kcontrol struct by performing arithmetic operations on a
    user-provided size without checking for integer overflow.  If a user
    provides a large enough size, an overflow will occur, the allocated
    chunk will be too small, and a second user-influenced value will be
    written repeatedly past the bounds of this chunk.  This code is
    reachable by unprivileged users who have permission to open
    a /dev/snd/controlC* device (on many distros, this is group "audio") via
    the SNDRV_CTL_IOCTL_ELEM_ADD and SNDRV_CTL_IOCTL_ELEM_REPLACE ioctls.

Tested with the reproducer provided in bz.

Regards,
Jerome


diff --git a/sound/core/control.c b/sound/core/control.c
index 2448150..c066f5d 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -33,6 +33,7 @@
 
 /* max number of user-defined controls */
 #define MAX_USER_CONTROLS	32
+#define MAX_CONTROL_COUNT	1028
 
 struct snd_kctl_ioctl {
 	struct list_head list;		/* list of all ioctls */
@@ -190,6 +191,10 @@ static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control,
 	
 	snd_assert(control != NULL, return NULL);
 	snd_assert(control->count > 0, return NULL);
+
+	if (control->count > MAX_CONTROL_COUNT)
+		return NULL;
+
 	kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL);
 	if (kctl == NULL) {
 		snd_printk(KERN_ERR "Cannot allocate control instance\n");