Re-land: Move unix sockets to /tmp/cf_avd

Bug: 279085447
Test: launch_cvd
      Check unix sockets are under /tmp/cf_avd/cvd-1/...
      Not ~/cuttlefush_runtime.1/...
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:136b95e7004ce622789531084de669f4fd3bce29)
Merged-In: Ia264affc58ade2a8261977dbaa0c05cd7dc50d8c
Change-Id: Ia264affc58ade2a8261977dbaa0c05cd7dc50d8c
diff --git a/common/libs/utils/files.cpp b/common/libs/utils/files.cpp
index f8c8116..6b650c7 100644
--- a/common/libs/utils/files.cpp
+++ b/common/libs/utils/files.cpp
@@ -58,6 +58,7 @@
 #include "common/libs/utils/result.h"
 #include "common/libs/utils/scope_guard.h"
 #include "common/libs/utils/subprocess.h"
+#include "common/libs/utils/users.h"
 
 namespace cuttlefish {
 
@@ -93,21 +94,47 @@
 }
 
 Result<void> EnsureDirectoryExists(const std::string& directory_path,
-                                   const mode_t mode) {
+                                   const mode_t mode,
+                                   const std::string& group_name) {
   if (DirectoryExists(directory_path)) {
     return {};
   }
   const auto parent_dir = cpp_dirname(directory_path);
   if (parent_dir.size() > 1) {
-    EnsureDirectoryExists(parent_dir);
+    EnsureDirectoryExists(parent_dir, mode, group_name);
   }
   LOG(DEBUG) << "Setting up " << directory_path;
   if (mkdir(directory_path.c_str(), mode) < 0 && errno != EEXIST) {
     return CF_ERRNO("Failed to create directory: \"" << directory_path << "\"");
   }
+
+  if (group_name != "") {
+    ChangeGroup(directory_path, group_name);
+  }
+
   return {};
 }
 
