cros_vm: Safely create vm_dir.

There's a TOCTOU vulnerability raised here:
https://chromium-review.googlesource.com/c/chromiumos/chromite/+/871140#message-a810603ab6e1fc41752cc09937f370ec51765100

Introduce _CreateVMDir to fix this.

BUG=chromium:782664
TEST=manual

Change-Id: I1c22f2cd867ccd23d11974c4cef61b0673a3ce3a
Reviewed-on: https://chromium-review.googlesource.com/980751
Commit-Ready: Achuith Bhandarkar <achuith@chromium.org>
Tested-by: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
diff --git a/scripts/cros_vm.py b/scripts/cros_vm.py
index 656e304..d9c5dd3 100644
--- a/scripts/cros_vm.py
+++ b/scripts/cros_vm.py
@@ -71,14 +71,7 @@
     if not self.vm_dir:
       self.vm_dir = os.path.join(osutils.GetGlobalTempDir(),
                                  'cros_vm_%d' % self.ssh_port)
-    if os.path.exists(self.vm_dir):
-      # For security, ensure that vm_dir is not a symlink, and is owned by us or
-      # by root.
-      assert not os.path.islink(self.vm_dir), \
-          'VM state dir is misconfigured; please recreate: %s' % self.vm_dir
-      st_uid = os.stat(self.vm_dir).st_uid
-      assert st_uid == 0 or st_uid == os.getuid(), \
-          'VM state dir is misconfigured; please recreate: %s' % self.vm_dir
+    self._CreateVMDir()
 
     self.pidfile = os.path.join(self.vm_dir, 'kvm.pid')
     self.kvm_monitor = os.path.join(self.vm_dir, 'kvm.monitor')
@@ -100,15 +93,20 @@
     else:
       return cros_build_lib.RunCommand(*args, **kwargs)
 
-  def _CleanupFiles(self, recreate):
-    """Cleanup vm_dir.
+  def _CreateVMDir(self):
+    """Safely create vm_dir."""
+    if not osutils.SafeMakedirs(self.vm_dir, sudo=self.use_sudo):
+      # For security, ensure that vm_dir is not a symlink, and is owned by us or
+      # by root.
+      error_str = ('VM state dir is misconfigured; please recreate: %s'
+                   % self.vm_dir)
+      assert not os.path.islink(self.vm_dir), error_str
+      st_uid = os.stat(self.vm_dir).st_uid
+      assert st_uid == 0 or st_uid == os.getuid(), error_str
 
-    Args:
-      recreate: recreate vm_dir.
-    """
+  def _RmVMDir(self):
+    """Cleanup vm_dir."""
     osutils.RmDir(self.vm_dir, ignore_missing=True, sudo=self.use_sudo)
-    if recreate:
-      osutils.SafeMakedirs(self.vm_dir)
 
   @staticmethod
   def _GetCachePath(cache_name):
@@ -270,7 +268,8 @@
     self._SetQemuPath()
     self._SetVMImagePath()
 
-    self._CleanupFiles(recreate=True)
+    self._RmVMDir()
+    self._CreateVMDir()
     # Make sure we can read these files later on by creating them as ourselves.
     osutils.Touch(self.kvm_serial)
     for pipe in [self.kvm_pipe_in, self.kvm_pipe_out]:
@@ -358,8 +357,7 @@
       logging.info('Killing %d.', pid)
       if not self.dry_run:
         self._RunCommand(['kill', '-9', str(pid)], error_code_ok=True)
-
-    self._CleanupFiles(recreate=False)
+    self._RmVMDir()
 
   def _WaitForProcs(self):
     """Wait for expected processes to launch."""