Skip to content

Results of the Facebook Infer static analysis tool #111

@TomasBeranek

Description

@TomasBeranek

Hello, within the Arrowhead Project we applied the Facebook Infer static analyzer to the core-cpp project. Infer produced over 500 issues (note that Infer produces a large number of false reports). Due to a large number of reported issues, we have checked only reported NULL dereferences. Some of them point to some suspicious parts of the code:

103
core-cpp/inc/sqlite3/shell.c:14500: error: Null Dereference
pointer 'zText' last assigned on line 14498 could be null and is dereferenced at line 14500, column 7.

    14498.   const char *zText = (const char*)sqlite3_value_text(argv[0]);
    14499.   UNUSED_PARAMETER(argc);
    14500.   if( zText[0]=='\'' ){
                 ^
    14501.     int nText = sqlite3_value_bytes(argv[0]);
    14502.     int i;

The sqlite3ValueText function can return NULL, but in the shellEscapeCrnl
function, there is no check for it. In this context, I was not able to prove that
the NULL DEREFERENCE may happen, but it is a generally good practice to check
the returned value if the function can return NULL.

329
core-cpp/inc/sqlite3/sqlite3.c:102113: error: Null Dereference
pointer 'pExpr' last assigned on line 102109 could be null and is dereferenced at line 102113, column 10.

    102111.   assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0
    102112.        || sqlite3StrICmp(pExpr->u.zToken,"false")==0 );
    102113.   return pExpr->u.zToken[4]==0;
                     ^
    102114. }
    102115.

The sqlite3ExprSkipCollate function can return NULL, because it contains while
loop, which can break when pExpr == NULL, this value is then immediately returned.
In the sqlite3ExprTruthValue function, the returned value is not checked for NULL.
Again, I was not able to prove that the NULL DEREFERENCE can happen (see 103).

380
core-cpp/inc/sqlite3/sqlite3.c:116098: error: Null Dereference
pointer 'pColl2' last assigned on line 116097 could be null and is dereferenced at line 116098, column 9.

    116096.   for(i=0; i<3; i++){
    116097.     pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, 0);
    116098.     if( pColl2->xCmp!=0 ){
                    ^
    116099.       memcpy(pColl, pColl2, sizeof(CollSeq));
    116100.       pColl->xDel = 0;         /* Do not copy the destructor */

The NULL DEREFERENCE can happen if the sqlite3HashFind function can return NULL.
Since in the findCollSeqEntry function, there is a check for it, I assume that it
is possible. Moreover, one level above in the call tree there is another check for
NULL --> if the returned value is not NULL then some offset is added. Again,
I was not able to prove that the NULL DEREFERENCE can happen (see 103).

417
core-cpp/inc/sqlite3/sqlite3.c:122594: error: Null Dereference
pointer 'pPk' last assigned on line 122593 could be null and is dereferenced at line 122594, column 16.

    122592.   }else{
    122593.     pPk = sqlite3PrimaryKeyIndex(pTab);
    122594.     nPkField = pPk->nKeyCol;
                           ^
    122595.   }
    122596.

The NULL DEREFERENCE can happen if the sqlite3PrimaryKeyIndex function can return
NULL. It is possible because:

	Index *p;
	for(p=pTab->pIndex; p && !IsPrimaryKeyIndex(p); p=p->pNext){}
	return p;

The loop can end when p == NULL and the NULL value is then returned. Again,
I was not able to prove that the NULL DEREFERENCE can happen (see 103).

492
core-cpp/inc/sqlite3/sqlite3.c:139683: error: Null Dereference
pointer 'pPk' last assigned on line 139682 could be null and is dereferenced at line 139683, column 17.

    139681.     }else{
    139682.       Index *pPk = sqlite3PrimaryKeyIndex(pTab);
    139683.       int nPk = pPk->nKeyCol;
                            ^
    139684.       int iPk = pParse->nMem+1;
    139685.       pParse->nMem += nPk;

Same as 417.

506
core-cpp/inc/sqlite3/sqlite3.c:142499: error: Null Dereference
pointer 'pNew' last assigned on line 142497 could be null and is dereferenced at line 142499, column 26.

    142497.   pNew = sqlite3ExprDup(db, pX, 0);
    142498.   if( db->mallocFailed==0 ){
    142499.     ExprList *pOrigRhs = pNew->x.pSelect->pEList;  /* Original unmodified RHS */
                                     ^
    142500.     ExprList *pOrigLhs = pNew->pLeft->x.pList;     /* Original unmodified LHS */
    142501.     ExprList *pRhs = 0;         /* New RHS after modifications */

The NULL DEREFERENCE can happen if the sqlite3ExprDup function can return NULL.
It is possible because:

	return p ? exprDup(db, p, flags, 0) : 0;

Again, I was not able to prove that the NULL DEREFERENCE can happen (see 103).

512
core-cpp/inc/sqlite3/sqlite3.c:144771: error: Null Dereference
pointer 'pRight' last assigned on line 144770 could be null and is dereferenced at line 144771, column 8.

    144769.
    144770.   pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr);
    144771.   op = pRight->op;
                   ^
    144772.   if( op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){
    144773.     Vdbe *pReprepare = pParse->pReprepare;

Same as 329.

If you are interested, I can also provide the rest of the reported issues or a more detailed description produced by Infer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions