Vulnerability: Moddable commit before 135aa9a4a6a9b49b60aa730ebc3bcc6247d75c45 was discovered to contain an out-of-bounds read via the function fxUint8Getter at /moddable/xs/sources/xsDataView.c.
Vulnerability ID: CVE-2022-29368
CWE: CWE-125
Severity score: 4.9
Project: https://github.com/Moddable-OpenSource/moddable
Published: 2022-05-12
File: xs/sources/xsDataView.c
Commit message: XS: #896
Commit author: Patrick Soquet

Vulnerable version (before fix):
 void fx_DataView(txMachine* the) 		mxRangeError("out of range byteOffset %ld", offset); 	size = fxArgToByteLength(the, 2, -1); 	if (size >= 0) { 		if (info->value.bufferInfo.length < (offset + size)) 			mxRangeError("out of range byteLength %ld", size); 	} 	else { void fx_DataView(txMachine* the) 		if (info->value.bufferInfo.length < offset) 			mxRangeError("out of range byteOffset %ld", offset); 		else if (size >= 0) { 			if (info->value.bufferInfo.length < (offset + size)) 				mxRangeError("out of range byteLength %ld", size); 		} 	} void fx_TypedArray(txMachine* the) 			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); 			} 			else { 				if (info->value.bufferInfo.length & ((1 << shift) - 1))

Fixed version (after fix):
 void fx_DataView(txMachine* the) 		mxRangeError("out of range byteOffset %ld", offset); 	size = fxArgToByteLength(the, 2, -1); 	if (size >= 0) { 		txInteger end = offset + size; 		if ((info->value.bufferInfo.length < end) || (end < offset)) 			mxRangeError("out of range byteLength %ld", size); 	} 	else { void fx_DataView(txMachine* the) 		if (info->value.bufferInfo.length < offset) 			mxRangeError("out of range byteOffset %ld", offset); 		else if (size >= 0) { 			txInteger end = offset + size; 			if ((info->value.bufferInfo.length < end) || (end < offset)) 				mxRangeError("out of range byteLength %ld", size); 		} 	} void fx_TypedArray(txMachine* the) 			size = fxArgToByteLength(the, 2, -1); 			info = fxGetBufferInfo(the, mxArgv(0)); 			if (size >= 0) { 				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))

Patch:
patch: @@ -773,7 +773,8 @@ void fx_DataView(txMachine* the)
 		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 {
@@ -793,7 +794,8 @@ void fx_DataView(txMachine* the)
 		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);
 		}
 	}
@@ -1360,9 +1362,11 @@ void fx_TypedArray(txMachine* the)
 			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))
path: xs/sources/xsDataView.c