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/
Christian Wendt wrote:
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.
Generally you should report bugs by opening a ticket in the ITS.
Christian Wendt wrote:
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:
The code is correct. If either src or dst is a LEAF2 page, both of them will be, so it makes no difference which page is checked. The code uses csrc in both places because it will likely already be in the CPU cache the second time.
Christian Wendt wrote:
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?
Overflow pages are never loose. The code is correct.
openldap-technical@openldap.org