diff --git a/CMakeLists.txt b/CMakeLists.txt index 394ef48e9..285b8146d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -199,8 +199,13 @@ if (USE_ONEDS_BOUNDCHECK_METHODS) add_definitions(-DHAVE_ONEDS_BOUNDCHECK_METHODS) endif() +option(USE_ONEDS_SECURE_MEM_FUNCTIONS "Use secure memory functions for sqlite" OFF) +if(USE_ONEDS_SECURE_MEM_FUNCTIONS) + add_definitions(-DUSE_ONEDS_SECURE_MEM_FUNCTIONS) +endif() + if(PAL_IMPLEMENTATION STREQUAL "WIN32") - add_definitions(-DZLIB_WINAPI) + add_definitions(-DZLIB_WINAPI) endif() add_definitions(-DNOMINMAX) diff --git a/docs/List-of-OSS-Components.md b/docs/List-of-OSS-Components.md index 4d66b194d..43d8480a3 100644 --- a/docs/List-of-OSS-Components.md +++ b/docs/List-of-OSS-Components.md @@ -16,6 +16,8 @@ SQLite is a C-language library that implements a small, fast, self-contained, hi SDK maintains its own snapshot of the mainline SQLite, which is used for Windows builds [here](../sqlite). Other platforms use platform-provided SQLite. It is the responsibility of product teams to ensure that a snapshot of zlib they use meets their product security and licensing requirements. +The SDK provides an option to use a secure version of the traditional `memset` function, which includes safety checks to prevent buffer overflows. + ## [nlohmann/json](https://github.com/nlohmann/json) JSON for Modern C++. diff --git a/sqlite/memset_s.h b/sqlite/memset_s.h new file mode 100644 index 000000000..63bb41746 --- /dev/null +++ b/sqlite/memset_s.h @@ -0,0 +1,47 @@ +#ifndef MEMSET_S_H +#define MEMSET_S_H + +#include +#include +#include + +#ifndef SIZE_MAX +#define SIZE_MAX ((size_t)-1) +#endif + +#ifndef RSIZE_MAX +#define RSIZE_MAX (SIZE_MAX >> 1) +#endif + +typedef size_t rsize_t; +typedef int errno_t; + +/* +** The memset_s implementation is added as a secure version of the traditional +** memset function. It includes safety checks to prevent buffer overflows. +*/ +static errno_t memset_s_impl(void* s, rsize_t smax, int c, rsize_t n) +{ + if (!s || smax > RSIZE_MAX) + { + return EINVAL; + } + if (n > smax) + { + // Set memory up to the buffer size and return an error + memset(s, c, smax); + return EINVAL; + } + // Perform the memory set operation for the requested size + memset(s, c, n); + return 0; +} + +// Define the macro for conditional use of memset_s or memset +#ifdef USE_ONEDS_SECURE_MEM_FUNCTIONS +#define MEMSET_S(s, smax, c, n) memset_s_impl(s, smax, c, n) +#else +#define MEMSET_S(s, smax, c, n) memset(s, c, n) +#endif + +#endif // MEMSET_S_H diff --git a/sqlite/sqlite.vcxproj b/sqlite/sqlite.vcxproj index 95bbef456..b68d07389 100644 --- a/sqlite/sqlite.vcxproj +++ b/sqlite/sqlite.vcxproj @@ -586,6 +586,7 @@ + diff --git a/sqlite/sqlite.vcxproj.filters b/sqlite/sqlite.vcxproj.filters index 855165507..f24f8043d 100644 --- a/sqlite/sqlite.vcxproj.filters +++ b/sqlite/sqlite.vcxproj.filters @@ -29,5 +29,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/sqlite/sqlite3.c b/sqlite/sqlite3.c index f838fcd5d..309e34b26 100644 --- a/sqlite/sqlite3.c +++ b/sqlite/sqlite3.c @@ -1,4 +1,5 @@ #include "msvc.h" +#include "memset_s.h" #ifdef NDEBUG /* No debug */ #include "sqlite3_retail.c" diff --git a/sqlite/sqlite3_debug.c b/sqlite/sqlite3_debug.c index d120451ae..66993991a 100644 --- a/sqlite/sqlite3_debug.c +++ b/sqlite/sqlite3_debug.c @@ -49629,7 +49629,8 @@ static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit( assert( pPage!=0 ); pPgHdr = (PgHdr*)pPage->pExtra; assert( pPgHdr->pPage==0 ); - memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty)); + MEMSET_S(&pPgHdr->pDirty, sizeof(PgHdr) - offsetof(PgHdr, pDirty), 0, + sizeof(PgHdr) - offsetof(PgHdr, pDirty)); pPgHdr->pPage = pPage; pPgHdr->pData = pPage->pBuf; pPgHdr->pExtra = (void *)&pPgHdr[1]; @@ -78098,7 +78099,8 @@ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){ Vdbe *p; p = sqlite3DbMallocRawNN(db, sizeof(Vdbe) ); if( p==0 ) return 0; - memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp)); + MEMSET_S(&p->aOp, sizeof(Vdbe) - offsetof(Vdbe, aOp), 0, + sizeof(Vdbe) - offsetof(Vdbe, aOp)); p->db = db; if( db->pVdbe ){ db->pVdbe->pPrev = p; @@ -101926,7 +101928,8 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend( pItem = &pList->a[pList->nExpr++]; assert( offsetof(struct ExprList_item,zEName)==sizeof(pItem->pExpr) ); assert( offsetof(struct ExprList_item,pExpr)==0 ); - memset(&pItem->zEName,0,sizeof(*pItem)-offsetof(struct ExprList_item,zEName)); + MEMSET_S(&pItem->zEName, sizeof(*pItem) - offsetof(struct ExprList_item,zEName), 0, + sizeof(*pItem) - offsetof(struct ExprList_item,zEName)); pItem->pExpr = pExpr; return pList; @@ -144787,8 +144790,8 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ pTerm->wtFlags = wtFlags; pTerm->pWC = pWC; pTerm->iParent = -1; - memset(&pTerm->eOperator, 0, - sizeof(WhereTerm) - offsetof(WhereTerm,eOperator)); + MEMSET_S(&pTerm->eOperator, sizeof(WhereTerm) - offsetof(WhereTerm,eOperator), 0, + sizeof(WhereTerm) - offsetof(WhereTerm,eOperator)); return idx; } @@ -151130,8 +151133,8 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( pWInfo->wctrlFlags = wctrlFlags; pWInfo->iLimit = iAuxArg; pWInfo->savedNQueryLoop = pParse->nQueryLoop; - memset(&pWInfo->nOBSat, 0, - offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat)); + MEMSET_S(&pWInfo->nOBSat, offsetof(WhereInfo, sWC) - offsetof(WhereInfo, nOBSat), + 0, offsetof(WhereInfo, sWC) - offsetof(WhereInfo, nOBSat)); memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel)); assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */ pMaskSet = &pWInfo->sMaskSet; diff --git a/sqlite/sqlite3_retail.c b/sqlite/sqlite3_retail.c index 781aaecc5..c0075da33 100644 --- a/sqlite/sqlite3_retail.c +++ b/sqlite/sqlite3_retail.c @@ -49555,7 +49555,8 @@ static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit( assert( pPage!=0 ); pPgHdr = (PgHdr*)pPage->pExtra; assert( pPgHdr->pPage==0 ); - memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty)); + MEMSET_S(&pPgHdr->pDirty, sizeof(PgHdr) - offsetof(PgHdr, pDirty), 0, + sizeof(PgHdr) - offsetof(PgHdr, pDirty)); pPgHdr->pPage = pPage; pPgHdr->pData = pPage->pBuf; pPgHdr->pExtra = (void *)&pPgHdr[1]; @@ -78011,7 +78012,8 @@ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){ Vdbe *p; p = sqlite3DbMallocRawNN(db, sizeof(Vdbe) ); if( p==0 ) return 0; - memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp)); + MEMSET_S(&p->aOp, sizeof(Vdbe) - offsetof(Vdbe, aOp), 0, + sizeof(Vdbe) - offsetof(Vdbe, aOp)); p->db = db; if( db->pVdbe ){ db->pVdbe->pPrev = p; @@ -101827,7 +101829,8 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend( pItem = &pList->a[pList->nExpr++]; assert( offsetof(struct ExprList_item,zEName)==sizeof(pItem->pExpr) ); assert( offsetof(struct ExprList_item,pExpr)==0 ); - memset(&pItem->zEName,0,sizeof(*pItem)-offsetof(struct ExprList_item,zEName)); + MEMSET_S(&pItem->zEName, sizeof(*pItem) - offsetof(struct ExprList_item,zEName), 0, + sizeof(*pItem) - offsetof(struct ExprList_item,zEName)); pItem->pExpr = pExpr; return pList; @@ -144659,8 +144662,8 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ pTerm->wtFlags = wtFlags; pTerm->pWC = pWC; pTerm->iParent = -1; - memset(&pTerm->eOperator, 0, - sizeof(WhereTerm) - offsetof(WhereTerm,eOperator)); + MEMSET_S(&pTerm->eOperator, sizeof(WhereTerm) - offsetof(WhereTerm,eOperator), 0, + sizeof(WhereTerm) - offsetof(WhereTerm,eOperator)); return idx; } @@ -151001,8 +151004,8 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( pWInfo->wctrlFlags = wctrlFlags; pWInfo->iLimit = iAuxArg; pWInfo->savedNQueryLoop = pParse->nQueryLoop; - memset(&pWInfo->nOBSat, 0, - offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat)); + MEMSET_S(&pWInfo->nOBSat, offsetof(WhereInfo, sWC) - offsetof(WhereInfo, nOBSat), + 0, offsetof(WhereInfo, sWC) - offsetof(WhereInfo, nOBSat)); memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel)); assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */ pMaskSet = &pWInfo->sMaskSet;