CVE-2022-29368: Out-of-bounds Read (CWE-125)
value: Moddable commit before 135aa9a4a6a9b49b60aa730ebc3bcc6247d75c45 was discovered to contain an out-of-bounds read via the function fxUint8Getter at /moddable/xs/sources/xsDataView.c.
CWE description: The product reads data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 7.1
Published: 2022-05-12T19:15Z
Repository: https://github.com/Moddable-OpenSource/moddable
Language: C
Files changed: xs/sources/xsDataView.c
Commit date: 2022-04-12 13:38:55 +0200
Commit message: XS: #896

Diff: diff --git a/xs/sources/xsDataView.c b/xs/sources/xsDataView.c
index 824c1c5c..7b1666f4 100644
--- a/xs/sources/xsDataView.c
+++ b/xs/sources/xsDataView.c
@@ -771,11 +771,12 @@ void fx_DataView(txMachine* the)
 	info = fxGetBufferInfo(the, mxArgv(0));
 	if (info->value.bufferInfo.length < offset)
 		mxRangeError("out of range byteOffset %ld", offset);
 	size = fxArgToByteLength(the, 2, -1);
 	if (size >= 0) {
-		if (info->value.bufferInfo.length < (offset + size))
+		txInteger end = offset + size;
+		if ((info->value.bufferInfo.length < end) || (end < offset))
 			mxRangeError("out of range byteLength %ld", size);
 	}
 	else {
 		if (info->value.bufferInfo.maxLength < 0)
 			size = info->value.bufferInfo.length - offset;
@@ -791,11 +792,12 @@ void fx_DataView(txMachine* the)
 	info = fxGetBufferInfo(the, buffer);
 	if (info->value.bufferInfo.maxLength >= 0) {
 		if (info->value.bufferInfo.length < offset)
 			mxRangeError("out of range byteOffset %ld", offset);
 		else if (size >= 0) {
-			if (info->value.bufferInfo.length < (offset + size))
+			txInteger end = offset + size;
+			if ((info->value.bufferInfo.length < end) || (end < offset))
 				mxRangeError("out of range byteLength %ld", size);
 		}
 	}
 	view->value.dataView.offset = offset;
 	view->value.dataView.size = size;
@@ -1358,13 +1360,15 @@ void fx_TypedArray(txMachine* the)
 			if (offset & ((1 << shift) - 1))
 				mxRangeError("invalid byteOffset %ld", offset);
 			size = fxArgToByteLength(the, 2, -1);
 			info = fxGetBufferInfo(the, mxArgv(0));
 			if (size >= 0) {
-				size <<= shift;
-				if (info->value.bufferInfo.length < (offset + size))
-					mxRangeError("out of range byteLength %ld", size);
+				txInteger delta = size << shift;
+				txInteger end = offset + delta;
+				if ((info->value.bufferInfo.length < end) || (end < offset))
+					mxRangeError("out of range length %ld", size);
+				size = delta;
 			}
 			else {
 				if (info->value.bufferInfo.length & ((1 << shift) - 1))
 					mxRangeError("invalid byteLength %ld", info->value.bufferInfo.length);
 				size = info->value.bufferInfo.length - offset;

Vulnerable code: 		if (info->value.bufferInfo.length < (offset + size))
			if (info->value.bufferInfo.length < (offset + size))
				size <<= shift;
				if (info->value.bufferInfo.length < (offset + size))
					mxRangeError("out of range byteLength %ld", size);
Fixed code: 		txInteger end = offset + size;
		if ((info->value.bufferInfo.length < end) || (end < offset))
			txInteger end = offset + size;
			if ((info->value.bufferInfo.length < end) || (end < offset))
				txInteger delta = size << shift;
				txInteger end = offset + delta;
				if ((info->value.bufferInfo.length < end) || (end < offset))
					mxRangeError("out of range length %ld", size);
				size = delta;