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@*/