Merge "Grant GPU access to logger_app" into rvc-dev
diff --git a/common/libs/net/netlink_request.cpp b/common/libs/net/netlink_request.cpp
index 501b2c3..68adcf0 100644
--- a/common/libs/net/netlink_request.cpp
+++ b/common/libs/net/netlink_request.cpp
@@ -95,6 +95,10 @@
   ad_info->ifa_index = if_index;
 }
 
+void NetlinkRequest::AddMacAddress(const std::array<unsigned char, 6>& address) {
+  AppendTag(IFLA_ADDRESS, address.data(), 6);
+}
+
 void NetlinkRequest::PushList(uint16_t type) {
   int length = request_.size();
   nlattr* list = AppendTag(type, NULL, 0);
diff --git a/common/libs/net/netlink_request.h b/common/libs/net/netlink_request.h
index 5e5b355..541c04b 100644
--- a/common/libs/net/netlink_request.h
+++ b/common/libs/net/netlink_request.h
@@ -19,6 +19,7 @@
 #include <linux/netlink.h>
 #include <stddef.h>
 
+#include <array>
 #include <memory>
 #include <string>
 #include <vector>
@@ -57,6 +58,9 @@
   // Add an address info to a specific interface.
   void AddAddrInfo(int32_t if_index, int prefix_len = 24);
 
+  // Add an ethernet address/mac address
+  void AddMacAddress(const std::array<unsigned char, 6>& address);
+
   // Creates new list.
   // List mimmic recursive structures in a flat, contiuous representation.
   // Each call to PushList() should have a corresponding call to PopList
diff --git a/guest/commands/setup_wifi/Android.bp b/guest/commands/setup_wifi/Android.bp
index 182d885..e578af2 100644
--- a/guest/commands/setup_wifi/Android.bp
+++ b/guest/commands/setup_wifi/Android.bp
@@ -22,7 +22,11 @@
     shared_libs: [
         "cuttlefish_net",
         "libbase",
+        "libcutils",
         "liblog",
     ],
+    static_libs: [
+        "libgflags",
+    ],
     defaults: ["cuttlefish_guest_only"]
 }
diff --git a/guest/commands/setup_wifi/main.cpp b/guest/commands/setup_wifi/main.cpp
index e3840ff..494a767 100644
--- a/guest/commands/setup_wifi/main.cpp
+++ b/guest/commands/setup_wifi/main.cpp
@@ -17,15 +17,34 @@
 #include <linux/rtnetlink.h>
 #include <net/if.h>
 
+#include <array>
 #include <cstdlib>
 #include <iostream>
+#include <sstream>
 #include <string>
 
+#include "android-base/logging.h"
+#include <cutils/properties.h>
+#include <gflags/gflags.h>
+
 #include "common/libs/net/netlink_client.h"
 #include "common/libs/net/netlink_request.h"
 #include "common/libs/net/network_interface.h"
 #include "common/libs/net/network_interface_manager.h"
