From: Gary Lockyer Date: Tue, 13 Mar 2018 02:08:10 +0000 (+1300) Subject: ldb_mdb: prevent MDB_env reuse across forks X-Git-Tag: ldb-1.4.0~101 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=322e42818b144249084dc3a8d4f7988cd8fcab3e;p=thirdparty%2Fsamba.git ldb_mdb: prevent MDB_env reuse across forks MDB_env's may not be reused accross forks. Check the pid that the lmdb structure was created by, and return an error if it is being used by a different process. Signed-off-by: Gary Lockyer Reviewed-by: Andrew Bartlett Reviewed-by: Garming Sam --- diff --git a/lib/ldb/ldb_mdb/ldb_mdb.c b/lib/ldb/ldb_mdb/ldb_mdb.c index 857801a833a..9364970f3f3 100644 --- a/lib/ldb/ldb_mdb/ldb_mdb.c +++ b/lib/ldb/ldb_mdb/ldb_mdb.c @@ -443,6 +443,18 @@ static int lmdb_lock_read(struct ldb_module *module) void *data = ldb_module_get_private(module); struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); struct lmdb_private *lmdb = ltdb->lmdb_private; + pid_t pid = getpid(); + + if (pid != lmdb->pid) { + ldb_asprintf_errstring( + lmdb->ldb, + __location__": Reusing ldb opened by pid %d in " + "process %d\n", + lmdb->pid, + pid); + lmdb->error = MDB_BAD_TXN; + return LDB_ERR_PROTOCOL_ERROR; + } lmdb->error = MDB_SUCCESS; if (lmdb_transaction_active(ltdb) == false && @@ -482,6 +494,7 @@ static int lmdb_transaction_start(struct ltdb_private *ltdb) struct lmdb_trans *ltx; struct lmdb_trans *ltx_head; MDB_txn *tx_parent; + pid_t pid = getpid(); /* Do not take out the transaction lock on a read-only DB */ if (ltdb->read_only) { @@ -493,6 +506,18 @@ static int lmdb_transaction_start(struct ltdb_private *ltdb) return ldb_oom(lmdb->ldb); } + if (pid != lmdb->pid) { + ldb_asprintf_errstring( + lmdb->ldb, + __location__": Reusing ldb opened by pid %d in " + "process %d\n", + lmdb->pid, + pid); + lmdb->error = MDB_BAD_TXN; + return LDB_ERR_PROTOCOL_ERROR; + } + + ltx_head = lmdb_private_trans_head(lmdb); tx_parent = lmdb_trans_get_tx(ltx_head); @@ -660,7 +685,7 @@ struct mdb_env_wrap { dev_t device; ino_t inode; MDB_env *env; - int pid; + pid_t pid; }; static struct mdb_env_wrap *mdb_list; @@ -689,10 +714,13 @@ static int lmdb_open_env(TALLOC_CTX *mem_ctx, struct mdb_env_wrap *w; struct stat st; + pid_t pid = getpid(); if (stat(path, &st) == 0) { for (w=mdb_list;w;w=w->next) { - if (st.st_dev == w->device && st.st_ino == w->inode) { + if (st.st_dev == w->device && + st.st_ino == w->inode && + pid == w->pid) { /* * We must have only one MDB_env per process */ @@ -765,6 +793,7 @@ static int lmdb_open_env(TALLOC_CTX *mem_ctx, w->env = *env; w->device = st.st_dev; w->inode = st.st_ino; + w->pid = pid; talloc_set_destructor(w, mdb_env_wrap_destructor);