Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash on mdb_node_search for corrupted data.mdb file #30

Open
unseddd opened this issue Jul 29, 2020 · 1 comment
Open

Crash on mdb_node_search for corrupted data.mdb file #30

unseddd opened this issue Jul 29, 2020 · 1 comment

Comments

@unseddd
Copy link

unseddd commented Jul 29, 2020

With the following minimal example for creating a test entry in an LMDB database:

use lmdb_zero as lmdb;

fn main() {
    let path = "test_mdb";
    std::fs::create_dir_all(path).unwrap();

    let env = unsafe {
        lmdb::EnvBuilder::new().unwrap().open(
            path, lmdb::open::NOTLS, 0o600).unwrap()
    };

    let db = lmdb::Database::open(
        &env, None, &lmdb::DatabaseOptions::new(lmdb::db::CREATE))
        .unwrap();

    {
        let txn = lmdb::WriteTransaction::new(&env).unwrap();

        {
            let mut access = txn.access();
            access.put(&db, "Test", "Entry", lmdb::put::Flags::empty()).unwrap();
        }

        txn.commit().unwrap();
    }
}

The program will create a database in test_mdb/data.mdb, which you can edit with a hex-editor to get the following diff:

< 00002000: 0200 0000 0000 0000 0000 0200 1200 ee0f  ................
---
> 00002000: 0200 0000 0000 0000 0000 0200 0000 ee0f  ................

So, change byte 200c to 00, which appears to encode lmdb node information.

Convert the hex dump back to binary data.mdb file, and re-run the program. Notice the SIGSEGV segmentation fault.

