cros_sdk: merge user PATH with root's PATH

While we want to keep entries from the user's PATH when running under
sudo, we don't want to ignore the entries that sudo/root implies.  By
default, users do not have /sbin in their PATH, but sudo/root does,
and that's where we find tools that we rely on for image management.
So instead of clobbering root's PATH, merge it instead.

BUG=chromium:1104438
TEST=`PATH=/bin:/usr/bin ./bin/cros_sdk` works again

Change-Id: I39834831e27ca75a0f2ca5b0701beacee7e56f93
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/2296278
Reviewed-by: Lepton Wu <lepton@chromium.org>
Tested-by: Mike Frysinger <vapier@chromium.org>
Commit-Queue: Mike Frysinger <vapier@chromium.org>
diff --git a/scripts/cros_sdk.py b/scripts/cros_sdk.py
index 8ca6158..83145ee 100644
--- a/scripts/cros_sdk.py
+++ b/scripts/cros_sdk.py
@@ -464,17 +464,19 @@
   """Get the 'sudo' command, along with all needed environment variables."""
 
   # Pass in the ENVIRONMENT_WHITELIST and ENV_PASSTHRU variables so that
-  # scripts in the chroot know what variables to pass through.  We keep PATH
-  # not for the chroot but for the re-exec & for programs we might run before
-  # we chroot into the SDK.  The process that enters the SDK itself will take
-  # care of initializing PATH to the right value then.
+  # scripts in the chroot know what variables to pass through.
   cmd = ['sudo']
-  for key in (constants.CHROOT_ENVIRONMENT_WHITELIST + constants.ENV_PASSTHRU +
-              ('PATH',)):
+  for key in constants.CHROOT_ENVIRONMENT_WHITELIST + constants.ENV_PASSTHRU:
     value = os.environ.get(key)
     if value is not None:
       cmd += ['%s=%s' % (key, value)]
 
+  # We keep PATH not for the chroot but for the re-exec & for programs we might
+  # run before we chroot into the SDK.  The process that enters the SDK itself
+  # will take care of initializing PATH to the right value then.  But we can't
+  # override the system's default PATH for root as that will hide /sbin.
+  cmd += ['CHROMEOS_SUDO_PATH=%s' % os.environ.get('PATH', '')]
+
   # Pass in the path to the depot_tools so that users can access them from
   # within the chroot.
   cmd += ['DEPOT_TOOLS=%s' % constants.DEPOT_TOOLS_DIR]
@@ -884,6 +886,11 @@
         "cros_sdk is currently only supported on x86_64; you're running"
         ' %s.  Please find a x86_64 machine.' % (host,))
 
+  # Merge the outside PATH setting if we re-execed ourselves.
+  if 'CHROMEOS_SUDO_PATH' in os.environ:
+    os.environ['PATH'] = '%s:%s' % (os.environ.pop('CHROMEOS_SUDO_PATH'),
+                                    os.environ['PATH'])
+
   _ReportMissing(osutils.FindMissingBinaries(NEEDED_TOOLS))
   if options.proxy_sim:
     _ReportMissing(osutils.FindMissingBinaries(PROXY_NEEDED_TOOLS))