From 9529598aa903ac427d65592b2ff71023b760460c Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Sat, 2 Dec 2006 15:21:14 +0000 Subject: [PATCH] Merged from trunk 5149:5157 Always verify the ebuild checksums before executing it. Thanks to solar for the suggestion and antarus for the initial patch. For manifest and digest phases, use a global variable to temporarily exempt the depend phase from manifest checks (in cache regeneration is triggered). Temporarily exempt the depend phase during the help phase also. Avoid checking the same Manifest several times in a row during a regen with an empty cache. For consistent behavior in all timezones, make emerge-webrsync use UTC time for decisions about which snapshots to download. Only attempt to verify the Manifest if the ebuild is actually in a portage tree. Make sure that *all* of the ebuilds are listed in the Manifest. Make sure that all depend phases triggered by the digest phase are exempt from digest checks. svn path=/main/branches/prefix/; revision=5158 --- bin/emerge-webrsync | 23 +++++------ pym/portage.py | 98 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 86 insertions(+), 35 deletions(-) diff --git a/bin/emerge-webrsync b/bin/emerge-webrsync index 8e9bb44c4..b6d8e130a 100755 --- a/bin/emerge-webrsync +++ b/bin/emerge-webrsync @@ -84,21 +84,20 @@ sync_local() { echo "Fetching most recent snapshot" -declare -i attempts=-1 +declare -i attempts=0 while (( $attempts < 40 )) ; do attempts=$(( attempts + 1 )) - #this too, sucks. it works in the interim though. - if [ "$USERLAND" == "BSD" ] || [ "$USERLAND" == "Darwin" ] ; then - daysbefore=$(expr $(date +"%s") - 86400 \* $attempts) - day=$(date -r $daysbefore +"%d") - month=$(date -r $daysbefore +"%m") - year=$(date -r $daysbefore +"%Y") - else - day=$(date -d "-$attempts day" +"%d") - month=$(date -d "-$attempts day" +"%m") - year=$(date -d "-$attempts day" +"%Y") - fi + # The snapshot for a given day is generated at 01:45 UTC on the following + # day, so the current day's snapshot (going by UTC time) hasn't been + # generated yet. Therefore, always start by looking for the previous day's + # snapshot (for attempts=1, subtract 1 day from the current UTC time). + daysbefore=$(expr $(date -u +"%s") - 86400 \* ${attempts}) + DATE_ARGS="-d @${daysbefore}" + [ "${USERLAND}" != "GNU" ] && DATE_ARGS="-r ${daysbefore}" + day=$(date ${DATE_ARGS} -u +"%d") + month=$(date ${DATE_ARGS} -u +"%m") + year=$(date ${DATE_ARGS} -u +"%Y") FILE_ORIG="portage-${year}${month}${day}.tar.bz2" diff --git a/pym/portage.py b/pym/portage.py index 4f980a18b..45d5b3f7f 100644 --- a/pym/portage.py +++ b/pym/portage.py @@ -2978,6 +2978,9 @@ def prepare_build_dirs(myroot, mysettings, cleanup): (mysettings["CATEGORY"], mysettings["PF"], logid_time)) del logid_path, logid_time +_doebuild_manifest_exempt_depend = False +_doebuild_manifest_checked = None + def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, fetchonly=0, cleanup=0, dbkey=None, use_cache=1, fetchall=0, tree=None, mydbapi=None, vartree=None, prev_mtimes=None): @@ -3014,34 +3017,78 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, noiselevel=-1) return 1 - doebuild_environment(myebuild, mydo, myroot, mysettings, debug, - use_cache, mydbapi) - - # get possible slot information from the deps file - if mydo=="depend": - if mysettings.has_key("PORTAGE_DEBUG") and mysettings["PORTAGE_DEBUG"]=="1": - # XXX: This needs to use a FD for saving the output into a file. - # XXX: Set this up through spawn - pass - writemsg("!!! DEBUG: dbkey: %s\n" % str(dbkey), 2) - if dbkey: - mysettings["dbkey"] = dbkey - else: - mysettings["dbkey"] = mysettings.depcachedir+"/aux_db_key_temp" - - retval = spawn(EBUILD_SH_BINARY+" depend",mysettings) - return retval + global _doebuild_manifest_exempt_depend - if not os.path.isdir(mysettings["PORTAGE_TMPDIR"]): - writemsg("The directory specified in your PORTAGE_TMPDIR variable, '%s',\n" % \ - mysettings["PORTAGE_TMPDIR"], noiselevel=-1) - writemsg("does not exist. Please create this directory or correct your PORTAGE_TMPDIR setting.\n", - noiselevel=-1) - return 1 + if "strict" in features and \ + tree == "porttree" and \ + mydo not in ("digest", "manifest", "help") and \ + not _doebuild_manifest_exempt_depend: + # Always verify the ebuild checksums before executing it. + pkgdir = os.path.dirname(myebuild) + manifest_path = os.path.join(pkgdir, "Manifest") + global _doebuild_manifest_checked + # Avoid checking the same Manifest several times in a row during a + # regen with an empty cache. + if _doebuild_manifest_checked != manifest_path: + if not os.path.exists(manifest_path): + writemsg("!!! Manifest file not found: '%s'\n" % manifest_path, + noiselevel=-1) + return 1 + mf = Manifest(pkgdir, mysettings["DISTDIR"]) + try: + mf.checkTypeHashes("EBUILD") + except portage_exception.FileNotFound, e: + writemsg("!!! A file listed in the Manifest " + \ + "could not be found: %s\n" % str(e), noiselevel=-1) + return 1 + except portage_exception.DigestException, e: + writemsg("!!! Digest verification failed:\n", noiselevel=-1) + writemsg("!!! %s\n" % e.value[0], noiselevel=-1) + writemsg("!!! Reason: %s\n" % e.value[1], noiselevel=-1) + writemsg("!!! Got: %s\n" % e.value[2], noiselevel=-1) + writemsg("!!! Expected: %s\n" % e.value[3], noiselevel=-1) + return 1 + # Make sure that all of the ebuilds are actually listed in the + # Manifest. + for f in os.listdir(pkgdir): + if f.endswith(".ebuild") and not mf.hasFile("EBUILD", f): + writemsg("!!! A file is not listed in the " + \ + "Manifest: '%s'\n" % os.path.join(pkgdir, f), + noiselevel=-1) + return 1 + _doebuild_manifest_checked = manifest_path logfile=None builddir_lock = None try: + if mydo in ("digest", "manifest", "help"): + # Temporarily exempt the depend phase from manifest checks, in case + # aux_get calls trigger cache generation. + _doebuild_manifest_exempt_depend = True + + doebuild_environment(myebuild, mydo, myroot, mysettings, debug, + use_cache, mydbapi) + + # get possible slot information from the deps file + if mydo == "depend": + writemsg("!!! DEBUG: dbkey: %s\n" % str(dbkey), 2) + if dbkey: + mysettings["dbkey"] = dbkey + else: + mysettings["dbkey"] = \ + os.path.join(mysettings.depcachedir, "aux_db_key_temp") + + return spawn(EBUILD_SH_BINARY + " depend", mysettings) + + if "PORTAGE_TMPDIR" not in mysettings or \ + not os.path.isdir(mysettings["PORTAGE_TMPDIR"]): + writemsg("The directory specified in your " + \ + "PORTAGE_TMPDIR variable, '%s',\n" % \ + mysettings.get("PORTAGE_TMPDIR", ""), noiselevel=-1) + writemsg("does not exist. Please create this directory or " + \ + "correct your PORTAGE_TMPDIR setting.\n", noiselevel=-1) + return 1 + # Build directory creation isn't required for any of these. if mydo not in ["fetch","digest","manifest"]: mystatus = prepare_build_dirs(myroot, mysettings, cleanup) @@ -3312,6 +3359,11 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, except OSError: pass + if mydo in ("digest", "manifest", "help"): + # If necessary, depend phase has been triggered by aux_get calls + # and the exemption is no longer needed. + _doebuild_manifest_exempt_depend = False + expandcache={} def movefile(src,dest,newmtime=None,sstat=None,mysettings=None): -- 2.26.2