+Result<void> ChangeGroup(const std::string& path,
+                         const std::string& group_name) {
+  auto groupId = GroupIdFromName(group_name);
+
+  if (groupId == -1) {
+    return CF_ERR("Failed to get group id: ") << group_name;
+  }
+
+  if (chown(path.c_str(), -1, groupId) != 0) {
+    return CF_ERRNO("Feailed to set group for path: "
+                    << path << ", " << group_name << ", " << strerror(errno));
+  }
+
+  return {};
+}
+
+bool CanAccess(const std::string& path, const int mode) {
+  return access(path.c_str(), mode) == 0;
+}
+
 bool IsDirectoryEmpty(const std::string& path) {
   auto direc = ::opendir(path.c_str());
   if (!direc) {
diff --git a/common/libs/utils/files.h b/common/libs/utils/files.h
index 5257e32..b9b0eca 100644
--- a/common/libs/utils/files.h
+++ b/common/libs/utils/files.h
@@ -31,7 +31,11 @@
 bool DirectoryExists(const std::string& path, bool follow_symlinks = true);
 Result<void> EnsureDirectoryExists(const std::string& directory_path,
                                    const mode_t mode = S_IRWXU | S_IRWXG |
-                                                       S_IROTH | S_IXOTH);
+                                                       S_IROTH | S_IXOTH,
+                                   const std::string& group_name = "");
+Result<void> ChangeGroup(const std::string& path,
+                         const std::string& group_name);
+bool CanAccess(const std::string& path, const int mode);
 bool IsDirectoryEmpty(const std::string& path);
 bool RecursivelyRemoveDirectory(const std::string& path);
 bool Copy(const std::string& from, const std::string& to);
diff --git a/common/libs/utils/users.cpp b/common/libs/utils/users.cpp
index dc434ce..e8ff32e 100644
--- a/common/libs/utils/users.cpp
+++ b/common/libs/utils/users.cpp
@@ -37,6 +37,24 @@
 
 namespace cuttlefish {
 namespace {
+std::vector<gid_t> GetSuplementaryGroups() {
+  int num_groups = getgroups(0, nullptr);
+  if (num_groups < 0) {
+    LOG(ERROR) << "Unable to get number of suplementary groups: "
+               << std::strerror(errno);
+    return {};
+  }
+  std::vector<gid_t> groups(num_groups + 1);
+  int retval = getgroups(groups.size(), groups.data());
+  if (retval < 0) {
+    LOG(ERROR) << "Error obtaining list of suplementary groups (list size: "
+               << groups.size() << "): " << std::strerror(errno);
+    return {};
+  }
+  return groups;
+}
+}  // namespace
+
 gid_t GroupIdFromName(const std::string& group_name) {
   struct group grp{};
   struct group* grp_p{};
@@ -64,24 +82,6 @@
   }
 }
 
-std::vector<gid_t> GetSuplementaryGroups() {
-  int num_groups = getgroups(0, nullptr);
-  if (num_groups < 0) {
-    LOG(ERROR) << "Unable to get number of suplementary groups: "
-               << std::strerror(errno);
-    return {};
-  }
-  std::vector<gid_t> groups(num_groups + 1);
-  int retval = getgroups(groups.size(), groups.data());
-  if (retval < 0) {
-    LOG(ERROR) << "Error obtaining list of suplementary groups (list size: "
-               << groups.size() << "): " << std::strerror(errno);
-    return {};
-  }
-  return groups;
-}
-}  // namespace
-
 bool InGroup(const std::string& group) {
   auto gid = GroupIdFromName(group);
   if (gid == static_cast<gid_t>(-1)) {
diff --git a/common/libs/utils/users.h b/common/libs/utils/users.h
index f823037..6b439d5 100644
--- a/common/libs/utils/users.h
+++ b/common/libs/utils/users.h
@@ -15,12 +15,15 @@
  */
 #pragma once
 
+#include <grp.h>
+
 #include <string>
 
 #include "common/libs/utils/result.h"
 
 namespace cuttlefish {
 
+gid_t GroupIdFromName(const std::string& group_name);
 bool InGroup(const std::string& group);
 
 /**
diff --git a/host/commands/assemble_cvd/assemble_cvd.cc b/host/commands/assemble_cvd/assemble_cvd.cc
index 9875f26..9d285ec 100644
--- a/host/commands/assemble_cvd/assemble_cvd.cc
+++ b/host/commands/assemble_cvd/assemble_cvd.cc
@@ -153,6 +153,19 @@
     return CF_ERRNO("symlink(\"" << instance.instance_dir() << "\", \""
                                  << legacy_instance_path << "\") failed");
   }
+
+  const auto mac80211_uds_name = "vhost_user_mac80211";
+
+  const auto mac80211_uds_path =
+      instance.PerInstanceInternalUdsPath(mac80211_uds_name);
+  const auto legacy_mac80211_uds_path =
+      instance.PerInstanceInternalPath(mac80211_uds_name);
+
+  if (symlink(mac80211_uds_path.c_str(), legacy_mac80211_uds_path.c_str())) {
+    return CF_ERRNO("symlink(\"" << mac80211_uds_path << "\", \""
+                                 << legacy_mac80211_uds_path << "\") failed");
+  }
+
   return {};
 }
 
@@ -253,9 +266,17 @@
                               config.instance_dirs()),
               "Failed to clean prior files");
 
+    auto defaultGroup = "cvdnetwork";
+    const mode_t defaultMode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
+
     CF_EXPECT(EnsureDirectoryExists(config.root_dir()));
     CF_EXPECT(EnsureDirectoryExists(config.assembly_dir()));
     CF_EXPECT(EnsureDirectoryExists(config.instances_dir()));
+    CF_EXPECT(EnsureDirectoryExists(config.instances_uds_dir(), defaultMode,
+                                    defaultGroup));
+
+    LOG(INFO) << "Path for instance UDS: " << config.instances_uds_dir();
+
     if (log->LinkAtCwd(config.AssemblyPath("assemble_cvd.log"))) {
       LOG(ERROR) << "Unable to persist assemble_cvd log at "
                   << config.AssemblyPath("assemble_cvd.log")
@@ -266,13 +287,19 @@
       CF_EXPECT(EnsureDirectoryExists(instance.instance_dir()));
       auto internal_dir = instance.instance_dir() + "/" + kInternalDirName;
       CF_EXPECT(EnsureDirectoryExists(internal_dir));
-      auto grpc_socket_dir = instance.instance_dir() + "/" + kGrpcSocketDirName;
-      CF_EXPECT(EnsureDirectoryExists(grpc_socket_dir));
       auto shared_dir = instance.instance_dir() + "/" + kSharedDirName;
       CF_EXPECT(EnsureDirectoryExists(shared_dir));
       auto recording_dir = instance.instance_dir() + "/recording";
       CF_EXPECT(EnsureDirectoryExists(recording_dir));
       CF_EXPECT(EnsureDirectoryExists(instance.PerInstanceLogPath("")));
+
+      CF_EXPECT(EnsureDirectoryExists(instance.instance_uds_dir(), defaultMode,
+                                      defaultGroup));
+      CF_EXPECT(EnsureDirectoryExists(instance.instance_internal_uds_dir(),
+                                      defaultMode, defaultGroup));
+      CF_EXPECT(EnsureDirectoryExists(instance.PerInstanceGrpcSocketPath(""),
+                                      defaultMode, defaultGroup));
+
       // TODO(schuffelen): Move this code somewhere better
       CF_EXPECT(CreateLegacySymlinks(instance));
     }
diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc
index 4b6a3bb..c5ef034 100644
--- a/host/commands/assemble_cvd/flags.cc
+++ b/host/commands/assemble_cvd/flags.cc
@@ -1393,9 +1393,9 @@
     if (start_wmediumd) {
       // TODO(b/199020470) move this to the directory for shared resources
       auto vhost_user_socket_path =
-          const_instance.PerInstanceInternalPath("vhost_user_mac80211");
+          const_instance.PerInstanceInternalUdsPath("vhost_user_mac80211");
       auto wmediumd_api_socket_path =
-          const_instance.PerInstanceInternalPath("wmediumd_api_server");
+          const_instance.PerInstanceInternalUdsPath("wmediumd_api_server");
 
       tmp_config_obj.set_vhost_user_mac80211_hwsim(vhost_user_socket_path);
       tmp_config_obj.set_wmediumd_api_server_socket(wmediumd_api_socket_path);
diff --git a/host/commands/display/main.cpp b/host/commands/display/main.cpp
index cf1984b..375c31d 100644
--- a/host/commands/display/main.cpp
+++ b/host/commands/display/main.cpp
@@ -107,7 +107,7 @@
 
   const std::string crosvm_binary_path = instance.crosvm_binary();
   const std::string crosvm_control_path =
-      instance.PerInstanceInternalPath("crosvm_control.sock");
+      instance.PerInstanceInternalUdsPath("crosvm_control.sock");
 
   cuttlefish::Command command(crosvm_binary_path);
   command.AddParameter("gpu");
diff --git a/host/commands/health/health.cpp b/host/commands/health/health.cpp
index 4147ca8..aad9869 100644
--- a/host/commands/health/health.cpp
+++ b/host/commands/health/health.cpp
@@ -24,7 +24,7 @@
 #include "host/libs/vm_manager/vm_manager.h"
 
 std::string GetControlSocketPath(const cuttlefish::CuttlefishConfig& config) {
-  return config.ForDefaultInstance().PerInstanceInternalPath(
+  return config.ForDefaultInstance().PerInstanceInternalUdsPath(
       "crosvm_control.sock");
 }
 
diff --git a/host/commands/run_cvd/launch/open_wrt.cpp b/host/commands/run_cvd/launch/open_wrt.cpp
index 648b7b5..b712ee3 100644
--- a/host/commands/run_cvd/launch/open_wrt.cpp
+++ b/host/commands/run_cvd/launch/open_wrt.cpp
@@ -53,7 +53,7 @@
                                  kOpenwrtVmResetExitCode);
     ap_cmd.Cmd().AddParameter("run");
     ap_cmd.AddControlSocket(
-        instance_.PerInstanceInternalPath(crosvm_for_ap_socket),
+        instance_.PerInstanceInternalUdsPath(crosvm_for_ap_socket),
         instance_.crosvm_binary());
 
     if (!config_.vhost_user_mac80211_hwsim().empty()) {
diff --git a/host/commands/run_cvd/launch/secure_env.cpp b/host/commands/run_cvd/launch/secure_env.cpp
index 8a80510..b5e0cf8 100644
--- a/host/commands/run_cvd/launch/secure_env.cpp
+++ b/host/commands/run_cvd/launch/secure_env.cpp
@@ -91,7 +91,7 @@
     }
 
     auto confui_socket_path =
-        instance_.PerInstanceInternalPath("confui_sign.sock");
+        instance_.PerInstanceInternalUdsPath("confui_sign.sock");
     confui_server_fd_ = SharedFD::SocketLocalServer(confui_socket_path, false,
                                                     SOCK_STREAM, 0600);
     CF_EXPECT(confui_server_fd_->IsOpen(),
diff --git a/host/commands/run_cvd/server_loop.cpp b/host/commands/run_cvd/server_loop.cpp
index 44c9b61..6347670 100644
--- a/host/commands/run_cvd/server_loop.cpp
+++ b/host/commands/run_cvd/server_loop.cpp
@@ -233,7 +233,7 @@
     DeleteFifos();
 
     // TODO(b/269669405): Figure out why this file is not being deleted
-    unlink(instance_.PerInstanceInternalPath("crosvm_control.sock").c_str());
+    unlink(instance_.PerInstanceInternalUdsPath("crosvm_control.sock").c_str());
 
     // TODO(schuffelen): Clean up duplication with assemble_cvd
     unlink(instance_.PerInstancePath("NVChip").c_str());
diff --git a/host/commands/secure_env/confui_sign_server.cpp b/host/commands/secure_env/confui_sign_server.cpp
index 03ff94e..f82ee85 100644
--- a/host/commands/secure_env/confui_sign_server.cpp
+++ b/host/commands/secure_env/confui_sign_server.cpp
@@ -37,7 +37,7 @@
   auto config = cuttlefish::CuttlefishConfig::Get();
   CHECK(config) << "Config must not be null";
   auto instance = config->ForDefaultInstance();
-  server_socket_path_ = instance.PerInstanceInternalPath("confui_sign.sock");
+  server_socket_path_ = instance.PerInstanceInternalUdsPath("confui_sign.sock");
 }
 
 [[noreturn]] void ConfUiSignServer::MainLoop() {
diff --git a/host/commands/stop/main.cc b/host/commands/stop/main.cc
index 12350fa..c617632 100644
--- a/host/commands/stop/main.cc
+++ b/host/commands/stop/main.cc
@@ -62,6 +62,7 @@
   return {
       config.assembly_dir(),
       instance.instance_dir(),
+      instance.instance_uds_dir(),
   };
 }
 
diff --git a/host/libs/config/cuttlefish_config.cpp b/host/libs/config/cuttlefish_config.cpp
index 1fcb88e..1b9e07b 100644
--- a/host/libs/config/cuttlefish_config.cpp
+++ b/host/libs/config/cuttlefish_config.cpp
@@ -578,6 +578,25 @@
   return AbsolutePath(assembly_dir() + "/" + file_name);
 }
 
+std::string CuttlefishConfig::instances_uds_dir() const {
+  // Try to use /tmp/cf_avd_{uid}/ for UDS directory.
+  // If it fails, use HOME directory(legacy) instead.
+
+  auto defaultPath = AbsolutePath("/tmp/cf_avd_" + std::to_string(getuid()));
+
+  if (!DirectoryExists(defaultPath) ||
+      CanAccess(defaultPath, R_OK | W_OK | X_OK)) {
+    return defaultPath;
+  }
+
+  return instances_dir();
+}
+
+std::string CuttlefishConfig::InstancesUdsPath(
+    const std::string& file_name) const {
+  return AbsolutePath(instances_uds_dir() + "/" + file_name);
+}
+
 CuttlefishConfig::MutableInstanceSpecific CuttlefishConfig::ForInstance(int num) {
   return MutableInstanceSpecific(this, std::to_string(num));
 }
@@ -608,6 +627,7 @@
   std::vector<std::string> result;
   for (const auto& instance : Instances()) {
     result.push_back(instance.instance_dir());
+    result.push_back(instance.instance_uds_dir());
   }
   return result;
 }
diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h
index 55850dd..16151b3 100644
--- a/host/libs/config/cuttlefish_config.h
+++ b/host/libs/config/cuttlefish_config.h
@@ -102,6 +102,9 @@
   std::string assembly_dir() const;
   std::string AssemblyPath(const std::string&) const;
 
+  std::string instances_uds_dir() const;
+  std::string InstancesUdsPath(const std::string&) const;
+
   std::string vm_manager() const;
   void set_vm_manager(const std::string& name);
 
@@ -320,15 +323,25 @@
 
     // Returns the path to a file with the given name in the instance
     // directory..
-    std::string PerInstancePath(const char* file_name) const;
-    std::string PerInstanceInternalPath(const char* file_name) const;
+    std::string PerInstancePath(const std::string& file_name) const;
+    std::string PerInstanceInternalPath(const std::string& file_name) const;
     std::string PerInstanceLogPath(const std::string& file_name) const;
-    std::string PerInstanceGrpcSocketPath(const std::string& socket_name) const;
 
     std::string instance_dir() const;
 
     std::string instance_internal_dir() const;
 
+    // Return the Unix domain socket path with given name. Because the
+    // length limitation of Unix domain socket name, it needs to be in
+    // the another directory than normal Instance path.
+    std::string PerInstanceUdsPath(const std::string& file_name) const;
+    std::string PerInstanceInternalUdsPath(const std::string& file_name) const;
+    std::string PerInstanceGrpcSocketPath(const std::string& socket_name) const;
+
+    std::string instance_uds_dir() const;
+
+    std::string instance_internal_uds_dir() const;
+
     std::string touch_socket_path(int screen_idx) const;
     std::string keyboard_socket_path() const;
     std::string switches_socket_path() const;
diff --git a/host/libs/config/cuttlefish_config_instance.cpp b/host/libs/config/cuttlefish_config_instance.cpp
index c297157..cb6b732 100644
--- a/host/libs/config/cuttlefish_config_instance.cpp
+++ b/host/libs/config/cuttlefish_config_instance.cpp
@@ -59,6 +59,15 @@
   return PerInstancePath(kInternalDirName);
 }
 
+std::string CuttlefishConfig::InstanceSpecific::instance_uds_dir() const {
+  return config_->InstancesUdsPath(IdToName(id_));
+}
+
+std::string CuttlefishConfig::InstanceSpecific::instance_internal_uds_dir()
+    const {
+  return PerInstanceUdsPath(kInternalDirName);
+}
+
 // TODO (b/163575714) add virtio console support to the bootloader so the
 // virtio console path for the console device can be taken again. When that
 // happens, this function can be deleted along with all the code paths it
@@ -954,7 +963,7 @@
 
 std::string CuttlefishConfig::InstanceSpecific::launcher_monitor_socket_path()
     const {
-  return AbsolutePath(PerInstancePath("launcher_monitor.sock"));
+  return AbsolutePath(PerInstanceUdsPath("launcher_monitor.sock"));
 }
 
 static constexpr char kModemSimulatorPorts[] = "modem_simulator_ports";
@@ -1029,7 +1038,7 @@
 static constexpr char kMobileBridgeName[] = "mobile_bridge_name";
 
 std::string CuttlefishConfig::InstanceSpecific::audio_server_path() const {
-  return AbsolutePath(PerInstanceInternalPath("audio_server.sock"));
+  return AbsolutePath(PerInstanceInternalUdsPath("audio_server.sock"));
 }
 
 CuttlefishConfig::InstanceSpecific::BootFlow CuttlefishConfig::InstanceSpecific::boot_flow() const {
@@ -1357,20 +1366,20 @@
 
 std::string CuttlefishConfig::InstanceSpecific::touch_socket_path(
     int screen_idx) const {
-  return PerInstanceInternalPath(
+  return PerInstanceInternalUdsPath(
       ("touch_" + std::to_string(screen_idx) + ".sock").c_str());
 }
 
 std::string CuttlefishConfig::InstanceSpecific::keyboard_socket_path() const {
-  return PerInstanceInternalPath("keyboard.sock");
+  return PerInstanceInternalUdsPath("keyboard.sock");
 }
 
 std::string CuttlefishConfig::InstanceSpecific::switches_socket_path() const {
-  return PerInstanceInternalPath("switches.sock");
+  return PerInstanceInternalUdsPath("switches.sock");
 }
 
 std::string CuttlefishConfig::InstanceSpecific::frames_socket_path() const {
-  return PerInstanceInternalPath("frames.sock");
+  return PerInstanceInternalUdsPath("frames.sock");
 }
 
 static constexpr char kWifiMacPrefix[] = "wifi_mac_prefix";
@@ -1392,12 +1401,12 @@
 }
 
 std::string CuttlefishConfig::InstanceSpecific::PerInstancePath(
-    const char* file_name) const {
+    const std::string& file_name) const {
   return (instance_dir() + "/") + file_name;
 }
 
 std::string CuttlefishConfig::InstanceSpecific::PerInstanceInternalPath(
-    const char* file_name) const {
+    const std::string& file_name) const {
   if (file_name[0] == '\0') {
     // Don't append a / if file_name is empty.
     return PerInstancePath(kInternalDirName);
@@ -1406,14 +1415,29 @@
   return PerInstancePath(relative_path.c_str());
 }
 
+std::string CuttlefishConfig::InstanceSpecific::PerInstanceUdsPath(
+    const std::string& file_name) const {
+  return (instance_uds_dir() + "/") + file_name;
+}
+
+std::string CuttlefishConfig::InstanceSpecific::PerInstanceInternalUdsPath(
+    const std::string& file_name) const {
+  if (file_name[0] == '\0') {
+    // Don't append a / if file_name is empty.
+    return PerInstanceUdsPath(kInternalDirName);
+  }
+  auto relative_path = (std::string(kInternalDirName) + "/") + file_name;
+  return PerInstanceUdsPath(relative_path.c_str());
+}
+
 std::string CuttlefishConfig::InstanceSpecific::PerInstanceGrpcSocketPath(
     const std::string& socket_name) const {
   if (socket_name.size() == 0) {
     // Don't append a / if file_name is empty.
-    return PerInstancePath(kGrpcSocketDirName);
+    return PerInstanceUdsPath(kGrpcSocketDirName);
   }
   auto relative_path = (std::string(kGrpcSocketDirName) + "/") + socket_name;
-  return PerInstancePath(relative_path.c_str());
+  return PerInstanceUdsPath(relative_path.c_str());
 }
 
 std::string CuttlefishConfig::InstanceSpecific::PerInstanceLogPath(
diff --git a/host/libs/confui/sign.cc b/host/libs/confui/sign.cc
index 2c454e5..bbaac83 100644
--- a/host/libs/confui/sign.cc
+++ b/host/libs/confui/sign.cc
@@ -37,7 +37,7 @@
   auto config = cuttlefish::CuttlefishConfig::Get();
   CHECK(config) << "Config must not be null";
   auto instance = config->ForDefaultInstance();
-  return instance.PerInstanceInternalPath("confui_sign.sock");
+  return instance.PerInstanceInternalUdsPath("confui_sign.sock");
 }
 
 /**
diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp
index c53dda7..033797f 100644
--- a/host/libs/vm_manager/crosvm_manager.cpp
+++ b/host/libs/vm_manager/crosvm_manager.cpp
@@ -48,7 +48,7 @@
 std::string GetControlSocketPath(
     const CuttlefishConfig::InstanceSpecific& instance,
     const std::string& socket_name) {
-  return instance.PerInstanceInternalPath(socket_name.c_str());
+  return instance.PerInstanceInternalUdsPath(socket_name.c_str());
 }
 
 }  // namespace
diff --git a/host/libs/vm_manager/qemu_manager.cpp b/host/libs/vm_manager/qemu_manager.cpp
index 362eb23..27a3ddf 100644
--- a/host/libs/vm_manager/qemu_manager.cpp
+++ b/host/libs/vm_manager/qemu_manager.cpp
@@ -50,8 +50,8 @@
 namespace {
 
 std::string GetMonitorPath(const CuttlefishConfig& config) {
-  return config.ForDefaultInstance()
-      .PerInstanceInternalPath("qemu_monitor.sock");
+  return config.ForDefaultInstance().PerInstanceInternalUdsPath(
+      "qemu_monitor.sock");
 }
 
 void LogAndSetEnv(const char* key, const std::string& value) {