https://bugs.openldap.org/show_bug.cgi?id=9567

          Issue ID: 9567
           Summary: Double free error after attempt to insert a duplicate
                    entry
           Product: LMDB
           Version: 0.9.17
          Hardware: All
                OS: All
            Status: UNCONFIRMED
          Severity: normal
          Priority: ---
         Component: liblmdb
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: ---

This problem was originally discovered by Adi Prasaja on Ubuntu with
lmdb-0.9.24, and reproduced by me on Fedora with lmdb-0.9.25, as well as
multiple source repo branches from github.com/openldap.

The problem was introduced with lmdb version 0.9.17 and still exists in the
'head' version 0.9.70 as retrieved from github.com on May 28, 2021.

Quick demo (any Postfix version with LMDB support): create a key-value store
from a file containing one (key, value) per line.

$ cat /tmp/aa
aa      1
aa      2
$ postmap lmdb:/tmp/aa
postmap: warning: lmdb:/tmp/aa: duplicate entry: "aa" <== Postfix message
free(): double free detected in tcache 2              <== libc message
Aborted (core dumped)

Commenting out the free(env->me_txn0) call mdb_env_close0() will prevent the
double free() error. Of course, that results in a memory leak when the input
contains no duplicate line.

The remainder of this message show the steps to reproduce this with lmdb
version 0.9.70 (from github 'head') on Fedora 32 with postfix-3.7-20210424.
These steps have been verified to also work for Postfix 3.2.

The steps assume that the LMDB library and header files are installed in 
/usr/local, by using the default lmdb Makefile.

$ cat >makemakefiles-lmdb-local <<'EOF'
#!/bin/sh

export OPT=""
export CCARGS="-DNO_NIS"
export AUXLIBS=""
# Add LMDB
export CCARGS="$CCARGS -DHAS_LMDB"
export AUXLIBS_LMDB="-L/usr/local/lib -Wl,-rpath,/usr/local/lib -llmdb"

unset shlib_directory
make -f Makefile.in makefiles shared=no dynamicmaps=no
CCARGS="-I/usr/local/include $CCARGS" AUXLIBS="$AUXLIBS $AUXLIBS_LMDB"
EOF
$ make tidy
[some output]
$ sh makemakefiles-lmdb-local
$ make -j8
[lots of output]
$ cat >/tmp/aa << EOF
aa      1
aa      2
EOF
$ valgrind --tool=memcheck bin/postmap lmdb:/tmp/aa
==340318== Memcheck, a memory error detector
==340318== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==340318== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==340318== Command: bin/postmap lmdb:/tmp/aa
==340318== 
postmap: warning: lmdb:/tmp/aa: duplicate entry: "aa"
==340318== Invalid free() / delete / delete[] / realloc()
==340318==    at 0x483B9F5: free (vg_replace_malloc.c:538)
==340318==    by 0x4858CFD: mdb_env_close0 (in /usr/local/lib/liblmdb.so)
==340318==    by 0x4859B0C: mdb_env_close (in /usr/local/lib/liblmdb.so)
==340318==    by 0x13CBC3: slmdb_close (slmdb.c:780)
==340318==    by 0x13B297: dict_lmdb_close (dict_lmdb.c:475)
==340318==    by 0x113DFF: mkmap_close (mkmap_open.c:211)
==340318==    by 0x10F080: postmap (postmap.c:557)
==340318==    by 0x1108E4: main (postmap.c:1140)
==340318==  Address 0x7320c30 is 0 bytes inside a block of size 258 free'd
==340318==    at 0x483B9F5: free (vg_replace_malloc.c:538)
==340318==    by 0x48561DE: mdb_txn_commit (mdb.c:4130)
==340318==    by 0x13CB7D: slmdb_close (slmdb.c:771)
==340318==    by 0x13B297: dict_lmdb_close (dict_lmdb.c:475)
==340318==    by 0x113DFF: mkmap_close (mkmap_open.c:211)
==340318==    by 0x10F080: postmap (postmap.c:557)
==340318==    by 0x1108E4: main (postmap.c:1140)
==340318==  Block was alloc'd at
==340318==    at 0x483CAE9: calloc (vg_replace_malloc.c:760)
==340318==    by 0x48599F2: mdb_env_open (in /usr/local/lib/liblmdb.so)
==340318==    by 0x13CD91: slmdb_open (slmdb.c:851)
==340318==    by 0x13B6C6: dict_lmdb_open (dict_lmdb.c:612)
==340318==    by 0x113F50: mkmap_open (mkmap_open.c:283)
==340318==    by 0x10EC02: postmap (postmap.c:438)
==340318==    by 0x1108E4: main (postmap.c:1140)
==340318== 
==340318== 
==340318== HEAP SUMMARY:
==340318==     in use at exit: 27,608 bytes in 634 blocks
==340318==   total heap usage: 1,430 allocs, 797 frees, 3,356,293 bytes
allocated
==340318== 
==340318== LEAK SUMMARY:
==340318==    definitely lost: 0 bytes in 0 blocks
==340318==    indirectly lost: 0 bytes in 0 blocks
==340318==      possibly lost: 27,582 bytes in 633 blocks
==340318==    still reachable: 26 bytes in 1 blocks
==340318==         suppressed: 0 bytes in 0 blocks
==340318== Rerun with --leak-check=full to see details of leaked memory
==340318== 
==340318== For lists of detected and suppressed errors, rerun with: -s
==340318== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Similar errors happen with lmdb-0.9.17. The problem does not exist in
lmdb-0.9.16 or earlier versions.

-- 
You are receiving this mail because:
You are on the CC list for the issue.

Reply via email to