Issue 7828 - LMDB crash in mdb_cursor_put(MDB_CURRENT)
Summary: LMDB crash in mdb_cursor_put(MDB_CURRENT)
Status: VERIFIED FIXED
Alias: None
Product: LMDB
Classification: Unclassified
Component: liblmdb (show other issues)
Version: unspecified
Hardware: All All
: --- normal
Target Milestone: ---
Assignee: OpenLDAP project
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-03-26 06:29 UTC by sbn@tbricks.com
Modified: 2020-03-12 15:54 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Howard Chu 2014-03-26 03:10:21 UTC
changed notes
changed state Open to Test
moved from Incoming to Software Bugs
Comment 1 sbn@tbricks.com 2014-03-26 06:29:49 UTC
Full_Name: Dmitri Shubin
Version: LMDB 0.9.11 (2727e97)
OS: Linux (CentOS 6)
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (80.239.140.98)


Hi!

I got a crash inside LMDB in mdb_cursor_put() functions when I trying to modify
the record under cursor.

Simple test:

$ cat test-mdb_current.c 
#include <stdio.h>
#include <stdlib.h>

#include "lmdb.h"

#define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr)
#define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \
    "%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort()))

#define DBDIR "./testdb"

int main()
{
    int rc;
    MDB_env *env;
    MDB_dbi dbi;
    MDB_txn *txn;
    MDB_val key, data;
    MDB_cursor *cursor;

    int key_v = 17;
    char data_v[] = "0123456789";

    E(system("rm -rf " DBDIR " && mkdir " DBDIR));

    E(mdb_env_create(&env));
    E(mdb_env_open(env, DBDIR, 0, 0664));

    E(mdb_txn_begin(env, NULL, 0, &txn));
    E(mdb_dbi_open(txn, NULL, 0, &dbi));

    /* put some data */
    key.mv_data = &key_v;
    key.mv_size = sizeof(key_v);
    data.mv_data = data_v;
    data.mv_size = sizeof(data_v);

    E(mdb_put(txn, dbi, &key, &data, 0));

    E(mdb_txn_commit(txn));

    /* replace using cursor */
    E(mdb_txn_begin(env, NULL, 0, &txn));

    E(mdb_cursor_open(txn, dbi, &cursor));

    E(mdb_cursor_get(cursor, &key, &data, MDB_SET));

    data.mv_data = data_v;
    data.mv_size = sizeof(data_v) - 1;
    E(mdb_cursor_put(cursor, &key, &data, MDB_CURRENT));

    mdb_cursor_close(cursor);

    E(mdb_txn_commit(txn));

    mdb_dbi_close(env, dbi);
    mdb_env_close(env);

    return 0;
}
$ gcc -g test-mdb_current.c  -llmdb -L. -Wl,-rpath,.
$ ./a.out 
Segmentation fault (core dumped)
$ gdb a.out
...
Program terminated with signal 11, Segmentation fault.
#0  0x00007fefaba9895c in mdb_leaf_size (env=0xbd8010, key=0x0,
data=0x7fff59e6a830) at mdb.c:6430
6430            sz = LEAFSIZE(key, data);
(gdb) bt
#0  0x00007fefaba9895c in mdb_leaf_size (env=0xbd8010, key=0x0,
data=0x7fff59e6a830) at mdb.c:6430
#1  0x00007fefaba97c53 in mdb_cursor_put (mc=0xbda2f0, key=0x0,
data=0x7fff59e6a830, flags=64) at mdb.c:6178
#2  0x0000000000400ee0 in main () at test-mdb_current.c:51
(gdb) l
6425    static size_t
6426    mdb_leaf_size(MDB_env *env, MDB_val *key, MDB_val *data)
6427    {
6428            size_t           sz;
6429
6430            sz = LEAFSIZE(key, data);
6431            if (sz > env->me_nodemax) {
6432                    /* put on overflow page */
6433                    sz -= data->mv_size - sizeof(pgno_t);
6434            }
(gdb) p key
$1 = (MDB_val *) 0x0

If I remove MDB_CURRENT flag from mdb_cursor_put() call it works fine.

Thanks!
Comment 2 Hallvard Furuseth 2014-03-26 08:54:33 UTC
Doc bug, fixed recently: MDB_CURRENT must not change the data size.

Also with DUPSORT the data item must sort in the same place as the
previous one, that needs to be documented too.


Comment 3 Howard Chu 2014-03-26 09:42:25 UTC
h.b.furuseth@usit.uio.no wrote:
> Doc bug, fixed recently: MDB_CURRENT must not change the data size.

Wrong. This is a regression due to ITS#7793. That commit has now been reverted.

> Also with DUPSORT the data item must sort in the same place as the
> previous one, that needs to be documented too.

I'll add this note to the doc.

-- 
   -- Howard Chu
   CTO, Symas Corp.           http://www.symas.com
   Director, Highland Sun     http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP  http://www.openldap.org/project/

Comment 4 sbn@tbricks.com 2014-03-28 06:39:18 UTC
Works after reverting commit (checked f537429)
Thanks!

Comment 5 OpenLDAP project 2014-08-01 21:04:51 UTC
fixed in mdb.master
Comment 6 Quanah Gibson-Mount 2014-12-11 01:06:33 UTC
changed state Test to Release
Comment 7 Quanah Gibson-Mount 2014-12-11 01:12:02 UTC
changed state Release to Closed