Merge pull request #2602 from LMDB/issue2601

Fix #2601 misuses of LMDB API
This commit is contained in:
martinhsv 2022-02-09 10:46:15 -05:00 committed by GitHub
commit d0813fec45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 107 deletions

View File

@ -37,9 +37,13 @@ namespace backend {
LMDB::LMDB(std::string name) : LMDB::LMDB(std::string name) :
Collection(name), m_env(NULL) { Collection(name), m_env(NULL) {
MDB_txn *txn;
mdb_env_create(&m_env); mdb_env_create(&m_env);
mdb_env_open(m_env, "./modsec-shared-collections", mdb_env_open(m_env, "./modsec-shared-collections",
MDB_WRITEMAP | MDB_NOSUBDIR, 0664); MDB_WRITEMAP | MDB_NOSUBDIR, 0664);
mdb_txn_begin(m_env, NULL, 0, &txn);
mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &m_dbi);
mdb_txn_commit(txn);
} }
@ -89,23 +93,6 @@ void LMDB::lmdb_debug(int rc, std::string op, std::string scope) {
break; break;
} }
std::cout << std::endl; std::cout << std::endl;
} else if (op == "dbi") {
std::cout << scope << ", LMDB failure while opening dbi: ";
switch (rc) {
case MDB_NOTFOUND:
std::cout << "not found: the specified database doesn't ";
std::cout << "exist in the environment and MDB_CREATE was ";
std::cout << "not specified.";
break;
case MDB_DBS_FULL:
std::cout << "full: too many databases have been opened. See ";
std::cout << "mdb_env_set_maxdbs().";
break;
default:
std::cout << "not sure what is wrong.";
break;
}
std::cout << std::endl;
} else if (op == "get") { } else if (op == "get") {
std::cout << scope << ", LMDB failure while getting the key: "; std::cout << scope << ", LMDB failure while getting the key: ";
switch (rc) { switch (rc) {
@ -169,21 +156,15 @@ std::unique_ptr<std::string> LMDB::resolveFirst(const std::string& var) {
MDB_val mdb_value_ret; MDB_val mdb_value_ret;
std::unique_ptr<std::string> ret = NULL; std::unique_ptr<std::string> ret = NULL;
MDB_txn *txn = NULL; MDB_txn *txn = NULL;
MDB_dbi dbi;
string2val(var, &mdb_key); string2val(var, &mdb_key);
rc = mdb_txn_begin(m_env, NULL, 0, &txn); rc = mdb_txn_begin(m_env, NULL, MDB_RDONLY, &txn);
lmdb_debug(rc, "txn", "resolveFirst"); lmdb_debug(rc, "txn", "resolveFirst");
if (rc != 0) { if (rc != 0) {
goto end_txn; goto end_txn;
} }
rc = mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &dbi); rc = mdb_get(txn, m_dbi, &mdb_key, &mdb_value_ret);
lmdb_debug(rc, "dbi", "resolveFirst");
if (rc != 0) {
goto end_dbi;
}
rc = mdb_get(txn, dbi, &mdb_key, &mdb_value_ret);
lmdb_debug(rc, "get", "resolveFirst"); lmdb_debug(rc, "get", "resolveFirst");
if (rc != 0) { if (rc != 0) {
goto end_get; goto end_get;
@ -194,8 +175,6 @@ std::unique_ptr<std::string> LMDB::resolveFirst(const std::string& var) {
mdb_value_ret.mv_size)); mdb_value_ret.mv_size));
end_get: end_get:
mdb_dbi_close(m_env, dbi);
end_dbi:
mdb_txn_abort(txn); mdb_txn_abort(txn);
end_txn: end_txn:
return ret; return ret;
@ -206,7 +185,6 @@ bool LMDB::storeOrUpdateFirst(const std::string &key,
const std::string &value) { const std::string &value) {
int rc; int rc;
MDB_txn *txn; MDB_txn *txn;
MDB_dbi dbi;
MDB_val mdb_key; MDB_val mdb_key;
MDB_val mdb_value; MDB_val mdb_value;
MDB_val mdb_value_ret; MDB_val mdb_value_ret;
@ -220,23 +198,17 @@ bool LMDB::storeOrUpdateFirst(const std::string &key,
goto end_txn; goto end_txn;
} }
rc = mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &dbi); rc = mdb_get(txn, m_dbi, &mdb_key, &mdb_value_ret);
lmdb_debug(rc, "dbi", "storeOrUpdateFirst");
if (rc != 0) {
goto end_dbi;
}
rc = mdb_get(txn, dbi, &mdb_key, &mdb_value_ret);
lmdb_debug(rc, "get", "storeOrUpdateFirst"); lmdb_debug(rc, "get", "storeOrUpdateFirst");
if (rc == 0) { if (rc == 0) {
rc = mdb_del(txn, dbi, &mdb_key, &mdb_value_ret); rc = mdb_del(txn, m_dbi, &mdb_key, &mdb_value_ret);
lmdb_debug(rc, "del", "storeOrUpdateFirst"); lmdb_debug(rc, "del", "storeOrUpdateFirst");
if (rc != 0) { if (rc != 0) {
goto end_del; goto end_del;
} }
} }
rc = mdb_put(txn, dbi, &mdb_key, &mdb_value, 0); rc = mdb_put(txn, m_dbi, &mdb_key, &mdb_value, 0);
lmdb_debug(rc, "put", "storeOrUpdateFirst"); lmdb_debug(rc, "put", "storeOrUpdateFirst");
if (rc != 0) { if (rc != 0) {
goto end_put; goto end_put;
@ -248,14 +220,12 @@ bool LMDB::storeOrUpdateFirst(const std::string &key,
goto end_commit; goto end_commit;
} }
end_commit:
end_put: end_put:
end_del: end_del:
mdb_dbi_close(m_env, dbi);
end_dbi:
if (rc != 0) { if (rc != 0) {
mdb_txn_abort(txn); mdb_txn_abort(txn);
} }
end_commit:
end_txn: end_txn:
return true; return true;
} }
@ -265,26 +235,20 @@ void LMDB::resolveSingleMatch(const std::string& var,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
int rc; int rc;
MDB_txn *txn; MDB_txn *txn;
MDB_dbi dbi;
MDB_val mdb_key; MDB_val mdb_key;
MDB_val mdb_value; MDB_val mdb_value;
MDB_val mdb_value_ret; MDB_val mdb_value_ret;
MDB_cursor *cursor; MDB_cursor *cursor;
rc = mdb_txn_begin(m_env, NULL, 0, &txn); rc = mdb_txn_begin(m_env, NULL, MDB_RDONLY, &txn);
lmdb_debug(rc, "txn", "resolveSingleMatch"); lmdb_debug(rc, "txn", "resolveSingleMatch");
if (rc != 0) { if (rc != 0) {
goto end_txn; goto end_txn;
} }
rc = mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &dbi);
lmdb_debug(rc, "dbi", "resolveSingleMatch");
if (rc != 0) {
goto end_dbi;
}
string2val(var, &mdb_key); string2val(var, &mdb_key);
mdb_cursor_open(txn, dbi, &cursor); mdb_cursor_open(txn, m_dbi, &cursor);
while ((rc = mdb_cursor_get(cursor, &mdb_key, while ((rc = mdb_cursor_get(cursor, &mdb_key,
&mdb_value_ret, MDB_NEXT_DUP)) == 0) { &mdb_value_ret, MDB_NEXT_DUP)) == 0) {
std::string *a = new std::string( std::string *a = new std::string(
@ -295,9 +259,6 @@ void LMDB::resolveSingleMatch(const std::string& var,
} }
mdb_cursor_close(cursor); mdb_cursor_close(cursor);
mdb_dbi_close(m_env, dbi);
end_dbi:
mdb_txn_abort(txn); mdb_txn_abort(txn);
end_txn: end_txn:
return; return;
@ -307,7 +268,6 @@ end_txn:
void LMDB::store(std::string key, std::string value) { void LMDB::store(std::string key, std::string value) {
MDB_val mdb_key, mdb_data; MDB_val mdb_key, mdb_data;
MDB_txn *txn = NULL; MDB_txn *txn = NULL;
MDB_dbi dbi;
int rc; int rc;
MDB_stat mst; MDB_stat mst;
@ -316,15 +276,10 @@ void LMDB::store(std::string key, std::string value) {
if (rc != 0) { if (rc != 0) {
goto end_txn; goto end_txn;
} }
rc = mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &dbi);
lmdb_debug(rc, "dbi", "store");
if (rc != 0) {
goto end_dbi;
}
string2val(key, &mdb_key); string2val(key, &mdb_key);
string2val(value, &mdb_data); string2val(value, &mdb_data);
rc = mdb_put(txn, dbi, &mdb_key, &mdb_data, 0); rc = mdb_put(txn, m_dbi, &mdb_key, &mdb_data, 0);
lmdb_debug(rc, "put", "store"); lmdb_debug(rc, "put", "store");
if (rc != 0) { if (rc != 0) {
goto end_put; goto end_put;
@ -336,13 +291,12 @@ void LMDB::store(std::string key, std::string value) {
goto end_commit; goto end_commit;
} }
end_commit:
end_put: end_put:
mdb_dbi_close(m_env, dbi);
end_dbi: end_dbi:
if (rc != 0) { if (rc != 0) {
mdb_txn_abort(txn); mdb_txn_abort(txn);
} }
end_commit:
end_txn: end_txn:
return; return;
} }
@ -352,7 +306,6 @@ bool LMDB::updateFirst(const std::string &key,
const std::string &value) { const std::string &value) {
int rc; int rc;
MDB_txn *txn; MDB_txn *txn;
MDB_dbi dbi;
MDB_val mdb_key; MDB_val mdb_key;
MDB_val mdb_value; MDB_val mdb_value;
MDB_val mdb_value_ret; MDB_val mdb_value_ret;
@ -363,28 +316,22 @@ bool LMDB::updateFirst(const std::string &key,
goto end_txn; goto end_txn;
} }
rc = mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &dbi);
lmdb_debug(rc, "dbi", "updateFirst");
if (rc != 0) {
goto end_dbi;
}
string2val(key, &mdb_key); string2val(key, &mdb_key);
string2val(value, &mdb_value); string2val(value, &mdb_value);
rc = mdb_get(txn, dbi, &mdb_key, &mdb_value_ret); rc = mdb_get(txn, m_dbi, &mdb_key, &mdb_value_ret);
lmdb_debug(rc, "get", "updateFirst"); lmdb_debug(rc, "get", "updateFirst");
if (rc != 0) { if (rc != 0) {
goto end_get; goto end_get;
} }
rc = mdb_del(txn, dbi, &mdb_key, &mdb_value_ret); rc = mdb_del(txn, m_dbi, &mdb_key, &mdb_value_ret);
lmdb_debug(rc, "del", "updateFirst"); lmdb_debug(rc, "del", "updateFirst");
if (rc != 0) { if (rc != 0) {
goto end_del; goto end_del;
} }
rc = mdb_put(txn, dbi, &mdb_key, &mdb_value, 0); rc = mdb_put(txn, m_dbi, &mdb_key, &mdb_value, 0);
lmdb_debug(rc, "put", "updateFirst"); lmdb_debug(rc, "put", "updateFirst");
if (rc != 0) { if (rc != 0) {
goto end_put; goto end_put;
@ -396,15 +343,13 @@ bool LMDB::updateFirst(const std::string &key,
goto end_commit; goto end_commit;
} }
end_commit:
end_put: end_put:
end_del: end_del:
end_get: end_get:
mdb_dbi_close(m_env, dbi);
end_dbi:
if (rc != 0) { if (rc != 0) {
mdb_txn_abort(txn); mdb_txn_abort(txn);
} }
end_commit:
end_txn: end_txn:
return rc == 0; return rc == 0;
@ -414,7 +359,6 @@ end_txn:
void LMDB::del(const std::string& key) { void LMDB::del(const std::string& key) {
int rc; int rc;
MDB_txn *txn; MDB_txn *txn;
MDB_dbi dbi;
MDB_val mdb_key; MDB_val mdb_key;
MDB_val mdb_value; MDB_val mdb_value;
MDB_val mdb_value_ret; MDB_val mdb_value_ret;
@ -426,21 +370,15 @@ void LMDB::del(const std::string& key) {
goto end_txn; goto end_txn;
} }
rc = mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &dbi);
lmdb_debug(rc, "dbi", "del");
if (rc != 0) {
goto end_dbi;
}
string2val(key, &mdb_key); string2val(key, &mdb_key);
rc = mdb_get(txn, dbi, &mdb_key, &mdb_value_ret); rc = mdb_get(txn, m_dbi, &mdb_key, &mdb_value_ret);
lmdb_debug(rc, "get", "del"); lmdb_debug(rc, "get", "del");
if (rc != 0) { if (rc != 0) {
goto end_get; goto end_get;
} }
rc = mdb_del(txn, dbi, &mdb_key, &mdb_value_ret); rc = mdb_del(txn, m_dbi, &mdb_key, &mdb_value_ret);
lmdb_debug(rc, "del", "del"); lmdb_debug(rc, "del", "del");
if (rc != 0) { if (rc != 0) {
goto end_del; goto end_del;
@ -452,14 +390,12 @@ void LMDB::del(const std::string& key) {
goto end_commit; goto end_commit;
} }
end_commit:
end_del: end_del:
end_get: end_get:
mdb_dbi_close(m_env, dbi);
end_dbi:
if (rc != 0) { if (rc != 0) {
mdb_txn_abort(txn); mdb_txn_abort(txn);
} }
end_commit:
end_txn: end_txn:
return; return;
} }
@ -470,25 +406,18 @@ void LMDB::resolveMultiMatches(const std::string& var,
variables::KeyExclusions &ke) { variables::KeyExclusions &ke) {
MDB_val key, data; MDB_val key, data;
MDB_txn *txn = NULL; MDB_txn *txn = NULL;
MDB_dbi dbi;
int rc; int rc;
MDB_stat mst; MDB_stat mst;
size_t keySize = var.size(); size_t keySize = var.size();
MDB_cursor *cursor; MDB_cursor *cursor;
rc = mdb_txn_begin(m_env, NULL, 0, &txn); rc = mdb_txn_begin(m_env, NULL, MDB_RDONLY, &txn);
lmdb_debug(rc, "txn", "resolveMultiMatches"); lmdb_debug(rc, "txn", "resolveMultiMatches");
if (rc != 0) { if (rc != 0) {
goto end_txn; goto end_txn;
} }
rc = mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &dbi); rc = mdb_cursor_open(txn, m_dbi, &cursor);
lmdb_debug(rc, "dbi", "resolveMultiMatches");
if (rc != 0) {
goto end_dbi;
}
rc = mdb_cursor_open(txn, dbi, &cursor);
lmdb_debug(rc, "cursor_open", "resolveMultiMatches"); lmdb_debug(rc, "cursor_open", "resolveMultiMatches");
if (rc != 0) { if (rc != 0) {
goto end_cursor_open; goto end_cursor_open;
@ -519,8 +448,6 @@ void LMDB::resolveMultiMatches(const std::string& var,
mdb_cursor_close(cursor); mdb_cursor_close(cursor);
end_cursor_open: end_cursor_open:
mdb_dbi_close(m_env, dbi);
end_dbi:
mdb_txn_abort(txn); mdb_txn_abort(txn);
end_txn: end_txn:
return; return;
@ -532,26 +459,19 @@ void LMDB::resolveRegularExpression(const std::string& var,
variables::KeyExclusions &ke) { variables::KeyExclusions &ke) {
MDB_val key, data; MDB_val key, data;
MDB_txn *txn = NULL; MDB_txn *txn = NULL;
MDB_dbi dbi;
int rc; int rc;
MDB_stat mst; MDB_stat mst;
MDB_cursor *cursor; MDB_cursor *cursor;
Utils::Regex r(var, true); Utils::Regex r(var, true);
rc = mdb_txn_begin(m_env, NULL, 0, &txn); rc = mdb_txn_begin(m_env, NULL, MDB_RDONLY, &txn);
lmdb_debug(rc, "txn", "resolveRegularExpression"); lmdb_debug(rc, "txn", "resolveRegularExpression");
if (rc != 0) { if (rc != 0) {
goto end_txn; goto end_txn;
} }
rc = mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &dbi); rc = mdb_cursor_open(txn, m_dbi, &cursor);
lmdb_debug(rc, "dbi", "resolveRegularExpression");
if (rc != 0) {
goto end_dbi;
}
rc = mdb_cursor_open(txn, dbi, &cursor);
lmdb_debug(rc, "cursor_open", "resolveRegularExpression"); lmdb_debug(rc, "cursor_open", "resolveRegularExpression");
if (rc != 0) { if (rc != 0) {
goto end_cursor_open; goto end_cursor_open;
@ -578,8 +498,6 @@ void LMDB::resolveRegularExpression(const std::string& var,
mdb_cursor_close(cursor); mdb_cursor_close(cursor);
end_cursor_open: end_cursor_open:
mdb_dbi_close(m_env, dbi);
end_dbi:
mdb_txn_abort(txn); mdb_txn_abort(txn);
end_txn: end_txn:
return; return;

View File

@ -79,6 +79,7 @@ class LMDB :
void inline lmdb_debug(int rc, std::string op, std::string scope); void inline lmdb_debug(int rc, std::string op, std::string scope);
MDB_env *m_env; MDB_env *m_env;
MDB_dbi m_dbi;
}; };
} // namespace backend } // namespace backend