-#include "common/libs/glog/logging.h"
+
+DEFINE_string(mac_address, "", "mac address to use for wlan0");
+
+static std::array<unsigned char, 6> str_to_mac(const std::string& mac_str) {
+  std::array<unsigned char, 6> mac;
+  std::istringstream stream(mac_str);
+  for (int i = 0; i < 6; i++) {
+    int num;
+    stream >> std::hex >> num;
+    mac[i] = num;
+    stream.get();
+  }
+  return mac;
+}
 
 // TODO(schuffelen): Merge this with the ip_link_add binary.
 int CreateWifiWrapper(const std::string& source,
@@ -33,13 +52,32 @@
   auto factory = cvd::NetlinkClientFactory::Default();
   std::unique_ptr<cvd::NetlinkClient> nl(factory->New(NETLINK_ROUTE));
 
+  LOG(INFO) << "Setting " << source << " mac address to " << FLAGS_mac_address;
+  int32_t index = if_nametoindex(source.c_str());
+  // Setting the address is available in RTM_SETLINK, but not RTM_NEWLINK.
+  // https://elixir.bootlin.com/linux/v5.4.44/source/net/core/rtnetlink.c#L2785
+  // https://elixir.bootlin.com/linux/v5.4.44/source/net/core/rtnetlink.c#L2460
+  // Setting the address seems to work better on the underlying ethernet device,
+  // and this mac address is inherited by the virt_wifi device.
+  cvd::NetlinkRequest fix_mac_request(
+      RTM_SETLINK, NLM_F_REQUEST|NLM_F_ACK|0x600);
+  fix_mac_request.Append(ifinfomsg {
+    .ifi_index = index,
+    .ifi_change = 0xFFFFFFFF,
+  });
+  fix_mac_request.AddMacAddress(str_to_mac(FLAGS_mac_address));
+  bool fix_mac = nl->Send(fix_mac_request);
+  if (!fix_mac) {
+    LOG(ERROR) << "setup_network: could not fix mac address";
+    return -5;
+  }
+
   // http://maz-programmersdiary.blogspot.com/2011/09/netlink-sockets.html
   cvd::NetlinkRequest link_add_request(RTM_NEWLINK,
                                        NLM_F_REQUEST|NLM_F_ACK|0x600);
   link_add_request.Append(ifinfomsg {
     .ifi_change = 0xFFFFFFFF,
   });
-  int32_t index = if_nametoindex(source.c_str());
   if (index == 0) {
     LOG(ERROR) << "setup_network: invalid interface name '" << source << "'\n";
     return -2;
@@ -93,7 +131,15 @@
   return 0;
 }
 
-int main() {
+int main(int argc, char** argv) {
+  char wifi_address[PROPERTY_VALUE_MAX + 1];
+  property_get("ro.boot.wifi_mac_address", wifi_address, "");
+
+  SetCommandLineOptionWithMode("mac_address", wifi_address,
+                               google::FlagSettingMode::SET_FLAGS_DEFAULT);
+
+  gflags::ParseCommandLineFlags(&argc, &argv, true);
+
   int renamed_eth0 = RenameNetwork("eth0", "buried_eth0");
   if (renamed_eth0 != 0) {
     return renamed_eth0;
diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc
index a58aed8..5ce8e99 100644
--- a/host/commands/assemble_cvd/flags.cc
+++ b/host/commands/assemble_cvd/flags.cc
@@ -7,6 +7,7 @@
 #include <unistd.h>
 
 #include <algorithm>
+#include <array>
 #include <iostream>
 #include <fstream>
 
@@ -419,6 +420,15 @@
       const_instance.PerInstancePath("overlay.img"),
       const_instance.sdcard_path(),
     });
+
+    std::array<unsigned char, 6> mac_address;
+    mac_address[0] = 1 << 6; // locally administered
+    // TODO(schuffelen): Randomize these and preserve the state.
+    for (int i = 1; i < 5; i++) {
+      mac_address[i] = i;
+    }
+    mac_address[5] = num;
+    instance.set_wifi_mac_address(mac_address);
   }
 
   return tmp_config_obj;
diff --git a/host/commands/assemble_cvd/super_image_mixer.cc b/host/commands/assemble_cvd/super_image_mixer.cc
index 23df66b..011aadd 100644
--- a/host/commands/assemble_cvd/super_image_mixer.cc
+++ b/host/commands/assemble_cvd/super_image_mixer.cc
@@ -64,6 +64,21 @@
   "IMAGES/vbmeta.img",
   "IMAGES/vendor.img",
 };
