CVE-2019-17113 (published 2019-10-04T00:15Z)

In libopenmpt before 0.3.19 and 0.4.x before 0.4.9, ModPlug_InstrumentName and ModPlug_SampleName in libopenmpt_modplug.c do not restrict the lengths of libmodplug output-buffer strings in the C API, leading to a buffer overflow.

Severity: HIGH
CVSS v2 base score: 7.5 (AV:N/AC:L/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-120
cwe_name: Buffer Copy without Checking Size of Input ('Classic Buffer Overflow')
description: The product copies an input buffer to an output buffer without verifying that the size of the input buffer is less than the size of the output buffer, leading to a buffer overflow.
extended_description: A buffer overflow condition exists when a product attempts to put more data in a buffer than it can hold, or when it attempts to put data in a memory area outside of the boundaries of a buffer. The simplest type of error, and the most common cause of buffer overflows, is the "classic" case in which the product copies the buffer without restricting how much is copied. Other variants exist, but the existence of a classic overflow strongly suggests that the programmer is not considering even the most basic of security protections.
         

Fix information:
repo_url: https://github.com/OpenMPT/openmpt
commit_details: repo_url: https://github.com/OpenMPT/openmpt
author: Jörn Heusipp
author_date: 2019-10-02 13:37:46+00:00
msg: [Fix] libmodplug: C API: Limit the length of strings copied to the output buffer of ModPlug_InstrumentName() and ModPlug_SampleName() to 32 bytes (including terminating null) as is done by original libmodplug. This avoids potential buffer overflows in software relying on this limit instead of querying the required buffer size beforehand. libopenmpt can return strings longer than 32 bytes here beacuse the internal limit of 32 bytes applies to strings encoded in arbitrary character encodings but the API returns them converted to UTF-8, which can be longer. (reported by Antonio Morales Maldonado of Semmle Security Research Team)

git-svn-id: https://source.openmpt.org/svn/openmpt/trunk/OpenMPT@12127 56274372-70c3-4bfc-bfc3-4c3a0b034d27
repository: repo_url: https://github.com/OpenMPT/openmpt
repo_name: OpenMPT/openmpt
description: Official read-only git mirror of the OpenMPT and libopenmpt subversion repository at https://source.openmpt.org/. This repository may occasionally get rebased without further notice when subversion revision properties (commit message) get fixed in recent history after the fact. Be sure to rebase often in case you clone or fork it.
repo_language: C++
owner: OpenMPT
file_changes: filename: libopenmpt_modplug.c
change_type: ModificationType.MODIFY
diff: @@ -478,53 +478,35 @@ LIBOPENMPT_MODPLUG_API unsigned int ModPlug_NumChannels(ModPlugFile* file)
 LIBOPENMPT_MODPLUG_API unsigned int ModPlug_SampleName(ModPlugFile* file, unsigned int qual, char* buff)
 {
 	const char* str;
-	unsigned int retval;
-	size_t tmpretval;
+	char buf[32];
 	if(!file) return 0;
 	str = openmpt_module_get_sample_name(file->mod,qual-1);
-	if(!str){
-		if(buff){
-			*buff = '\0';
-		}
-		return 0;
-	}
-	tmpretval = strlen(str);
-	if(tmpretval>=INT_MAX){
-		tmpretval = INT_MAX-1;
+	memset(buf,0,32);
+	if(str){
+		strncpy(buf,str,31);
+		openmpt_free_string(str);
 	}
-	retval = (int)tmpretval;
 	if(buff){
-		memcpy(buff,str,retval+1);
-		buff[retval] = '\0';
+		strncpy(buff,buf,32);
 	}
-	openmpt_free_string(str);
-	return retval;
+	return (unsigned int)strlen(buf);
 }
 
 LIBOPENMPT_MODPLUG_API unsigned int ModPlug_InstrumentName(ModPlugFile* file, unsigned int qual, char* buff)
 {
 	const char* str;
-	unsigned int retval;
-	size_t tmpretval;
+	char buf[32];
 	if(!file) return 0;
 	str = openmpt_module_get_instrument_name(file->mod,qual-1);
-	if(!str){
-		if(buff){
-			*buff = '\0';
-		}
-		return 0;
-	}
-	tmpretval = strlen(str);
-	if(tmpretval>=INT_MAX){
-		tmpretval = INT_MAX-1;
+	memset(buf,0,32);
+	if(str){
+		strncpy(buf,str,31);
+		openmpt_free_string(str);
 	}
-	retval = (int)tmpretval;
 	if(buff){
-		memcpy(buff,str,retval+1);
-		buff[retval] = '\0';
+		strncpy(buff,buf,32);
 	}
-	openmpt_free_string(str);
-	return retval;
+	return (unsigned int)strlen(buf);
 }
 
 LIBOPENMPT_MODPLUG_API ModPlugNote* ModPlug_GetPattern(ModPlugFile* file, int pattern, unsigned int* numrows)

programming_language: C