All pastes #87354 Raw Edit

nanardon

public text v1 · immutable
·published 2006-07-13 21:49 UTC
rendered paste body
Index: rpmdb/db3.c
===================================================================
--- rpmdb/db3.c
+++ rpmdb/db3.c	2006-07-13 23:34:53.513448569 +0200
@@ -77,6 +77,77 @@
 };
 /*@=fielduse@*/
 
+/*@unchecked@*/ /*@only@*/ /*@null@*/
+static const char * db3Cwd = NULL;
+/*@unchecked@*/
+static int db3InRoot = 0;
+
+static void enterChroot(dbiIndex dbi)
+	/*@globals db3Cwd, db3InRoot, internalState @*/
+	/*@modifies db3Cwd, db3InRoot, internalState @*/
+{
+    char * currDir = NULL; 
+    int xx;
+    char * root = NULL;
+    root = (dbi->dbi_root ? dbi->dbi_root : dbi->dbi_rpmdb->db_root);
+if(_debug)
+fprintf(stderr, "try to chroot(%s) %d\n", root, db3InRoot);
+
+    if ((root[0] == '/' && root[1] == '\0') || dbi->dbi_rpmdb->db_chrootDone || db3InRoot)
+       /* Nothing to do, was not already in chroot */
+       return;
+
+if (_debug)
+fprintf(stderr, "db3:chroot(%s)\n", root);
+
+    {
+      int currDirLen = 0;
+
+      do {
+        currDirLen += 128;
+        currDir = xrealloc(currDir, currDirLen);
+        memset(currDir, 0, currDirLen);
+      } while (getcwd(currDir, currDirLen) == NULL && errno == ERANGE);
+    }
+
+    db3Cwd = currDir;
+    xx = chdir("/");
+/*@-superuser@*/
+    xx = chroot(root);
+/*@=superuser@*/
+assert(xx == 0);
+    db3InRoot=1;
+}
+
+static void leaveChroot(dbiIndex dbi)
+	/*@globals db3Cwd, db3InRoot, internalState @*/
+	/*@modifies db3Cwd, db3InRoot, internalState @*/
+{
+    int xx;
+    char * root = NULL;
+
+    root = (dbi->dbi_root ? dbi->dbi_root : dbi->dbi_rpmdb->db_root);
+
+
+    if ((root[0] == '/' && root[1] == '\0') || dbi->dbi_rpmdb->db_chrootDone || !db3InRoot)
+       /* Nothing to do, not in chroot */
+       return;
+
+if (_debug)
+fprintf(stderr, "db3:chroot(.)\n");
+
+/*@-superuser@*/
+    xx = chroot(".");
+/*@=superuser@*/
+assert(xx == 0);
+    if (db3Cwd != NULL) {
+	xx = chdir(db3Cwd);
+	db3Cwd = _free(db3Cwd);
+    }
+
+    db3InRoot = 0;
+}
+
 #ifdef	NOTNOW
 static const char * bfstring(unsigned int x, const char * xbf)
 {
@@ -183,6 +254,8 @@
     if (dbenv == NULL)
 	return 0;
 
+    enterChroot(dbi);
+
     rc = dbenv->close(dbenv, 0);
     rc = cvtdberr(dbi, "dbenv->close", rc, _debug);
 
@@ -209,6 +282,7 @@
 			dbhome, dbfile);
 
     }
+    leaveChroot(dbi);
     return rc;
 }
 
@@ -295,6 +369,8 @@
     eflags = (dbi->dbi_oeflags | dbi->dbi_eflags);
     if (eflags & DB_JOINENV) eflags &= DB_JOINENV;
 
+    enterChroot(dbi);
+
     if (dbfile)
 	rpmMessage(RPMMESS_DEBUG, _("opening  db environment %s/%s %s\n"),
 		dbhome, dbfile, prDbiOpenFlags(eflags, 1));
@@ -377,10 +453,13 @@
 	    const char * root;
 	    const char * tmpdir;
 
+#if 0
 	    root = (dbi->dbi_root ? dbi->dbi_root : rpmdb->db_root);
 /*@-boundsread@*/
 	    if ((root[0] == '/' && root[1] == '\0') || rpmdb->db_chrootDone)
 		root = NULL;
+#endif
+        root = NULL;
 /*@=boundsread@*/
 /*@-mods@*/
 	    tmpdir = rpmGenPath(root, dbi->dbi_tmpdir, NULL);
@@ -442,7 +521,7 @@
 /*@-boundswrite@*/
     *dbenvp = dbenv;
 /*@=boundswrite@*/
-
+    leaveChroot(dbi);
     return 0;
 
 errxit:
