Code Monkey home page Code Monkey logo

Comments (3)

mqudsi avatar mqudsi commented on August 30, 2024
if (!mpBuf && mnBufferLen > 0)

may be rewritten as

if (mpBuf == null && mnBufferLen > 0)

Per De Morgan's law, that means the only way line 78 can be reached (the negation of a conjunction) is the following (the disjunction of the negation):

assert(mpBuf != null || mnBufferLen <= 0)
std::memcpy(...);

It is safe (even if ill-advised) to pass an invalid pointer to std::memcpy(...) as the destination if the length is zero, the only catch is that as you can see, mpBuf may be null if mnBufferLen is less than or equal to 0. mnBufferLen is signed so it's theoretically possible that it contains a negative value, but std::memcpy takes an unsigned size_t length parameter, which would result in a negative value being interpreted as a very large one, which would in fact result in an invalid memcpy call.

The only question that remains is if mnBufferLen could possibly be negative in the first place. It's a private variable that's only modified in a few places, but it does sometimes obtain values derived from developer-provided arguments, such as here:

CppSQLite/CppSQLite3.cpp

Lines 311 to 333 in b53922e

unsigned char* CppSQLite3Binary::allocBuffer(int nLen)
{
clear();
// Allow extra space for encoded binary as per comments in
// SQLite encode.c See bottom of this file for implementation
// of SQLite functions use 3 instead of 2 just to be sure ;-)
mnBinaryLen = nLen;
mnBufferLen = 3 + (257*nLen)/254;
mpBuf = (unsigned char*)malloc(mnBufferLen);
if (!mpBuf)
{
throw CppSQLite3Exception(CPPSQLITE_ERROR,
ALLOCATION_ERROR_MESSAGE,
DONT_DELETE_MSG);
}
mbEncoded = false;
return mpBuf;
}

or if you pass in a string longer than 2GiB but less than 4GiB, strlen will return a positive unsigned number that will be coerced to a negative signed int assigned to mnBufferLen below, which may if allocation succeeds bypass the subsequent null check:

CppSQLite/CppSQLite3.cpp

Lines 247 to 265 in b53922e

void CppSQLite3Binary::setEncoded(const unsigned char* pBuf)
{
clear();
mnEncodedLen = strlen((const char*)pBuf);
mnBufferLen = mnEncodedLen + 1; // Allow for NULL terminator
mpBuf = (unsigned char*)malloc(mnBufferLen);
if (!mpBuf)
{
throw CppSQLite3Exception(CPPSQLITE_ERROR,
ALLOCATION_ERROR_MESSAGE,
DONT_DELETE_MSG);
}
memcpy(mpBuf, pBuf, mnBufferLen);
mbEncoded = true;
}

So the code is absolutely not safe and may in fact crash, but realistically, if it's doing so that means that you probably have a bug somewhere else in your code that is triggering the crash. The entire codebase is like that, it's very early 2000s in its design and lack of respect for signed types and it would take a full rewrite to address them all. But in terms of whether using the library the right way could still result in unsafe memory access, the answer should still be no.

If you're passing in user-provided input directly to the function, then you need to be doing sanity checking to make sure that only strings shorter than 2GiB are ever accepted.

from cppsqlite.

shlyakpavel avatar shlyakpavel commented on August 30, 2024

@mqudsi thank you for a nice explanation!

from cppsqlite.

mqudsi avatar mqudsi commented on August 30, 2024

No problem. Good luck hunting down your issue.

from cppsqlite.

Related Issues (5)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.