+const std::set<std::string> kDefaultTargetBuildProp = {
+  "ODM/etc/build.prop",
+  "VENDOR/build.prop",
+};
+
+void FindImports(cvd::Archive* archive, const std::string& build_prop_file) {
+  auto contents = archive->ExtractToMemory(build_prop_file);
+  auto lines = android::base::Split(contents, "\n");
+  for (const auto& line : lines) {
+    auto parts = android::base::Split(line, " ");
+    if (parts.size() >= 2 && parts[0] == "import") {
+      LOG(INFO) << build_prop_file << ": " << line;
+    }
+  }
+}
 
 bool CombineTargetZipFiles(const std::string& default_target_zip,
                            const std::string& system_target_zip,
@@ -149,6 +164,19 @@
       return false;
     }
   }
+  for (const auto& name : default_target_contents) {
+    if (!android::base::EndsWith(name, "build.prop")) {
+      continue;
+    } else if (kDefaultTargetBuildProp.count(name) == 0) {
+      continue;
+    }
+    FindImports(&default_target_archive, name);
+    LOG(INFO) << "Writing " << name;
+    if (!default_target_archive.ExtractFiles({name}, output_path)) {
+      LOG(ERROR) << "Failed to extract " << name << " from the default target zip";
+      return false;
+    }
+  }
 
   for (const auto& name : system_target_contents) {
     if (!android::base::StartsWith(name, "IMAGES/")) {
@@ -164,6 +192,19 @@
       return false;
     }
   }
+  for (const auto& name : system_target_contents) {
+    if (!android::base::EndsWith(name, "build.prop")) {
+      continue;
+    } else if (kDefaultTargetBuildProp.count(name) > 0) {
+      continue;
+    }
+    FindImports(&default_target_archive, name);
+    LOG(INFO) << "Writing " << name;
+    if (!default_target_archive.ExtractFiles({name}, output_path)) {
+      LOG(ERROR) << "Failed to extract " << name << " from the default target zip";
+      return false;
+    }
+  }
 
   return true;
 }
diff --git a/host/commands/run_cvd/kernel_args.cc b/host/commands/run_cvd/kernel_args.cc
index 6615441..60a53dd 100644
--- a/host/commands/run_cvd/kernel_args.cc
+++ b/host/commands/run_cvd/kernel_args.cc
@@ -16,6 +16,8 @@
 
 #include "host/commands/run_cvd/kernel_args.h"
 
+#include <array>
+#include <sstream>
 #include <string>
 #include <vector>
 
@@ -36,6 +38,15 @@
   return os.str();
 }
 
+static std::string mac_to_str(const std::array<unsigned char, 6>& mac) {
+  std::ostringstream stream;
+  stream << std::hex << (int) mac[0];
+  for (int i = 1; i < 6; i++) {
+    stream << ":" << std::hex << (int) mac[i];
+  }
+  return stream.str();
+}
+
 std::vector<std::string> KernelCommandLineFromConfig(const vsoc::CuttlefishConfig& config) {
   auto instance = config.ForDefaultInstance();
   std::vector<std::string> kernel_cmdline;
@@ -76,6 +87,10 @@
     kernel_cmdline.push_back("androidboot.force_normal_boot=1");
   }
 
+  // TODO(b/158131610): Set this in crosvm instead
+  kernel_cmdline.push_back(concat("androidboot.wifi_mac_address=",
+                                  mac_to_str(instance.wifi_mac_address())));
+
   AppendVector(&kernel_cmdline, config.extra_kernel_cmdline());
 
   return kernel_cmdline;
diff --git a/host/frontend/gcastv2/webrtc/certs/server.crt b/host/frontend/gcastv2/webrtc/certs/server.crt
index 81759be..0b9aa36 100644
--- a/host/frontend/gcastv2/webrtc/certs/server.crt
+++ b/host/frontend/gcastv2/webrtc/certs/server.crt
@@ -1,20 +1,20 @@
 -----BEGIN CERTIFICATE-----
-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
+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
 -----END CERTIFICATE-----