@@ -451,6 +530,7 @@
 	xx = dbenv->close(dbenv, 0);
 	xx = cvtdberr(dbi, "dbenv->close", xx, _debug);
     }
+    leaveChroot(dbi);
     return rc;
 }
 /*@=moduncon@*/
@@ -463,6 +543,8 @@
     int rc = 0;
     int _printit;
 
+    enterChroot(dbi);
+
     if (db != NULL)
 	rc = db->sync(db, flags);
     /* XXX DB_INCOMPLETE is returned occaisionally with multiple access. */
@@ -472,6 +554,7 @@
     _printit = (rc == DB_INCOMPLETE ? 0 : _debug);
 #endif
     rc = cvtdberr(dbi, "db->sync", rc, _printit);
+    leaveChroot(dbi);
     return rc;
 }
 
@@ -481,13 +564,14 @@
 	/*@modifies *dbcp, fileSystem @*/
 {
     int rc;
-
+    enterChroot(dbi);
 /*@-boundswrite@*/
     if (dbcp) *dbcp = NULL;
 /*@=boundswrite@*/
     rc = dbcursor->c_dup(dbcursor, dbcp, flags);
     rc = cvtdberr(dbi, "dbcursor->c_dup", rc, _debug);
     /*@-nullstate @*/ /* FIX: *dbcp can be NULL */
+    leaveChroot(dbi);
     return rc;
     /*@=nullstate @*/
 }
@@ -500,11 +584,13 @@
 {
     int rc = -2;
 
+    enterChroot(dbi);
     /* XXX db3copen error pathways come through here. */
     if (dbcursor != NULL) {
 	rc = dbcursor->c_close(dbcursor);
 	rc = cvtdberr(dbi, "dbcursor->c_close", rc, _debug);
     }
+    leaveChroot(dbi);
     return rc;
 }
 /*@=mustmod@*/
@@ -519,8 +605,12 @@
     int flags;
     int rc;
 
+    if(_debug)
+        fprintf(stderr, "db3copen %d\n", __LINE__);
+
    /* XXX DB_WRITECURSOR cannot be used with sunrpc dbenv. */
     assert(db != NULL);
+    enterChroot(dbi);
     if ((dbiflags & DB_WRITECURSOR) &&
 	(dbi->dbi_eflags & DB_INIT_CDB) && !(dbi->dbi_oflags & DB_RDONLY))
     {
@@ -535,7 +625,8 @@
 	/*@-boundswrite -onlytrans@*/ *dbcp = dbcursor; /*@=boundswrite =onlytrans@*/
     else
 	(void) db3cclose(dbi, dbcursor, 0);
-
+    
+    leaveChroot(dbi);
     return rc;
 }
 
@@ -548,6 +639,7 @@
     int rc;
 
     assert(db != NULL);
+    enterChroot(dbi);
     if (dbcursor == NULL) {
 	rc = db->put(db, dbi->dbi_txnid, key, data, 0);
 	rc = cvtdberr(dbi, "db->put", rc, _debug);
@@ -555,7 +647,7 @@
 	rc = dbcursor->c_put(dbcursor, key, data, DB_KEYLAST);
 	rc = cvtdberr(dbi, "dbcursor->c_put", rc, _debug);
     }
-
+    leaveChroot(dbi);
     return rc;
 }
 
@@ -569,6 +661,7 @@
     int rc;
 
     assert(db != NULL);
+    enterChroot(dbi);
     if (dbcursor == NULL) {
 	rc = db->del(db, dbi->dbi_txnid, key, flags);
 	rc = cvtdberr(dbi, "db->del", rc, _debug);
@@ -587,6 +680,7 @@
 	}
     }
 
+    leaveChroot(dbi);
     return rc;
 }
 /*@=mustmod@*/
@@ -602,6 +696,7 @@
     int rc;
 
     assert(db != NULL);
+    enterChroot(dbi);
     if (dbcursor == NULL) {
 	/* XXX duplicates require cursors. */
 	rc = db->get(db, dbi->dbi_txnid, key, data, 0);
@@ -616,6 +711,7 @@
 	rc = cvtdberr(dbi, "dbcursor->c_get", rc, _printit);
     }
 
+    leaveChroot(dbi);
     return rc;
 }
 /*@=mustmod@*/
@@ -633,12 +729,14 @@
     assert(db != NULL);
     assert(dbcursor != NULL);
 
+    enterChroot(dbi);
     /* XXX db3 does DB_FIRST on uninitialized cursor */
     rc = dbcursor->c_pget(dbcursor, key, pkey, data, flags);
     /* XXX DB_NOTFOUND can be returned */
     _printit = (rc == DB_NOTFOUND ? 0 : _debug);
     rc = cvtdberr(dbi, "dbcursor->c_pget", rc, _printit);
 
