Merged from trunk 8843:8867
authorFabian Groffen <grobian@gentoo.org>
Sat, 8 Dec 2007 16:28:14 +0000 (16:28 -0000)
committerFabian Groffen <grobian@gentoo.org>
Sat, 8 Dec 2007 16:28:14 +0000 (16:28 -0000)
   | 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 <alonbl@gentoo.org> 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 <Arfrever.FTA@GMail.Com> 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
bin/ebuild.sh
bin/emerge-webrsync
cnf/sets.conf
pym/_emerge/__init__.py
pym/portage/__init__.py
pym/portage/sets/__init__.py

diff --git a/TODO b/TODO
index 1704a0d27e59ae239e9427839e97956bd178442d..08f4efebd04e584266da00ba1ceafbf58a2dbdd4 100644 (file)
--- 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)
index cff3591aa6f3967743e566262c463408b1e2763f..6638740d6fa3326c2ddc7b7ec9c52d07a15b2659 100755 (executable)
@@ -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"
index 6e5a4d46caeee1b25aa7cbf0633013232beeabe3..be0acb7221f71a0550f91f700f815de74502164f 100755 (executable)
@@ -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
index 47ff265f9fea99c6148044ed373a3960c417eb78..46d7c769fe786bba1e761573e5bf719c45c76f2c 100644 (file)
@@ -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
index 06ba9acaafe5b6d196fd5c800dc25c2d91ed8b2d..57b5f429b565631473e5b2ec85d5609c98e34aba 100644 (file)
@@ -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)
index a938699b3d6ca430ba5154d972fecf9e53ed913e..886fa3b629f7d290cb2fa4e8a5bde537a77e7077 100644 (file)
@@ -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") % \
index 2d36f481406bea3c32a440bd90eaa41418fb16f1..5f82b69b7492fd12db45526af163211b0c510e07 100644 (file)
@@ -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]