diff --git a/host/frontend/gcastv2/webrtc/certs/server.p12 b/host/frontend/gcastv2/webrtc/certs/server.p12
index 3d0d595..87a94c5 100644
--- a/host/frontend/gcastv2/webrtc/certs/server.p12
+++ b/host/frontend/gcastv2/webrtc/certs/server.p12
Binary files differ
diff --git a/host/frontend/gcastv2/webrtc/certs/trusted.pem b/host/frontend/gcastv2/webrtc/certs/trusted.pem
index b2080b4..8097b16 100644
--- a/host/frontend/gcastv2/webrtc/certs/trusted.pem
+++ b/host/frontend/gcastv2/webrtc/certs/trusted.pem
@@ -1,16 +1,17 @@
 Certificate:
     Data:
         Version: 1 (0x0)
-        Serial Number: 12406396960093165066 (0xac2c604da4d6d60a)
-    Signature Algorithm: sha256WithRSAEncryption
-        Issuer: C=US, ST=California, L=Santa Clara, O=Beyond Aggravated, CN=localhost
+        Serial Number:
+            15:c1:c9:dc:34:7b:fe:e5:df:57:7d:7f:33:bb:be:b0:71:03:0e:32
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = US, ST = California, L = Santa Clara, O = Beyond Aggravated, CN = localhost
         Validity
-            Not Before: May  8 20:11:49 2019 GMT
-            Not After : May  7 20:11:49 2020 GMT
-        Subject: C=US, ST=California, L=Santa Clara, O=Beyond Aggravated, CN=localhost
+            Not Before: May  7 21:33:01 2020 GMT
+            Not After : May  7 21:33:01 2021 GMT
+        Subject: C = US, ST = California, L = Santa Clara, O = Beyond Aggravated, CN = localhost
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
-                Public-Key: (2048 bit)
+                RSA Public-Key: (2048 bit)
                 Modulus:
                     00:f7:73:d1:3a:26:d4:d4:ae:8f:0c:58:16:11:b6:
                     32:7a:93:4d:4e:45:f4:4e:4e:c2:73:bd:b2:f9:57:
@@ -32,38 +33,38 @@
                     9b:55
                 Exponent: 65537 (0x10001)
     Signature Algorithm: sha256WithRSAEncryption
-         f4:3e:ed:b5:ef:cb:f4:52:c7:d9:60:48:08:8e:fd:1e:5e:a7:
-         74:a2:db:15:94:7b:48:58:8a:f9:90:d5:b5:f6:f3:41:69:0c:
-         ff:2d:65:7b:40:90:88:69:c9:67:62:4b:46:98:04:cc:92:2c:
-         30:c3:88:39:76:c5:45:9f:c5:93:b4:36:73:9c:54:9d:7b:8d:
-         9d:ac:27:18:6a:2a:4b:16:34:c4:cb:6f:b7:42:af:b9:14:4b:
-         6f:85:3a:e5:f0:47:e6:1e:6f:be:ee:a7:67:b9:e2:55:cb:ba:
-         22:95:59:eb:c5:01:45:5c:f1:78:60:ab:fb:0d:cf:6a:f0:b7:
-         98:86:5c:57:0b:09:7a:04:80:bc:07:9d:de:cb:05:1f:32:e8:
-         8b:04:7d:55:b9:51:54:96:a4:54:0f:38:37:5c:62:d5:60:69:
-         66:28:ed:36:20:85:98:f3:13:26:bc:54:87:3b:1e:01:e5:1f:
-         fd:54:8f:dc:af:87:e7:98:da:12:e8:2f:0b:a4:65:15:7f:0a:
-         73:1b:4a:4f:0b:2e:04:d8:b8:47:8b:7c:fb:92:9c:24:c4:46:
-         bc:9d:30:4c:91:70:5d:c7:96:30:ad:86:05:7b:61:1b:7c:71:
-         0a:2f:b1:56:41:be:e3:11:25:8c:e5:e2:13:37:7a:66:b4:d0:
-         fc:7b:48:3f
+         49:9c:74:40:63:51:e4:34:fc:bd:48:04:05:33:03:d4:e2:86:
+         de:b1:70:cd:72:c8:d4:bb:27:e6:72:0c:48:69:0b:ed:a2:25:
+         c7:b0:fc:95:b7:6f:cb:43:92:f8:28:3c:8c:4d:b9:eb:28:8c:
+         ed:c6:53:17:4e:eb:2b:05:1e:23:6b:ff:c0:3a:d7:28:ff:6a:
+         7c:c8:68:9c:80:ab:6d:0c:8a:95:9e:89:e2:12:d5:57:dc:02:
+         91:84:27:32:ac:12:fa:e4:87:d6:5d:57:fa:aa:f7:64:27:1a:
+         9a:04:d9:da:1a:e1:24:5c:b8:1c:47:a8:0b:8a:9d:2f:4f:ae:
+         33:63:61:ae:39:8f:06:fa:8c:ab:d8:58:59:ed:e7:01:11:26:
+         46:34:80:c4:13:1a:c2:34:e1:95:d2:ea:40:2a:28:ca:fb:4c:
+         b2:49:27:40:0c:cf:b5:ef:ea:bc:fe:24:59:1a:48:f8:a4:04:
+         bf:d4:5c:f2:22:3d:3c:d0:85:f7:e5:b8:ce:5e:a9:23:24:43:
+         45:56:16:c7:70:b5:3d:27:67:89:a4:dc:ff:20:d0:14:be:54:
+         6e:e6:79:ba:35:0e:76:f3:32:d7:20:25:71:38:83:56:8f:8a:
+         7b:bc:9b:00:af:45:84:40:71:30:f1:0b:c9:31:53:63:41:95:
+         28:8e:3a:40
 -----BEGIN CERTIFICATE-----