+    leaveChroot(dbi);
     return rc;
 }
 /*@=mustmod@*/
@@ -653,8 +751,10 @@
     int rc = 0;
 
     flags = 0;
+    enterChroot(dbi);
     rc = dbcursor->c_count(dbcursor, &count, flags);
     rc = cvtdberr(dbi, "dbcursor->c_count", rc, _debug);
+    leaveChroot(dbi);
     if (rc) return rc;
 /*@-boundswrite@*/
     if (countp) *countp = count;
@@ -668,6 +768,7 @@
     DB * db = dbi->dbi_db;
     int rc = 0;
 
+    enterChroot(dbi);
     if (db != NULL) {
 #if (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 3 && DB_VERSION_PATCH == 11) \
  || (DB_VERSION_MAJOR == 4)
@@ -680,6 +781,7 @@
 #endif
     }
 
+    leaveChroot(dbi);
     return rc;
 }
 
@@ -694,6 +796,7 @@
     int rc = 0;
 
     assert(db != NULL);
+    enterChroot(dbi);
 #if defined(DB_FAST_STAT)
     if (flags)
 	flags = DB_FAST_STAT;
@@ -712,6 +815,7 @@
     rc = db->stat(db, &dbi->dbi_stats, NULL, flags);
 #endif
     rc = cvtdberr(dbi, "db->stat", rc, _debug);
+    leaveChroot(dbi);
     return rc;
 }
 
@@ -726,6 +830,7 @@
     DB * secondary = dbisecondary->dbi_db;
     int rc;
 
+    enterChroot(dbi);
 /*@-moduncon@*/ /* FIX: annotate db3 methods */
 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
     DB_TXN * txnid = NULL;
@@ -738,6 +843,7 @@
 #endif
 /*@=moduncon@*/
     rc = cvtdberr(dbi, "db->associate", rc, _debug);
+    leaveChroot(dbi);
     return rc;
 }
 /*@=mustmod@*/
@@ -752,10 +858,12 @@
     int rc;
 
 assert(db != NULL);
+    enterChroot(dbi);
 /*@-moduncon@*/ /* FIX: annotate db3 methods */
     rc = db->join(db, curslist, dbcp, flags);
 /*@=moduncon@*/
     rc = cvtdberr(dbi, "db->join", rc, _debug);
+    leaveChroot(dbi);
     return rc;
 }
 /*@=mustmod@*/
@@ -782,13 +890,16 @@
     /*
      * Get the prefix/root component and directory path.
      */
+#if 0
     root = (dbi->dbi_root ? dbi->dbi_root : rpmdb->db_root);
 /*@-boundsread@*/
     if ((root[0] == '/' && root[1] == '\0') || rpmdb->db_chrootDone)
+#endif
 	root = NULL;
 /*@=boundsread@*/
     home = (dbi->dbi_home ? dbi->dbi_home : rpmdb->db_home);
 
+    enterChroot(dbi);
     /*
      * Either the root or directory components may be a URL. Concatenate,
      * convert the URL to a path, and add the name of the file.
@@ -903,6 +1014,7 @@
     }
 
 exit:
+    leaveChroot(dbi);
     dbi->dbi_db = NULL;
 
     urlfn = _free(urlfn);
@@ -943,7 +1055,8 @@
     if (dbip)
 	*dbip = NULL;
 /*@=boundswrite@*/
-
+    if(_debug)
+        fprintf(stderr, "db3open %d\n", __LINE__);
     /*
      * Parse db configuration parameters.
      */
@@ -958,10 +1071,14 @@
     /*
      * Get the prefix/root component and directory path.
      */
+#if 0
     root = (dbi->dbi_root ? dbi->dbi_root : rpmdb->db_root);
 /*@-boundsread@*/
     if ((root[0] == '/' && root[1] == '\0') || rpmdb->db_chrootDone)
+#endif
 	root = NULL;
+
+    enterChroot(dbi);
 /*@=boundsread@*/
     home = (dbi->dbi_home ? dbi->dbi_home : rpmdb->db_home);
 
@@ -1160,6 +1277,7 @@
 	/*@=mods@*/
     }
 
+    enterChroot(dbi);
     rpmMessage(RPMMESS_DEBUG, _("opening  db index       %s/%s %s mode=0x%x\n"),
 		dbhome, (dbfile ? dbfile : tagName(dbi->dbi_rpmtag)),
 		prDbiOpenFlags(oflags, 0), dbi->dbi_mode);
@@ -1430,6 +1548,7 @@
 
     urlfn = _free(urlfn);
 
+    leaveChroot(dbi);
     /*@-nullstate -compmempass@*/
     return rc;
     /*@=nullstate =compmempass@*/