myriadrf / LimeSuite

Driver and GUI for LMS7002M-based SDR platforms
https://myriadrf.org/projects/lime-suite/
Apache License 2.0
470 stars 186 forks source link

Undefined behavior when calling vsnprintf() leads to empty error messages #134

Closed kumbayo closed 6 years ago

kumbayo commented 7 years ago

LMS64CProtocol.cpp convertStatus executes the following code.

static int convertStatus(const int &status, const LMS64CProtocol::GenericPacket &pkt)
{
    if (status != 0) return ReportError(EIO, GetLastErrorMessage());

This causes a call to vsnprintf with the target string and the format string being the same buffer.

const char *lime::GetLastErrorMessage(void)
{
    return _reportedErrorMessage;
}
int lime::ReportError(const int errnum, const char *format, va_list argList)
{
    _reportedErrorCode = errnum;
    vsnprintf(_reportedErrorMessage, MAX_MSG_LEN, format, argList);
    return errnum;
}

According to "man vsnprintf" this is undefined behavior. C99 and POSIX.1-2001 specify that the results are undefined if a call to sprintf(), snprintf(), vsprintf(), or vsnprintf() would cause copying to take place between objects that overlap (e.g., if the target string array and one of the supplied input arguments refer to the same buffer). See NOTES.

On Ubuntu 17.04 this can cause empty error messages when loading an ini file fails due to some error limesdr_error_failed_to_load_file

Some other code executes

ReportError(-1, "RegistersTest() failed - %s", GetLastErrorMessage());

which might also cause problems.

IgnasJarusevicius commented 6 years ago

This seems to be fixed in current LimeSuite