File 0013-tlv-improve-robustness-of-raw-value-ranges.patch of Package alsa

From 70b958f460a253f2cbdfd9773d54d489d3dcc4ba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?=
 <benoit.thebaudeau@advansee.com>
Date: Wed, 23 May 2012 01:53:01 +0200
Subject: [PATCH 13/14] tlv: improve robustness of raw value ranges
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

snd_tlv_convert_from_dB() relies on rangemin/max blindly.
Since this function is exported, it is better for robustness and
consistency to parse the range properly, which this patch does.

Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/control/tlv.c |   36 ++++++++++++++++--------------------
 1 file changed, 16 insertions(+), 20 deletions(-)

diff --git a/src/control/tlv.c b/src/control/tlv.c
index f7c9976..6b0b9f4 100644
--- a/src/control/tlv.c
+++ b/src/control/tlv.c
@@ -291,41 +291,37 @@ int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax,
 {
 	switch (tlv[0]) {
 	case SND_CTL_TLVT_DB_RANGE: {
-		long dbmin, dbmax, prev_rangemax;
+		long dbmin, dbmax, prev_submax;
 		unsigned int pos, len;
 		len = int_index(tlv[1]);
-		if (len > MAX_TLV_RANGE_SIZE)
-			return -EINVAL;
-		if (snd_tlv_get_dB_range(tlv, rangemin, rangemax,
-					 &dbmin, &dbmax))
+		if (len < 6 || len > MAX_TLV_RANGE_SIZE)
 			return -EINVAL;
-		if (db_gain <= dbmin) {
-			*value = rangemin;
-			return 0;
-		} else if (db_gain >= dbmax) {
-			*value = rangemax;
-			return 0;
-		}
 		pos = 2;
-		prev_rangemax = 0;
+		prev_submax = 0;
 		while (pos + 4 <= len) {
-			rangemin = (int)tlv[pos];
-			rangemax = (int)tlv[pos + 1];
+			long submin, submax;
+			submin = (int)tlv[pos];
+			submax = (int)tlv[pos + 1];
+			if (rangemax < submax)
+				submax = rangemax;
 			if (!snd_tlv_get_dB_range(tlv + pos + 2,
-						  rangemin, rangemax,
+						  submin, submax,
 						  &dbmin, &dbmax) &&
 			    db_gain >= dbmin && db_gain <= dbmax)
 				return snd_tlv_convert_from_dB(tlv + pos + 2,
-							       rangemin, rangemax,
+							       submin, submax,
 							       db_gain, value, xdir);
 			else if (db_gain < dbmin) {
-				*value = xdir ? rangemin : prev_rangemax;
+				*value = xdir || pos == 2 ? submin : prev_submax;
 				return 0;
 			}
-			prev_rangemax = rangemax;
+			prev_submax = submax;
+			if (rangemax == submax)
+				break;
 			pos += int_index(tlv[pos + 3]) + 4;
 		}
-		return -EINVAL;
+		*value = prev_submax;
+		return 0;
 	}
 	case SND_CTL_TLVT_DB_SCALE: {
 		int min, step, max;
-- 
1.7.9.2

openSUSE Build Service is sponsored by