-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
+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
 -----END CERTIFICATE-----
diff --git a/host/libs/config/cuttlefish_config.cpp b/host/libs/config/cuttlefish_config.cpp
index ee3d67e..1b1403b 100644
--- a/host/libs/config/cuttlefish_config.cpp
+++ b/host/libs/config/cuttlefish_config.cpp
@@ -157,6 +157,7 @@
 const char* kBootImageKernelCmdline = "boot_image_kernel_cmdline";
 const char* kExtraKernelCmdline = "extra_kernel_cmdline";
 
+const char* kWifiMacAddress = "wifi_mac_address";
 }  // namespace
 
 namespace vsoc {
@@ -793,6 +794,28 @@
   return (*dictionary_)[kGuestForceNormalBoot].asBool();
 }
 
+void CuttlefishConfig::MutableInstanceSpecific::set_wifi_mac_address(
+    const std::array<unsigned char, 6>& mac_address) {
+  Json::Value mac_address_obj(Json::arrayValue);
+  for (const auto& num : mac_address) {
+    mac_address_obj.append(num);
+  }
+  (*Dictionary())[kWifiMacAddress] = mac_address_obj;
+}
+
+std::array<unsigned char, 6> CuttlefishConfig::InstanceSpecific::wifi_mac_address() const {
+  std::array<unsigned char, 6> mac_address{0, 0, 0, 0, 0, 0};
+  auto mac_address_obj = (*Dictionary())[kWifiMacAddress];
+  if (mac_address_obj.size() != 6) {
+    LOG(ERROR) << kWifiMacAddress << " entry had wrong size";
+    return {};
+  }
+  for (int i = 0; i < 6; i++) {
+    mac_address[i] = mac_address_obj[i].asInt();
+  }
+  return mac_address;
+}
+
 void CuttlefishConfig::set_boot_image_kernel_cmdline(std::string boot_image_kernel_cmdline) {
   Json::Value args_json_obj(Json::arrayValue);
   for (const auto& arg : android::base::Split(boot_image_kernel_cmdline, " ")) {
diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h
index 005b1b2..45c15e1 100644
--- a/host/libs/config/cuttlefish_config.h
+++ b/host/libs/config/cuttlefish_config.h
@@ -15,6 +15,7 @@
  */
 #pragma once
 
+#include <array>
 #include <memory>
 #include <string>
 #include <set>
@@ -322,6 +323,9 @@
     std::string launcher_monitor_socket_path() const;
 
     std::string sdcard_path() const;
+
+    // Wifi MAC address inside the guest
+    std::array<unsigned char, 6> wifi_mac_address() const;
   };
 
   // A view into an existing CuttlefishConfig object for a particular instance.
@@ -347,6 +351,8 @@
     void set_uuid(const std::string& uuid);
     void set_instance_dir(const std::string& instance_dir);
     void set_virtual_disk_paths(const std::vector<std::string>& disk_paths);
+    // Wifi MAC address inside the guest
+    void set_wifi_mac_address(const std::array<unsigned char, 6>&);
   };
 
  private:
