Skip to content

Commit 927688d

Browse files
committed
[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
1 parent 47a3b06 commit 927688d

File tree

1 file changed

+14
-32
lines changed

1 file changed

+14
-32
lines changed

Diff for: libopenmpt/libopenmpt_modplug.c

+14-32
Original file line numberDiff line numberDiff line change
@@ -478,53 +478,35 @@ LIBOPENMPT_MODPLUG_API unsigned int ModPlug_NumChannels(ModPlugFile* file)
478478
LIBOPENMPT_MODPLUG_API unsigned int ModPlug_SampleName(ModPlugFile* file, unsigned int qual, char* buff)
479479
{
480480
const char* str;
481-
unsigned int retval;
482-
size_t tmpretval;
481+
char buf[32];
483482
if(!file) return 0;
484483
str = openmpt_module_get_sample_name(file->mod,qual-1);
485-
if(!str){
486-
if(buff){
487-
*buff = '\0';
488-
}
489-
return 0;
490-
}
491-
tmpretval = strlen(str);
492-
if(tmpretval>=INT_MAX){
493-
tmpretval = INT_MAX-1;
484+
memset(buf,0,32);
485+
if(str){
486+
strncpy(buf,str,31);
487+
openmpt_free_string(str);
494488
}
495-
retval = (int)tmpretval;
496489
if(buff){
497-
memcpy(buff,str,retval+1);
498-
buff[retval] = '\0';
490+
strncpy(buff,buf,32);
499491
}
500-
openmpt_free_string(str);
501-
return retval;
492+
return (unsigned int)strlen(buf);
502493
}
503494

504495
LIBOPENMPT_MODPLUG_API unsigned int ModPlug_InstrumentName(ModPlugFile* file, unsigned int qual, char* buff)
505496
{
506497
const char* str;
507-
unsigned int retval;
508-
size_t tmpretval;
498+
char buf[32];
509499
if(!file) return 0;
510500
str = openmpt_module_get_instrument_name(file->mod,qual-1);
511-
if(!str){
512-
if(buff){
513-
*buff = '\0';
514-
}
515-
return 0;
516-
}
517-
tmpretval = strlen(str);
518-
if(tmpretval>=INT_MAX){
519-
tmpretval = INT_MAX-1;
501+
memset(buf,0,32);
502+
if(str){
503+
strncpy(buf,str,31);
504+
openmpt_free_string(str);
520505
}
521-
retval = (int)tmpretval;
522506
if(buff){
523-
memcpy(buff,str,retval+1);
524-
buff[retval] = '\0';
507+
strncpy(buff,buf,32);
525508
}
526-
openmpt_free_string(str);
527-
return retval;
509+
return (unsigned int)strlen(buf);
528510
}
529511

530512
LIBOPENMPT_MODPLUG_API ModPlugNote* ModPlug_GetPattern(ModPlugFile* file, int pattern, unsigned int* numrows)

0 commit comments

Comments
 (0)