Dear List,
I have run CodeSonar on a project using lmdb. I have downloaded lmdb-0.9.70.tar.gz. These warnings are a "Copy-Paste" error and "Use of memory after free". I would like to share the details to help find out whether these are real or false positives.
The copy-paste warning is generated by code around lines 8870f in mdb.c. In the first block, csrc-> is used throughout, in the second block cdst-> is used, except in one line:
/* Update the parent separators.
*/
if (csrc->mc_ki[csrc->mc_top] == 0) {
if (csrc->mc_ki[csrc->mc_top-1] != 0) {
if (IS_LEAF2(csrc->mc_pg[csrc->mc_top])) {
key.mv_data = LEAF2KEY(csrc->mc_pg[csrc->mc_top], 0, key.mv_size);
} else {
srcnode = NODEPTR(csrc->mc_pg[csrc->mc_top], 0);
key.mv_size = NODEKSZ(srcnode);
key.mv_data = NODEKEY(srcnode);
}
DPRINTF(("update separator for source page %"Yu" to [%s]",
csrc->mc_pg[csrc->mc_top]->mp_pgno, DKEY(&key)));
mdb_cursor_copy(csrc, &mn);
mn.mc_snum--;
mn.mc_top--;
/* We want mdb_rebalance to find mn when doing fixups */
WITH_CURSOR_TRACKING(mn,
rc = mdb_update_key(&mn, &key));
if (rc)
return rc;
}
if (IS_BRANCH(csrc->mc_pg[csrc->mc_top])) {
MDB_val nullkey;
indx_t ix = csrc->mc_ki[csrc->mc_top];
nullkey.mv_size = 0;
csrc->mc_ki[csrc->mc_top] = 0;
rc = mdb_update_key(csrc, &nullkey);
csrc->mc_ki[csrc->mc_top] = ix;
mdb_cassert(csrc, rc == MDB_SUCCESS);
}
}
if (cdst->mc_ki[cdst->mc_top] == 0) {
if (cdst->mc_ki[cdst->mc_top-1] != 0) {
if (IS_LEAF2(csrc->mc_pg[csrc->mc_top])) { /*
Copy-Paste Error [help] http://codesonar.rd.skov.com:7340/install/codesonar/doc/html/CodeSonar.html#WarningClasses/MISC/MISC.CPE.html This block of text appears to be a modified copy of the highlighted text. Did you intend to consistently change csrc to cdst, including here? */
key.mv_data = LEAF2KEY(cdst->mc_pg[cdst->mc_top], 0, key.mv_size);
} else {
srcnode = NODEPTR(cdst->mc_pg[cdst->mc_top], 0);
key.mv_size = NODEKSZ(srcnode);
key.mv_data = NODEKEY(srcnode);
}
DPRINTF(("update separator for destination page %"Yu" to [%s]",
cdst->mc_pg[cdst->mc_top]->mp_pgno, DKEY(&key)));
mdb_cursor_copy(cdst, &mn);
mn.mc_snum--;
mn.mc_top--;
/* We want mdb_rebalance to find mn when doing fixups */
WITH_CURSOR_TRACKING(mn,
rc = mdb_update_key(&mn, &key));
if (rc)
return rc;
}
if (IS_BRANCH(cdst->mc_pg[cdst->mc_top])) {
MDB_val nullkey;
indx_t ix = cdst->mc_ki[cdst->mc_top];
nullkey.mv_size = 0;
cdst->mc_ki[cdst->mc_top] = 0;
rc = mdb_update_key(cdst, &nullkey);
cdst->mc_ki[cdst->mc_top] = ix;
mdb_cassert(cdst, rc == MDB_SUCCESS);
} }
The second error is triggered by the loop freeing loose pages at line 3451 in mdb.c: NEXT_LOOSE_PAGE(mp) would access memory that is freed before, if mp points to an overflow page with more than one page allocated. If this is never the case, then maybe mdb_page_free() should be called on mp directly?
for (; mp; mp = NEXT_LOOSE_PAGE(mp)) {
/* Use After Free [help] http://codesonar.rd.skov.com:7340/install/codesonar/doc/html/CodeSonar.html#WarningClasses/ALLOC/ALLOC.UAF.html The memory pointed to by mp was freed at mdb.c:2047 and is read from here. */
mdb_midl_xappend(txn->mt_free_pgs, mp->mp_pgno);
/* must also remove from dirty list */
if (txn->mt_flags & MDB_TXN_WRITEMAP) {
for (x=1; x<=dl[0].mid; x++)
if (dl[x].mid == mp->mp_pgno)
break;
mdb_tassert(txn, x <= dl[0].mid);
} else {
x = mdb_mid2l_search(dl, mp->mp_pgno);
mdb_tassert(txn, dl[x].mid == mp->mp_pgno);
}
dl[x].mptr = NULL;
mdb_dpage_free(env, mp);
mdb_dpage_free(MDB_env *env, MDB_page *dp)
{
if (!IS_OVERFLOW(dp) || dp->mp_pages == 1) {
mdb_page_free(env, dp);
} else {
/* large pages just get freed directly */
VGMEMP_FREE(env, dp);
free(dp);
} }
I hope you can follow these descriptions, I can provide more detail if needed. I would like to get some help figuring out how to resolve these warnings.
Best regards,
Christian Wendt Software developer Ext: +45 7217 5943 ______________________________________ SKOV A/S Hedelund 4, Glyngoere, 7870 Roslev, Denmark Tel.: +45 7217 5555 - Fax: +45 7217 5959 www.skov.comhttp://www.skov.com/