diff --git a/shared/auto/device.mk b/shared/auto/device.mk
index 9a50cda..1c036cc 100644
--- a/shared/auto/device.mk
+++ b/shared/auto/device.mk
@@ -73,6 +73,10 @@
     libcuttlefish-ril \
     libcuttlefish-rild
 
+# system_other support
+PRODUCT_PACKAGES += \
+    cppreopts.sh \
+
 BOARD_IS_AUTOMOTIVE := true
 
 $(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base.mk)
diff --git a/shared/sepolicy/system_ext/private/permissioncontroller_app.te b/shared/sepolicy/system_ext/private/permissioncontroller_app.te
new file mode 100644
index 0000000..845592a
--- /dev/null
+++ b/shared/sepolicy/system_ext/private/permissioncontroller_app.te
@@ -0,0 +1 @@
+gpu_access(permissioncontroller_app)
diff --git a/shared/sepolicy/system_ext/private/te_macros b/shared/sepolicy/system_ext/private/te_macros
new file mode 100644
index 0000000..5c74dfa
--- /dev/null
+++ b/shared/sepolicy/system_ext/private/te_macros
@@ -0,0 +1,8 @@
+#####################################
+# gpu_access(client_domain)
+# Allow client_domain to communicate with the virgl GPU
+define(`gpu_access', `
+allow $1 gpu_device:dir { open read search };
+allow $1 gpu_device:chr_file { getattr ioctl map open read write };
+allow $1 graphics_device:chr_file { getattr };
+')
diff --git a/shared/sepolicy/vendor/property_contexts b/shared/sepolicy/vendor/property_contexts
index 7deeacf..ab29527 100644
--- a/shared/sepolicy/vendor/property_contexts
+++ b/shared/sepolicy/vendor/property_contexts
@@ -14,6 +14,7 @@
 ro.boot.vsock_keyboard_port  u:object_r:cuttlefish_vsock_keyboard_port:s0
 ro.boot.vsock_logcat_port  u:object_r:vsock_logcat_port_prop:s0
 ro.boot.vsock_touch_port  u:object_r:cuttlefish_vsock_touch_port:s0
+ro.boot.wifi_mac_address  u:object_r:cuttlefish_wifi_mac_address:s0
 ro.cdma.home.operator.alpha  u:object_r:vendor_init_radio_prop:s0
 ro.cdma.home.operator.numeric  u:object_r:vendor_init_radio_prop:s0
 sys.cf.ser.  u:object_r:sys_cf_ser_prop:s0
diff --git a/shared/sepolicy/vendor/setup_wifi.te b/shared/sepolicy/vendor/setup_wifi.te
index e6ec279..a6bd363 100644
--- a/shared/sepolicy/vendor/setup_wifi.te
+++ b/shared/sepolicy/vendor/setup_wifi.te
@@ -8,3 +8,7 @@
 allow setup_wifi self:netlink_route_socket { bind create nlmsg_write read write };
 
 allow setup_wifi kernel:system module_request;
+
+type cuttlefish_wifi_mac_address, property_type;
+
+get_prop(setup_wifi, cuttlefish_wifi_mac_address)