From 6e162cb767e81cd15f4dc2a2fa253d2e36adfd70 Mon Sep 17 00:00:00 2001
From: Alex Stewart <alex.stewart@ni.com>
Date: Thu, 19 Oct 2023 14:07:19 -0400
Subject: [PATCH 13/17] nms_adpcm: fix int overflow in signal estimate

It is possible (though functionally incorrect) for the signal estimate
calculation in nms_adpcm_update() to overflow the int value of s_e,
resulting in undefined behavior.

Since adpcm state signal values are never practically larger than
16 bits, use smaller numeric sizes throughout the file to avoid the
overflow.

CVE: CVE-2022-33065
Fixes: https://github.com/libsndfile/libsndfile/issues/833

Authored-by: Arthur Taylor <art@ified.ca>
Signed-off-by: Alex Stewart <alex.stewart@ni.com>

Upstream-Status: Backport [import from ubuntu https://git.launchpad.net/ubuntu/+source/libsndfile/tree/debian/patches/CVE-2022-33065/CVE-2022-33065-9.patch?h=ubuntu/jammy-security
Upstream commit https://github.com/libsndfile/libsndfile/commit/6e162cb767e81cd15f4dc2a2fa253d2e36adfd70]
CVE: CVE-2022-33065
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
---
 src/nms_adpcm.c | 81 ++++++++++++++++++++++++-------------------------
 1 file changed, 40 insertions(+), 41 deletions(-)

--- libsndfile-1.2.0.orig/src/nms_adpcm.c
+++ libsndfile-1.2.0/src/nms_adpcm.c
@@ -48,36 +48,36 @@
 /* Variable names from ITU G.726 spec */
 struct nms_adpcm_state
 {	/* Log of the step size multiplier. Operated on by codewords. */
-	int yl ;
+	short yl ;
 
 	/* Quantizer step size multiplier. Generated from yl. */
-	int y ;
+	short y ;
 
 	/* Coefficents of the pole predictor */
-	int a [2] ;
+	short a [2] ;
 
 	/* Coefficents of the zero predictor  */
-	int b [6] ;
+	short b [6] ;
 
 	/* Previous quantized deltas (multiplied by 2^14) */
-	int d_q [7] ;
+	short d_q [7] ;
 
 	/* d_q [x] + s_ez [x], used by the pole-predictor for signs only. */
-	int p [3] ;
+	short p [3] ;
 
 	/* Previous reconstructed signal values. */
-	int s_r [2] ;
+	short s_r [2] ;
 
 	/* Zero predictor components of the signal estimate. */
-	int s_ez ;
+	short s_ez ;
 
 	/* Signal estimate, (including s_ez). */
-	int s_e ;
+	short s_e ;
 
 	/* The most recent codeword (enc:generated, dec:inputted) */
-	int Ik ;
+	char Ik ;
 
-	int parity ;
+	char parity ;
 
 	/*
 	** Offset into code tables for the bitrate.
@@ -109,7 +109,7 @@ typedef struct
 } NMS_ADPCM_PRIVATE ;
 
 /* Pre-computed exponential interval used in the antilog approximation. */
-static unsigned int table_expn [] =
+static unsigned short table_expn [] =
 {	0x4000, 0x4167, 0x42d5, 0x444c,	0x45cb, 0x4752, 0x48e2, 0x4a7a,
 	0x4c1b, 0x4dc7, 0x4f7a, 0x5138,	0x52ff, 0x54d1, 0x56ac, 0x5892,
 	0x5a82, 0x5c7e, 0x5e84, 0x6096,	0x62b4, 0x64dd, 0x6712, 0x6954,
@@ -117,21 +117,21 @@ static unsigned int table_expn [] =
 } ;
 
 /* Table mapping codewords to scale factor deltas. */
-static int table_scale_factor_step [] =
+static short table_scale_factor_step [] =
 {	0x0,	0x0,	0x0,	0x0,	0x4b0,	0x0,	0x0,	0x0,	/* 2-bit */
 	-0x3c,	0x0,	0x90,	0x0,	0x2ee,	0x0,	0x898,	0x0,	/* 3-bit */
 	-0x30,	0x12,	0x6b,	0xc8,	0x188,	0x2e0,	0x551,	0x1150,	/* 4-bit */
 } ;
 
 /* Table mapping codewords to quantized delta interval steps. */
-static unsigned int table_step [] =
+static unsigned short table_step [] =
 {	0x73F,	0,		0,		0,		0x1829,	0,		0,		0,		/* 2-bit */
 	0x3EB,	0,		0xC18,	0,		0x1581,	0,		0x226E,	0,		/* 3-bit */
 	0x20C,	0x635,	0xA83,	0xF12,	0x1418,	0x19E3,	0x211A,	0x2BBA,	/* 4-bit */
 } ;
 
 /* Binary search lookup table for quantizing using table_step. */
-static int table_step_search [] =
+static short table_step_search [] =
 {	0,		0x1F6D,	0,		-0x1F6D,	0,		0,			0,			0, /* 2-bit */
 	0x1008,	0x1192,	0,		-0x219A,	0x1656,	-0x1656,	0,			0, /* 3-bit */
 	0x872,	0x1277,	-0x8E6,	-0x232B,	0xD06,	-0x17D7,	-0x11D3,	0, /* 4-bit */
@@ -179,23 +179,23 @@ static sf_count_t nms_adpcm_seek (SF_PRI
 ** Maps [1,20480] to [1,1024] in an exponential relationship. This is
 ** approximately ret = b^exp where b = e^(ln(1024)/ln(20480)) ~= 1.0003385
 */
-static inline int
-nms_adpcm_antilog (int exp)
-{	int ret ;
-
-	ret = 0x1000 ;
-	ret += (((exp & 0x3f) * 0x166b) >> 12) ;
-	ret *= table_expn [(exp & 0x7c0) >> 6] ;
-	ret >>= (26 - (exp >> 11)) ;
+static inline short
+nms_adpcm_antilog (short exp)
+{	int_fast32_t r ;
+
+	r = 0x1000 ;
+	r += (((int_fast32_t) (exp & 0x3f) * 0x166b) >> 12) ;
+	r *= table_expn [(exp & 0x7c0) >> 6] ;
+	r >>= (26 - (exp >> 11)) ;
 
-	return ret ;
+	return (short) r ;
 } /* nms_adpcm_antilog */
 
 static void
 nms_adpcm_update (struct nms_adpcm_state *s)
 {	/* Variable names from ITU G.726 spec */
-	int a1ul ;
-	int fa1 ;
+	short a1ul, fa1 ;
+	int_fast32_t se ;
 	int i ;
 
 	/* Decay and Modify the scale factor in the log domain based on the codeword. */
@@ -222,7 +222,7 @@ nms_adpcm_update (struct nms_adpcm_state
 	else if (fa1 > 256)
 		fa1 = 256 ;
 
-	s->a [0] = (0xff * s->a [0]) >> 8 ;
+	s->a [0] = (s->a [0] * 0xff) >> 8 ;
 	if (s->p [0] != 0 && s->p [1] != 0 && ((s->p [0] ^ s->p [1]) < 0))
 		s->a [0] -= 192 ;
 	else
@@ -230,7 +230,7 @@ nms_adpcm_update (struct nms_adpcm_state
 		fa1 = -fa1 ;
 		}
 
-	s->a [1] = fa1 + ((0xfe * s->a [1]) >> 8) ;
+	s->a [1] = fa1 + ((s->a [1] * 0xfe) >> 8) ;
 	if (s->p [0] != 0 && s->p [2] != 0 && ((s->p [0] ^ s->p [2]) < 0))
 		s->a [1] -= 128 ;
 	else
@@ -250,19 +250,18 @@ nms_adpcm_update (struct nms_adpcm_state
 			s->a [0] = a1ul ;
 		} ;
 
-	/* Compute the zero predictor estimate. Rotate past deltas too. */
-	s->s_ez = 0 ;
+	/* Compute the zero predictor estimate and rotate past deltas. */
+	se = 0 ;
 	for (i = 5 ; i >= 0 ; i--)
-	{	s->s_ez += s->d_q [i] * s->b [i] ;
+	{	se += (int_fast32_t) s->d_q [i] * s->b [i] ;
 		s->d_q [i + 1] = s->d_q [i] ;
 		} ;
+	s->s_ez = se >> 14 ;
 
-	/* Compute the signal estimate. */
-	s->s_e = s->a [0] * s->s_r [0] + s->a [1] * s->s_r [1] + s->s_ez ;
-
-	/* Return to scale */
-	s->s_ez >>= 14 ;
-	s->s_e >>= 14 ;
+	/* Complete the signal estimate. */
+	se += (int_fast32_t) s->a [0] * s->s_r [0] ;
+	se += (int_fast32_t) s->a [1] * s->s_r [1] ;
+	s->s_e = se >> 14 ;
 
 	/* Rotate members to prepare for next iteration. */
 	s->s_r [1] = s->s_r [0] ;
@@ -274,7 +273,7 @@ nms_adpcm_update (struct nms_adpcm_state
 static int16_t
 nms_adpcm_reconstruct_sample (struct nms_adpcm_state *s, uint8_t I)
 {	/* Variable names from ITU G.726 spec */
-	int dqx ;
+	int_fast32_t dqx ;
 
 	/*
 	** The ordering of the 12-bit right-shift is a precision loss. It agrees
@@ -308,17 +307,17 @@ nms_adpcm_codec_init (struct nms_adpcm_s
 /*
 ** nms_adpcm_encode_sample()
 **
-** Encode a linear 16-bit pcm sample into a 2,3, or 4 bit NMS-ADPCM codeword
+** Encode a linear 16-bit pcm sample into a 2, 3, or 4 bit NMS-ADPCM codeword
 ** using and updating the predictor state.
 */
 static uint8_t
 nms_adpcm_encode_sample (struct nms_adpcm_state *s, int16_t sl)
 {	/* Variable names from ITU G.726 spec */
-	int d ;
+	int_fast32_t d ;
 	uint8_t I ;
 
 	/* Down scale the sample from 16 => ~14 bits. */
-	sl = (sl * 0x1fdf) / 0x7fff ;
+	sl = ((int_fast32_t) sl * 0x1fdf) / 0x7fff ;
 
 	/* Compute estimate, and delta from actual value */
 	nms_adpcm_update (s) ;
@@ -407,7 +406,7 @@ nms_adpcm_encode_sample (struct nms_adpc
 */
 static int16_t
 nms_adpcm_decode_sample (struct nms_adpcm_state *s, uint8_t I)
-{	int sl ;
+{	int_fast32_t sl ;
 
 	nms_adpcm_update (s) ;
 	sl = nms_adpcm_reconstruct_sample (s, I) ;
