From 204908cf5084b95c5c2551d4103a344d78c4bd39 Mon Sep 17 00:00:00 2001 From: Danila Vershinin Date: Thu, 9 Jun 2022 18:10:26 +0300 Subject: [PATCH] Prevent segfault for #2755 Make transactions no-op if the file handle is invalid --- src/collection/backend/lmdb.cc | 26 ++++++++++++++++++++------ src/collection/backend/lmdb.h | 3 +++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/collection/backend/lmdb.cc b/src/collection/backend/lmdb.cc index 2e512fa1..1ffca80a 100644 --- a/src/collection/backend/lmdb.cc +++ b/src/collection/backend/lmdb.cc @@ -46,7 +46,12 @@ int LMDB::txn_begin(unsigned int flags, MDB_txn **ret) { m_dbi = *(MDBEnvProvider::GetInstance().GetDBI()); isOpen = true; } - return mdb_txn_begin(m_env, NULL, flags, ret); + + if (MDBEnvProvider::GetInstance().isValid()) { + return mdb_txn_begin(m_env, NULL, flags, ret); + } else { + return -1; + } } void LMDB::string2val(const std::string& str, MDB_val *val) { @@ -501,14 +506,19 @@ end_txn: } -MDBEnvProvider::MDBEnvProvider() : m_env(NULL) { +MDBEnvProvider::MDBEnvProvider() : m_env(NULL), valid(false) { + int rc; MDB_txn *txn; mdb_env_create(&m_env); - mdb_env_open(m_env, "./modsec-shared-collections", + rc = mdb_env_open(m_env, "./modsec-shared-collections", 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); + + if (rc == 0) { + valid = true; + mdb_txn_begin(m_env, NULL, 0, &txn); + mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &m_dbi); + mdb_txn_commit(txn); + } } MDB_env* MDBEnvProvider::GetEnv() { @@ -519,6 +529,10 @@ MDB_dbi* MDBEnvProvider::GetDBI() { return &m_dbi; } +bool MDBEnvProvider::isValid() { + return valid; +} + MDBEnvProvider::~MDBEnvProvider() { mdb_dbi_close(m_env, m_dbi); mdb_env_close(m_env); diff --git a/src/collection/backend/lmdb.h b/src/collection/backend/lmdb.h index 933f88c7..3baa9145 100644 --- a/src/collection/backend/lmdb.h +++ b/src/collection/backend/lmdb.h @@ -83,10 +83,13 @@ class MDBEnvProvider { } MDB_env* GetEnv(); MDB_dbi* GetDBI(); + bool isValid(); + ~MDBEnvProvider(); private: MDB_env *m_env; MDB_dbi m_dbi; + bool valid; MDBEnvProvider(); };