From 192e89881f1a1b1da97b43d166336097981ca8b8 Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Sat, 8 Dec 2007 16:28:14 +0000 Subject: [PATCH] Merged from trunk 8843:8867 | 8844 | In order to know exactly which atoms/sets should be added to | | zmedico | the world file, the depgraph performs set expansion later. | | | It will get confused about where the atoms came from if it's | | | not allowed to expand them itself. | | 8845 | bootstrap.sh expects that the "system" set always exists, so | | zmedico | create it automatically if necessary. | | 8846 | Show ? if the installed package is missing a repository | | zmedico | label. The stable version of portage creates these labels | | | now, so false positives won't be as common as they used to | | | be. | | 8848 | - repository configuration file and `emerge --sync | | zmedico | [repo_set]... [repo]...` support for overlays and binhosts | | | (zmedico) | | 8849 | Make SetConfig.getSets() return a copy of the psets | | zmedico | attribute instead of a direct reference. Fix the to stop | | | relying on having the direct reference. | | 8850 | Keep the RootConfig.sets attribute in sync with the | | zmedico | SetConfig. | | 8851 | Fix broken timestamp logic in do_snapshot(). Thanks to Alon | | zmedico | Bar-Lev for this patch. | | 8852 | Remove redundant successful exit call from the "depend" | | zmedico | phase and let it run to the bottom of ebuild.sh just like | | | the other phases. | | 8853 | Bug #201506 - Make preprocess_ebuild_env() preserve | | zmedico | SANDBOX_{DENY,PREDICT,READ,WRITE} between all phases, except | | | when the environment comes directly from environment.bz2. | | 8857 | Prevent the filter_opts local variable from leaking into the | | zmedico | environment in preprocess_ebuild_env(). | | 8859 | Declare retval as a local variable. | | zmedico | | | 8861 | Bug #201513 - Fix typos for preserve-libs and | | zmedico | PreservedLibraryConsumerSet. Thanks to Arfrever Frehtes | | | Taifersar Arahesis for this patch. | | 8862 | Remove automatic "system" and "world" set creation since we | | zmedico | can probably rely on having a complete config. | | 8863 | Perform set argument validation in emerge_main() even for | | zmedico | values actions that need to expland sets themselves. | | 8864 | Add a TODO note about remaining work for bug #189417. | | zmedico | | | 8865 | Bug #189417 - Explicitly whitelist any remaining variables | | zmedico | that are allowed to leak into the ebuild environment. Also, | | | fix spawnebuild to properly filter the env when it spawns | | | misc-functions.sh after the install phase. There is still | | | some remaining leakage that seems to come from something in | | | the ebuild environment sourcing /etc/profile. | | 8866 | Bug #189417 - Whitelist BASH_ENV since we need to have it | | zmedico | set in order to prevent sandbox from causing env leakage by | | | sourcing /etc/profile via it's bashrc. | | 8867 | Bug #189417 - Comment on how the whitelist and BASH_ENV are | | zmedico | used to prevent environment leakage. | svn path=/main/branches/prefix/; revision=8869 --- TODO | 2 ++ bin/ebuild.sh | 29 ++++++++++-------- bin/emerge-webrsync | 11 ++++--- cnf/sets.conf | 4 +-- pym/_emerge/__init__.py | 31 ++++++++++++-------- pym/portage/__init__.py | 57 ++++++++++++++++++++++++++++-------- pym/portage/sets/__init__.py | 2 +- 7 files changed, 89 insertions(+), 47 deletions(-) diff --git a/TODO b/TODO index 1704a0d27..08f4efebd 100644 --- a/TODO +++ b/TODO @@ -4,5 +4,7 @@ x package set integration in emerge (genone) x user interface for preserve-libs FEATURE (genone, fuzzyray?) x resolve the eselect-news situation (genone) - package set documentation (genone) +- repository configuration file and `emerge --sync [repo_set]... [repo]...` + support for overlays and binhosts (zmedico) (- denotes open/incomplete tasks, x denotes completed tasks) diff --git a/bin/ebuild.sh b/bin/ebuild.sh index cff3591aa..6638740d6 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -1454,12 +1454,17 @@ filter_readonly_variables() { # interfering with the current environment. This is useful when an existing # environment needs to be loaded from a binary or installed package. preprocess_ebuild_env() { - filter_readonly_variables --filter-sandbox < "${T}"/environment \ - > "${T}"/environment.filtered - if [ $? -ne 0 ] ; then - rm -f "${T}/environment.filtered" - return 1 - fi + local filter_opts="" + if [ -f "${T}/environment.raw" ] ; then + # This is a signal from the python side, indicating that the + # environment may contain stale SANDBOX_{DENY,PREDICT,READ,WRITE} + # variables that should be filtered out. Between phases, these + # variables are normally preserved. + filter_opts="--filter-sandbox ${filter_opts}" + fi + filter_readonly_variables ${filter_opts} < "${T}"/environment \ + > "${T}"/environment.filtered || return $? + unset filter_opts mv "${T}"/environment.filtered "${T}"/environment || return $? rm -f "${T}/environment.success" || return $? # WARNING: Code inside this subshell should avoid making assumptions @@ -1480,14 +1485,15 @@ preprocess_ebuild_env() { save_ebuild_env || exit $? touch "${T}/environment.success" || exit $? ) | filter_readonly_variables > "${T}/environment.filtered" + local retval if [ -e "${T}/environment.success" ] ; then - rm "${T}/environment.success" mv "${T}/environment.filtered" "${T}/environment" - return $? + retval=$? else - rm -f "${T}/environment.filtered" + retval=1 fi - return 1 + rm -f "${T}"/environment.{filtered,raw,success} + return ${retval} } # === === === === === === === === === === === === === === === === === === @@ -1780,9 +1786,6 @@ if [ -n "${EBUILD_SH_ARGS}" ] ; then 9>&- fi set +f - [ -n "${EBUILD_EXIT_STATUS_FILE}" ] && \ - touch "${EBUILD_EXIT_STATUS_FILE}" &>/dev/null - exit 0 ;; *) export SANDBOX_ON="1" diff --git a/bin/emerge-webrsync b/bin/emerge-webrsync index 6e5a4d46c..be0acb722 100755 --- a/bin/emerge-webrsync +++ b/bin/emerge-webrsync @@ -61,10 +61,9 @@ get_date_part() { fi } -get_utc_from_string() { +get_utc_second_from_string() { local s="$1" - - seconds=$(date -d "${s:0:4}-${s:4:2}-${s:6:2}" -u +"%s") + date -d "${s:0:4}-${s:4:2}-${s:6:2}" -u +"%s" } get_portage_timestamp() { @@ -241,14 +240,14 @@ do_snapshot() { have_files=0 fi else - utc_date=$(get_utc_from_string "${date}") + local utc_seconds=$(get_utc_second_from_string "${date}") # # Check that this snapshot # is what it claims to be... # - if [ ${snapshot_timestamp} -lt ${seconds} ] || \ - [ ${snapshot_timestamp} -gt $((${seconds}+ 2*86400)) ]; then + if [ ${snapshot_timestamp} -lt ${utc_seconds} ] || \ + [ ${snapshot_timestamp} -gt $((${utc_seconds}+ 2*86400)) ]; then echo "Warning: Snapshot timestamp is not in acceptable period." have_files=0 diff --git a/cnf/sets.conf b/cnf/sets.conf index 47ff265f9..46d7c769f 100644 --- a/cnf/sets.conf +++ b/cnf/sets.conf @@ -34,6 +34,6 @@ multiset = true directory = @DOMAIN_PREFIX@/etc/portage/sets # Set to rebuild all packages that need a preserved lib that only remains due -# to FEATURES=preserved-libs +# to FEATURES=preserve-libs [preserved-rebuild] -class = portage.sets.dbapi.PreservedConsumerSet +class = portage.sets.dbapi.PreservedLibraryConsumerSet diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index 06ba9acaa..57b5f429b 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -3593,11 +3593,7 @@ class depgraph(object): if repo_name_prev: repo_path_prev = portdb.getRepositoryPath( repo_name_prev) - # To avoid spam during the transition period, don't - # show ? if the installed package is missing a - # repository label. - if not repo_path_prev or \ - repo_path_prev == repo_path_real: + if repo_path_prev == repo_path_real: repoadd = repo_display.repoStr(repo_path_real) else: repoadd = "%s=>%s" % ( @@ -6987,13 +6983,23 @@ def emerge_main(): if myaction in ("clean", "config", "depclean", "info", "prune", "unmerge", None): root_config = trees[settings["ROOT"]]["root_config"] setconfig = root_config.setconfig - sets = root_config.sets + sets = setconfig.getSets() # emerge relies on the existance of sets with names "world" and "system" - for s in ("world", "system"): + required_sets = ("world", "system") + for s in required_sets: if s not in sets: - print "emerge: incomplete set configuration, no \"%s\" set defined" % s - print " sets defined: %s" % ", ".join(sets) + msg = ["emerge: incomplete set configuration, " + \ + "no \"%s\" set defined" % s] + msg.append(" sets defined: %s" % ", ".join(sets)) + for line in msg: + sys.stderr.write(line + "\n") return 1 + unmerge_actions = ("unmerge", "prune", "clean", "depclean") + # In order to know exactly which atoms/sets should be added to the + # world file, the depgraph performs set expansion later. It will get + # confused about where the atoms came from if it's not allowed to + # expand them itself. + do_not_expand = (None, ) newargs = [] for a in myfiles: if a in ("system", "world"): @@ -7010,13 +7016,14 @@ def emerge_main(): print "emerge: there are no sets to satisfy %s." % \ colorize("INFORM", s) return 1 - if myaction in ["unmerge", "prune", "clean", "depclean"] and \ + if myaction in unmerge_actions and \ not sets[s].supportsOperation("unmerge"): - print "emerge: the given set %s does not support unmerge operations" % s + sys.stderr.write("emerge: the given set %s does " + \ + "not support unmerge operations\n" % s) return 1 if not setconfig.getSetAtoms(s): print "emerge: '%s' is an empty set" % s - elif myaction != None: + elif myaction not in do_not_expand: newargs.extend(setconfig.getSetAtoms(s)) else: newargs.append(SETPREFIX+s) diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index a938699b3..886fa3b62 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -865,19 +865,38 @@ class config(object): _environ_whitelist = [] - # Preserve backupenv values that are initialized in the config - # constructor. Also, preserve XARGS since it is set by the - # portage.data module. + # Whitelisted variables are always allowed to enter the ebuild + # environment. Generally, this only includes special portage + # variables. Ebuilds can unset variables that are not whitelisted + # and rely on them remaining unset for future phases, without them + # leaking back in from various locations (bug #189417). It's very + # important to set our special BASH_ENV variable in the ebuild + # environment in order to prevent sandbox from sourcing /etc/profile + # in it's bashrc (causing major leakage). _environ_whitelist += [ - "DISTDIR", "FEATURES", "PORTAGE_BIN_PATH", - "PORTAGE_CONFIGROOT", "PORTAGE_DEPCACHEDIR", + "BASH_ENV", "BUILD_PREFIX", "D", + "DISTDIR", "DOC_SYMLINKS_DIR", "EBUILD_EXIT_STATUS_FILE", + "EBUILD", "EBUILD_PHASE", "ECLASSDIR", "ECLASS_DEPTH", "EMERGE_FROM", + "FEATURES", "FILESDIR", "HOME", "PATH", + "PKGUSE", "PKG_LOGDIR", "PKG_TMPDIR", + "PORTAGE_ACTUAL_DISTDIR", "PORTAGE_ARCHLIST", + "PORTAGE_BASHRC", "PORTAGE_BINPKG_TMPFILE", "PORTAGE_BIN_PATH", + "PORTAGE_BUILDDIR", "PORTAGE_COLORMAP", + "PORTAGE_CONFIGROOT", "PORTAGE_DEBUG", "PORTAGE_DEPCACHEDIR", "PORTAGE_GID", "PORTAGE_INST_GID", "PORTAGE_INST_UID", - "PORTAGE_PYM_PATH", "PORTAGE_WORKDIR_MODE", - "PORTDIR", "PORTDIR_OVERLAY", "PREROOTPATH", - "ROOT", "ROOTPATH", "USE_ORDER", + "PORTAGE_LOG_FILE", "PORTAGE_MASTER_PID", + "PORTAGE_PYM_PATH", "PORTAGE_REPO_NAME", "PORTAGE_RESTRICT", + "PORTAGE_TMPDIR", "PORTAGE_WORKDIR_MODE", + "PORTDIR", "PORTDIR_OVERLAY", "PREROOTPATH", "PROFILE_PATHS", + "ROOT", "ROOTPATH", "STARTDIR", "T", "TMP", "TMPDIR", + "USE_EXPAND", "USE_ORDER", "WORKDIR", "XARGS", ] + _environ_whitelist += [ + "A", "AA", "CATEGORY", "P", "PF", "PN", "PR", "PV", "PVR" + ] + # misc variables inherited from the calling environment _environ_whitelist += [ "COLORTERM", "DISPLAY", "EDITOR", "LESS", @@ -2600,9 +2619,11 @@ class config(object): if filter_calling_env and \ x not in environ_whitelist and \ not self._environ_whitelist_re.match(x): - if myvalue == env_d.get(x) or \ - myvalue == os.environ.get(x): - continue + # Do not allow anything to leak into the ebuild + # environment unless it is explicitly whitelisted. + # This ensures that variables unset by the ebuild + # remain unset. + continue mydict[x] = myvalue if not mydict.has_key("HOME") and mydict.has_key("BUILD_PREFIX"): writemsg("*** HOME not set. Setting to "+mydict["BUILD_PREFIX"]+"\n") @@ -3731,7 +3752,14 @@ def spawnebuild(mydo,actionmap,mysettings,debug,alwaysdep=0,logfile=None): os.path.basename(MISC_SH_BINARY)) mycommand = " ".join([_shell_quote(misc_sh_binary), "install_qa_check", "install_symlink_html_docs"]) - qa_retval = spawn(mycommand, mysettings, debug=debug, logfile=logfile, **kwargs) + filter_calling_env_state = mysettings._filter_calling_env + if os.path.exists(os.path.join(mysettings["T"], "environment")): + mysettings._filter_calling_env = True + try: + qa_retval = spawn(mycommand, mysettings, debug=debug, + logfile=logfile, **kwargs) + finally: + mysettings._filter_calling_env = filter_calling_env_state if qa_retval: writemsg("!!! install_qa_check failed; exiting.\n", noiselevel=-1) @@ -4468,7 +4496,10 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, if os.WIFEXITED(retval) and \ os.WEXITSTATUS(retval) == os.EX_OK and \ env_stat and env_stat.st_size > 0: - pass + # This is a signal to ebuild.sh, so that it knows to filter + # out things like SANDBOX_{DENY,PREDICT,READ,WRITE} that + # would be preserved between normal phases. + open(env_file + ".raw", "w") else: writemsg(("!!! Error extracting saved " + \ "environment: '%s'\n") % \ diff --git a/pym/portage/sets/__init__.py b/pym/portage/sets/__init__.py index 2d36f4814..5f82b69b7 100644 --- a/pym/portage/sets/__init__.py +++ b/pym/portage/sets/__init__.py @@ -74,7 +74,7 @@ class SetConfig(SafeConfigParser): def getSets(self): self._parse() - return self.psets + return self.psets.copy() def getSetAtoms(self, setname, ignorelist=None): myset = self.getSets()[setname] -- 2.26.2