From 3cfd298e9d03a7867118326fc60cc86fd7ea9b73 Mon Sep 17 00:00:00 2001
From: Michael Schroeder <mls@suse.de>
Date: Tue, 14 Apr 2020 10:58:34 +0200
Subject: [PATCH] ndb: do not map the index databases read-write all the time

Pass the flags to rpmidxOpenXdb and use read only mode if the
user specified O_RDONLY. We already did that for rpmidxOpen in
the past but we always used read-write mode when using the Xdb.

We still open the Xdb itself in read-write mode so that we can
regenerate missing index databases.

URL:https://github.com/rpm-software-management/rpm/commit/3cfd298e9d03a7867118326fc60cc86fd7ea9b73
---
 lib/backend/ndb/glue.c   | 11 ++++-------
 lib/backend/ndb/rpmidx.c |  8 ++++++--
 lib/backend/ndb/rpmidx.h |  2 +-
 3 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/lib/backend/ndb/glue.c b/lib/backend/ndb/glue.c
index f69a46e..2bdfecc 100644
--- a/lib/backend/ndb/glue.c
+++ b/lib/backend/ndb/glue.c
@@ -147,9 +147,6 @@ static int ndb_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags)
 	free(path);
 	dbi->dbi_db = ndbenv->pkgdb = pkgdb;
 	rpmpkgSetFsync(pkgdb, ndbenv->dofsync);
-
-	if ((oflags & (O_RDWR | O_RDONLY)) == O_RDONLY)
-	    dbi->dbi_flags |= DBI_RDONLY;
     } else {
 	unsigned int id;
 	rpmidxdb idxdb = 0;
@@ -188,20 +185,20 @@ static int ndb_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags)
 		ndb_CheckIndexSync(ndbenv->pkgdb, ndbenv->xdb);
 	}
 	if (rpmxdbLookupBlob(ndbenv->xdb, &id, rpmtag, 0, 0) == RPMRC_NOTFOUND) {
+	    oflags = O_RDWR|O_CREAT;
 	    dbi->dbi_flags |= DBI_CREATED;
 	}
 	rpmlog(RPMLOG_DEBUG, "opening  db index       %s tag=%d\n", dbiName(dbi), rpmtag);
-	if (rpmidxOpenXdb(&idxdb, rdb->db_pkgs->dbi_db, ndbenv->xdb, rpmtag)) {
+	if (rpmidxOpenXdb(&idxdb, rdb->db_pkgs->dbi_db, ndbenv->xdb, rpmtag, oflags)) {
 	    perror("rpmidxOpenXdb");
 	    ndb_Close(dbi, 0);
 	    return 1;
 	}
 	dbi->dbi_db = idxdb;
-
-	if (rpmxdbIsRdonly(ndbenv->xdb))
-	    dbi->dbi_flags |= DBI_RDONLY;
     }
 
+    if ((oflags & (O_RDWR | O_RDONLY)) == O_RDONLY)
+	dbi->dbi_flags |= DBI_RDONLY;
 
     if (dbip != NULL)
 	*dbip = dbi;
diff --git a/lib/backend/ndb/rpmidx.c b/lib/backend/ndb/rpmidx.c
index 0ec8c8d..90b22d5 100644
--- a/lib/backend/ndb/rpmidx.c
+++ b/lib/backend/ndb/rpmidx.c
@@ -885,13 +885,17 @@ int rpmidxOpen(rpmidxdb *idxdbp, rpmpkgdb pkgdb, const char *filename, int flags
     return RPMRC_FAIL;
 }
 
-int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmpkgdb pkgdb, rpmxdb xdb, unsigned int xdbtag)
+int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmpkgdb pkgdb, rpmxdb xdb, unsigned int xdbtag, int flags)
 {
     rpmidxdb idxdb;
     unsigned int id;
     *idxdbp = 0;
     int rc;
     
+    if (rpmxdbIsRdonly(xdb) && (flags & (O_RDONLY|O_RDWR)) != O_RDONLY) {
+	errno = EACCES;
+	return RPMRC_FAIL;
+    }
     if (rpmxdbLock(xdb, 0))
 	return RPMRC_FAIL;
     rc = rpmxdbLookupBlob(xdb, &id, xdbtag, IDXDB_XDB_SUBTAG, 0);
@@ -907,7 +911,7 @@ int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmpkgdb pkgdb, rpmxdb xdb, unsigned int xdb
     idxdb->xdbid = id;
     idxdb->pkgdb = pkgdb;
     idxdb->pagesize = rpmxdbPagesize(xdb);
-    idxdb->rdonly = rpmxdbIsRdonly(xdb) ? 1 : 0;
+    idxdb->rdonly = (flags & (O_RDONLY|O_RDWR)) == O_RDONLY ? 1 : 0;
     if (!id) {
 	if (rpmidxInit(idxdb)) {
 	    free(idxdb);
diff --git a/lib/backend/ndb/rpmidx.h b/lib/backend/ndb/rpmidx.h
index e89bd82..9b01fb9 100644
--- a/lib/backend/ndb/rpmidx.h
+++ b/lib/backend/ndb/rpmidx.h
@@ -5,7 +5,7 @@ struct rpmidxdb_s;
 typedef struct rpmidxdb_s *rpmidxdb;
 
 int rpmidxOpen(rpmidxdb *idxdbp, rpmpkgdb pkgdb, const char *filename, int flags, int mode);
-int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmpkgdb pkgdb, rpmxdb xdb, unsigned int xdbtag);
+int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmpkgdb pkgdb, rpmxdb xdb, unsigned int xdbtag, int flags);
 int rpmidxDelXdb(rpmpkgdb pkgdb, rpmxdb xdb, unsigned int xdbtag);
 void rpmidxClose(rpmidxdb idxdbp);
 
-- 
1.8.3.1