Here is a GDB backtrace of the crash:

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x000000bd63721dea in mdb_node_search (mc=mc@entry=0x787fffa5de90, key=key@entry=0x787fffa5e358, exactp=exactp@entry=0x787fffa5dde0) at mdb/libraries/liblmdb/mdb.c:5116
5116                            i = (low + high) >> 1;
warning: Missing auto-load script at offset 0 in section .debug_gdb_scripts
of file /home/user/lmdb-test/target/debug/lmdb-test.
Use `info auto-load python-scripts [REGEXP]' to list them.
(gdb) bt full
#0  0x000000bd63721dea in mdb_node_search (mc=mc@entry=0x787fffa5de90, key=key@entry=0x787fffa5e358, exactp=exactp@entry=0x787fffa5dde0) at mdb/libraries/liblmdb/mdb.c:5116
        i = 0
        nkeys = 2147483640
        low = 0
        high = 2147483639
        rc = 0
        mp = 0x68dc291b9000
        node = 0x0
        nodekey = {mv_size = 18446744073709551615, mv_data = 0xbd9591be91}
        cmp = 0xbd637224e0 <mdb_cmp_memn>
#1  0x000000bd63725a0e in mdb_cursor_set (mc=mc@entry=0x787fffa5de90, key=key@entry=0x787fffa5e358, data=0x787fffa5ddf0, op=op@entry=MDB_SET, exactp=exactp@entry=0x787fffa5dde0) at mdb/libraries/liblmdb/mdb.c:591
3
        rc = 0
        mp = 0x68dc291b9000
        leaf = <optimized out>
        __func__ = "mdb_cursor_set"
#2  0x000000bd63729c38 in mdb_cursor_put (mc=mc@entry=0x787fffa5de90, key=key@entry=0x787fffa5e358, data=data@entry=0x787fffa5e368, flags=flags@entry=0) at mdb/libraries/liblmdb/mdb.c:6344
        exact = 0
        d2 = {mv_size = 814258175649, mv_data = 0xbd9591be90}
        env = 0xbd9591ab70
        leaf = 0x0
        fp = <optimized out>
        mp = 0x787fffa5ddd8
        sub_root = 0x0
        fp_flags = <optimized out>
        xdata = {mv_size = 1, mv_data = 0xbd9591bea1}
        rdata = <optimized out>
        dkey = {mv_size = 0, mv_data = 0x11}
        olddata = {mv_size = 811748818944, mv_data = 0xbd6371f964 <core::ptr::mut_ptr::<impl *mut T>::add+20>}
        dummy = {md_pad = 17, md_flags = 0, md_depth = 0, md_branch_pages = 813417218354, md_leaf_pages = 814258175649, md_overflow_pages = 814258175632, md_entries = 17, md_root = 4294967297}
        do_sub = 0
        insert_key = <optimized out>
        insert_data = <optimized out>
        mcount = 0
        dcount = 0
        nospill = 0
        nsize = <optimized out>
        rc = <optimized out>
        rc2 = <optimized out>
        nflags = <optimized out>
        __func__ = "mdb_cursor_put"
#3  0x000000bd6372c16b in mdb_put (txn=0xbd9591bd80, dbi=1, key=0x787fffa5e358, data=0x787fffa5e368, flags=0) at mdb/libraries/liblmdb/mdb.c:8771
        mc = {mc_next = 0x0, mc_backup = 0x0, mc_xcursor = 0x0, mc_txn = 0xbd9591bd80, mc_dbi = 1, mc_db = 0xbd9591be38, mc_dbx = 0xbd9591acf0, mc_dbflag = 0xbd9591be81 "\030", mc_snum = 1, mc_top = 0, mc_flags =
 1, mc_pg = {
            0x68dc291b9000, 0x787fffa5def0, 0x787fffa5e230, 0xbd9591bd80, 0xbd637186e9 <core::intrinsics::copy_nonoverlapping+41>, 0x100000001, 0x787fffa5dfb8, 0x787fffa5dfb8, 0x787fffa5dfb8, 0xbd9591bd80,
            0xbd637190da <core::ptr::swap_nonoverlapping_one+170>, 0xbd9591bd80, 0x8, 0x787fffa5dfb8, 0x787fffa5e230, 0xff787fffa5e400, 0x787fffa5e230, 0x787fffa5dfb8, 0xbd9591bd80, 0x913d57a257183f34, 0x11ba093b
6d60665f, 0x8,
            0xbd63716e04 <core::mem::swap+20>, 0x0, 0xc894ed1c80428900, 0x787fffa5dfb8, 0x787fffa5e700, 0x1, 0x787fff260000, 0x787fff25f000, 0xbd6376e2e0, 0x787fffa5e4ff}, mc_ki = {0, 25457, 189, 0, 44144, 38289,
 189, 0, 62861, 25457,
            189, 0, 44144, 38289, 189, 0, 44144, 38289, 189, 0, 0, 0, 0, 0, 51642, 25457, 189, 0, 44144, 38289, 189, 0}}
        mx = {mx_cursor = {mc_next = 0x787fffa5e230, mc_backup = 0x787fffa5e1b0, mc_xcursor = 0x787fffa5e1b0, mc_txn = 0x787fffa5e118, mc_dbi = 4289061144, mc_db = 0xbd63710cdc <lmdb_zero::dbi::Database::open+230
0>,
            mc_dbx = 0xbd00000001, mc_dbflag = 0x10000bd637179cd <error: Cannot access memory at address 0x10000bd637179cd>, mc_snum = 58456, mc_top = 65445, mc_flags = 30847, mc_pg = {0x4000000000000, 0x0, 0x0,
0xbd9591bd80, 0x1,
              0xbd9591ab70, 0x787fffa5e438, 0x2000000091ab50, 0x787fffa5e438, 0x787fffa5e448, 0x5d59591ab50, 0x787fffa5e448, 0xc894ed1c80428900, 0x787fffa5e438, 0xbd9591ab70, 0xbd9591bd80, 0x0, 0x0, 0xbd6376e2e0,
 0x68dc297c9000,
              0xbd63723226 <mdb_txn_renew0+598>, 0x787fffa5e438, 0xbd6370f6a7 <supercow::Supercow<OWNED,BORROWED,SHARED,STORAGE,PTR>::borrowed+71>, 0x1, 0x0, 0x1, 0x0, 0x787fff25f000, 0xbd6376e2e0, 0xbd9591bd80,
              0xbd637240a8 <mdb_txn_begin+824>, 0x787f20200000}, mc_ki = {57664, 65445, 30847, 0, 58424, 65445, 30847, 0, 43888, 38289, 189, 0, 0, 0, 0, 0, 57896, 65445, 30847, 0, 58424, 65445, 30847, 0, 5, 0, 0,
 0, 37421, 25461, 189,
              0}}, mx_db = {md_pad = 1668649517, md_flags = 189, md_depth = 0, md_branch_pages = 5, md_leaf_pages = 813417468461, md_overflow_pages = 5, md_entries = 813417468461, md_root = 5}, mx_dbx = {md_name = {
              mv_size = 813417195181, mv_data = 0x787fffa5e518}, md_cmp = 0xbd6375922d, md_dcmp = 0xbd6375922d, md_rel = 0x5, md_relctx = 0x5}, mx_dbflag = 45 '-'}
        rc = <optimized out>
#4  0x000000bd63716154 in lmdb_zero::tx::WriteAccessor::put (self=0x787fffa5e5c8, db=0x787fffa5e518, key=..., value=..., flags=...) at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/lmdb-zero-0.4.4/src/tx.rs:1043
        mv_val = liblmdb_sys::MDB_val {mv_size: 5, mv_data: 0xbd6375922d}
        mv_key = liblmdb_sys::MDB_val {mv_size: 4, mv_data: 0xbd63759229}
#5  0x000000bd637156c0 in lmdb_test::main () at src/main.rs:21
        access = lmdb_zero::tx::WriteAccessor (lmdb_zero::tx::ConstAccessor (0x787fffa5e580))
        txn = lmdb_zero::tx::WriteTransaction (lmdb_zero::tx::ConstTransaction {env: supercow::Supercow<lmdb_zero::env::Environment, lmdb_zero::env::Environment, alloc::boxed::Box<NonSyncFeatures>, supercow::ext::BoxedStorage, *const lmdb_zero::env::Environment> {ptr: 0x787fffa5e438, mode: 0x0, storage: supercow::ext::BoxedStorage, _owned: core::marker::PhantomData<lmdb_zero::env::Environment>, _borrowed: core::marker::PhantomData<&lmdb_zero::env::Environment>, _shared: core::marker::PhantomData<alloc::boxed::Box<NonSyncFeatures>>}, tx: lmdb_zero::tx::TxHandle (0xbd9591bd80), has_yielded_accessor: core::cell::Cell<bool> {value: core::cell::UnsafeCell<bool> {value: true}}})
        db = lmdb_zero::dbi::Database {db: lmdb_zero::dbi::DbHandle {env: supercow::Supercow<lmdb_zero::env::Environment, lmdb_zero::env::Environment, alloc::boxed::Box<DefaultFeatures>, supercow::ext::BoxedStorage, *const lmdb_zero::env::
Environment> {ptr: 0x787fffa5e438, mode: 0x0, storage: supercow::ext::BoxedStorage, _owned: core::marker::PhantomData<lmdb_zero::env::Environment>, _borrowed: core::marker::PhantomData<&lmdb_zero::env::Environment>, _shared: core::marker::PhantomData<alloc::boxed::Box<DefaultFeatures>>}, dbi: 1, close_on_drop: true}}
        env = lmdb_zero::env::Environment {env: lmdb_zero::env::EnvHandle (0xbd9591ab70, true), open_dbis: std::sync::mutex::Mutex<std::collections::hash::set::HashSet<u32, std::collections::hash::map::RandomState>> {inner: 0xbd9591ac70, poison: std::sys_common::poison::Flag {failed: core::sync::atomic::AtomicBool {v: core::cell::UnsafeCell<u8> {value: 0}}}, data: core::cell::UnsafeCell<std::collections::hash::set::HashSet<u32, std::collections::hash::map::RandomState>> {value: std::collections::hash::set::HashSet<u32, std::collections::hash::map::RandomState> {map: std::collections::hash::map::HashMap<u32, (), std::collections::hash::map::RandomState> {base: hashbrown::map::HashMap<u32, (), std::collections::hash::map::RandomState> {hash_builder: std::collections::hash::map::RandomState {k0: 14426757800413882002, k1: 9949619668887126613}, table: hashbrown::raw::RawTable<(u32, ())> {bucket_mask: 1, ctrl: core::ptr::non_null::NonNull<u8> {pointer: 0xbd9591be90 "\377\b", '\377' <repeats 15 times>, "\b\000"}, data: core::ptr::non_null::NonNull<(u32, ())> {pointer: 0xbd9591bea4}, growth_left: 0, items: 1, marker: core::marker::PhantomData<(u32, ())>}}}}}}}
        path = "test_mdb"
@unseddd
Copy link
Author

unseddd commented Jul 29, 2020

The crash is ultimately somewhere around liblmdb-sys/mdb/libraries/liblmdb/mdb.c:5116, so can raise an issue upstream if that is better, referencing this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant