Merge changes I7cd7e619,Iaaf283e9,I06f71453

* changes:
  pvmfw: config: Tolerate invalid zero-sized entries
  pvmfw: config: Clarify error logs during parsing
  pvmfw: config: Refactor entry tracking
diff --git a/authfs/fd_server/src/main.rs b/authfs/fd_server/src/main.rs
index 21d0e64..9d97423 100644
--- a/authfs/fd_server/src/main.rs
+++ b/authfs/fd_server/src/main.rs
@@ -37,7 +37,8 @@
 use aidl::{FdConfig, FdService};
 use authfs_fsverity_metadata::parse_fsverity_metadata;
 
-const RPC_SERVICE_PORT: u32 = 3264; // TODO: support dynamic port for multiple fd_server instances
+// TODO(b/259920193): support dynamic port for multiple fd_server instances
+const RPC_SERVICE_PORT: u32 = 3264;
 
 fn is_fd_valid(fd: i32) -> bool {
     // SAFETY: a query-only syscall
@@ -137,7 +138,8 @@
 
     debug!("fd_server is starting as a rpc service.");
     let service = FdService::new_binder(fd_pool).as_binder();
-    let server = RpcServer::new_vsock(service, RPC_SERVICE_PORT)?;
+    // TODO(b/259920193): Only accept connections from the intended guest VM.
+    let server = RpcServer::new_vsock(service, libc::VMADDR_CID_ANY, RPC_SERVICE_PORT)?;
     debug!("fd_server is ready");
 
     // Close the ready-fd if we were given one to signal our readiness.
diff --git a/compos/common/lib.rs b/compos/common/lib.rs
index c9555d5..8d49ff0 100644
--- a/compos/common/lib.rs
+++ b/compos/common/lib.rs
@@ -21,9 +21,6 @@
 pub mod odrefresh;
 pub mod timeouts;
 
-/// Special CID indicating "any".
-pub const VMADDR_CID_ANY: u32 = -1i32 as u32;
-
 /// VSock port that the CompOS server listens on for RPC binder connections. This should be out of
 /// future port range (if happens) that microdroid may reserve for system components.
 pub const COMPOS_VSOCK_PORT: u32 = 6432;
diff --git a/javalib/api/system-current.txt b/javalib/api/system-current.txt
index c98c62e..04283c2 100644
--- a/javalib/api/system-current.txt
+++ b/javalib/api/system-current.txt
@@ -6,7 +6,6 @@
     method public void close();
     method @NonNull public android.os.IBinder connectToVsockServer(int) throws android.system.virtualmachine.VirtualMachineException;
     method @NonNull public android.os.ParcelFileDescriptor connectVsock(int) throws android.system.virtualmachine.VirtualMachineException;
-    method public int getCid() throws android.system.virtualmachine.VirtualMachineException;
     method @NonNull public android.system.virtualmachine.VirtualMachineConfig getConfig();
     method @NonNull public java.io.InputStream getConsoleOutput() throws android.system.virtualmachine.VirtualMachineException;
     method @NonNull public java.io.InputStream getLogOutput() throws android.system.virtualmachine.VirtualMachineException;
@@ -74,8 +73,8 @@
     method @NonNull public android.system.virtualmachine.VirtualMachineConfig build();
     method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setApkPath(@NonNull String);
     method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setDebugLevel(int);
-    method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setEncryptedStorageKib(@IntRange(from=0) long);
-    method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setMemoryMib(@IntRange(from=0) int);
+    method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setEncryptedStorageKib(@IntRange(from=1) long);
+    method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setMemoryMib(@IntRange(from=1) int);
     method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setNumCpus(@IntRange(from=1) int);
     method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setPayloadBinaryPath(@NonNull String);
     method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setProtectedVm(boolean);
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachine.java b/javalib/src/android/system/virtualmachine/VirtualMachine.java
index 504d3c7..c061003 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachine.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachine.java
@@ -940,23 +940,6 @@
     }
 
     /**
-     * Returns the CID of this virtual machine, if it is running.
-     *
-     * @throws VirtualMachineException if the virtual machine is not running.
-     * @hide
-     */
-    @SystemApi
-    public int getCid() throws VirtualMachineException {
-        synchronized (mLock) {
-            try {
-                return getRunningVm().getCid();
-            } catch (RemoteException e) {
-                throw e.rethrowAsRuntimeException();
-            }
-        }
-    }
-
-    /**
      * Changes the config of this virtual machine to a new one. This can be used to adjust things
      * like the number of CPU and size of the RAM, depending on the situation (e.g. the size of the
      * application to run on the virtual machine, etc.)
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java b/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
index 459b614..602f8b8 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
@@ -55,6 +55,8 @@
  */
 @SystemApi
 public final class VirtualMachineConfig {
+    private static final String[] EMPTY_STRING_ARRAY = {};
+
     // These define the schema of the config file persisted on disk.
     private static final int VERSION = 2;
     private static final String KEY_VERSION = "version";
@@ -133,49 +135,7 @@
             int memoryMib,
             int numCpus,
             long encryptedStorageKib) {
-        requireNonNull(apkPath);
-        if (!apkPath.startsWith("/")) {
-            throw new IllegalArgumentException("APK path must be an absolute path");
-        }
-
-        if (memoryMib < 0) {
-            throw new IllegalArgumentException("Memory size cannot be negative");
-        }
-
-        int availableCpus = Runtime.getRuntime().availableProcessors();
-        if (numCpus < 1 || numCpus > availableCpus) {
-            throw new IllegalArgumentException("Number of vCPUs (" + numCpus + ") is out of "
-                    + "range [1, " + availableCpus + "]");
-        }
-
-        if (debugLevel != DEBUG_LEVEL_NONE && debugLevel != DEBUG_LEVEL_FULL) {
-            throw new IllegalArgumentException("Invalid debugLevel: " + debugLevel);
-        }
-
-        if (payloadBinaryPath == null) {
-            if (payloadConfigPath == null) {
-                throw new IllegalStateException("setPayloadBinaryPath must be called");
-            }
-        } else {
-            if (payloadConfigPath != null) {
-                throw new IllegalStateException(
-                        "setPayloadBinaryPath and setPayloadConfigPath may not both be called");
-            }
-        }
-
-        if (protectedVm
-                && !HypervisorProperties.hypervisor_protected_vm_supported().orElse(false)) {
-            throw new UnsupportedOperationException(
-                    "Protected VMs are not supported on this device.");
-        }
-        if (!protectedVm && !HypervisorProperties.hypervisor_vm_supported().orElse(false)) {
-            throw new UnsupportedOperationException(
-                    "Unprotected VMs are not supported on this device.");
-        }
-        if (encryptedStorageKib < 0) {
-            throw new IllegalArgumentException("Encrypted Storage size cannot be negative");
-        }
-
+        // This is only called from Builder.build(); the builder handles parameter validation.
         mApkPath = apkPath;
         mPayloadConfigPath = payloadConfigPath;
         mPayloadBinaryPath = payloadBinaryPath;
@@ -212,40 +172,48 @@
     private static VirtualMachineConfig fromInputStream(@NonNull InputStream input)
             throws IOException, VirtualMachineException {
         PersistableBundle b = PersistableBundle.readFromStream(input);
+        try {
+            return fromPersistableBundle(b);
+        } catch (NullPointerException | IllegalArgumentException | IllegalStateException e) {
+            throw new VirtualMachineException("Persisted VM config is invalid", e);
+        }
+    }
+
+    @NonNull
+    private static VirtualMachineConfig fromPersistableBundle(PersistableBundle b) {
         int version = b.getInt(KEY_VERSION);
         if (version > VERSION) {
-            throw new VirtualMachineException("Version too high");
+            throw new IllegalArgumentException(
+                    "Version " + version + " too high; current is " + VERSION);
         }
-        String apkPath = b.getString(KEY_APKPATH);
-        if (apkPath == null) {
-            throw new VirtualMachineException("No apkPath");
+
+        Builder builder = new Builder();
+        builder.setApkPath(b.getString(KEY_APKPATH));
+
+        String payloadConfigPath = b.getString(KEY_PAYLOADCONFIGPATH);
+        if (payloadConfigPath == null) {
+            builder.setPayloadBinaryPath(b.getString(KEY_PAYLOADBINARYPATH));
+        } else {
+            builder.setPayloadConfigPath(payloadConfigPath);
         }
-        String payloadBinaryPath = b.getString(KEY_PAYLOADBINARYPATH);
-        String payloadConfigPath = null;
-        if (payloadBinaryPath == null) {
-            payloadConfigPath = b.getString(KEY_PAYLOADCONFIGPATH);
-            if (payloadConfigPath == null) {
-                throw new VirtualMachineException("No payloadBinaryPath");
-            }
-        }
+
         @DebugLevel int debugLevel = b.getInt(KEY_DEBUGLEVEL);
         if (debugLevel != DEBUG_LEVEL_NONE && debugLevel != DEBUG_LEVEL_FULL) {
-            throw new VirtualMachineException("Invalid debugLevel: " + debugLevel);
+            throw new IllegalArgumentException("Invalid debugLevel: " + debugLevel);
         }
-        boolean protectedVm = b.getBoolean(KEY_PROTECTED_VM);
+        builder.setDebugLevel(debugLevel);
+        builder.setProtectedVm(b.getBoolean(KEY_PROTECTED_VM));
         int memoryMib = b.getInt(KEY_MEMORY_MIB);
-        int numCpus = b.getInt(KEY_NUM_CPUS);
+        if (memoryMib != 0) {
+            builder.setMemoryMib(memoryMib);
+        }
+        builder.setNumCpus(b.getInt(KEY_NUM_CPUS));
         long encryptedStorageKib = b.getLong(KEY_ENCRYPTED_STORAGE_KIB);
+        if (encryptedStorageKib != 0) {
+            builder.setEncryptedStorageKib(encryptedStorageKib);
+        }
 
-        return new VirtualMachineConfig(
-                apkPath,
-                payloadConfigPath,
-                payloadBinaryPath,
-                debugLevel,
-                protectedVm,
-                memoryMib,
-                numCpus,
-                encryptedStorageKib);
+        return builder.build();
     }
 
     /** Persists this config to a file. */
@@ -335,7 +303,8 @@
     }
 
     /**
-     * Returns the amount of RAM that will be made available to the VM.
+     * Returns the amount of RAM that will be made available to the VM, or 0 if the default size
+     * will be used.
      *
      * @hide
      */
@@ -426,9 +395,8 @@
         vsConfig.protectedVm = mProtectedVm;
         vsConfig.memoryMib = mMemoryMib;
         vsConfig.numCpus = mNumCpus;
-        // Don't allow apps to set task profiles ... at last for now. Also, don't forget to
-        // validate the string because these are appended to the cmdline argument.
-        vsConfig.taskProfiles = new String[0];
+        // Don't allow apps to set task profiles ... at least for now.
+        vsConfig.taskProfiles = EMPTY_STRING_ARRAY;
         return vsConfig;
     }
 
@@ -439,15 +407,15 @@
      */
     @SystemApi
     public static final class Builder {
-        private final Context mContext;
+        @Nullable private final Context mContext;
         @Nullable private String mApkPath;
         @Nullable private String mPayloadConfigPath;
         @Nullable private String mPayloadBinaryPath;
-        @DebugLevel private int mDebugLevel;
+        @DebugLevel private int mDebugLevel = DEBUG_LEVEL_NONE;
         private boolean mProtectedVm;
         private boolean mProtectedVmSet;
         private int mMemoryMib;
-        private int mNumCpus;
+        private int mNumCpus = 1;
         private long mEncryptedStorageKib;
 
         /**
@@ -458,9 +426,14 @@
         @SystemApi
         public Builder(@NonNull Context context) {
             mContext = requireNonNull(context, "context must not be null");
-            mDebugLevel = DEBUG_LEVEL_NONE;
-            mNumCpus = 1;
-            mEncryptedStorageKib = 0;
+        }
+
+        /**
+         * Creates a builder with no associated context; {@link #setApkPath} must be called to
+         * specify which APK contains the payload.
+         */
+        private Builder() {
+            mContext = null;
         }
 
         /**
@@ -471,7 +444,26 @@
         @SystemApi
         @NonNull
         public VirtualMachineConfig build() {
-            String apkPath = (mApkPath == null) ? mContext.getPackageCodePath() : mApkPath;
+            String apkPath;
+            if (mApkPath == null) {
+                if (mContext == null) {
+                    throw new IllegalStateException("apkPath must be specified");
+                }
+                apkPath = mContext.getPackageCodePath();
+            } else {
+                apkPath = mApkPath;
+            }
+
+            if (mPayloadBinaryPath == null) {
+                if (mPayloadConfigPath == null) {
+                    throw new IllegalStateException("setPayloadBinaryPath must be called");
+                }
+            } else {
+                if (mPayloadConfigPath != null) {
+                    throw new IllegalStateException(
+                            "setPayloadBinaryPath and setPayloadConfigPath may not both be called");
+                }
+            }
 
             if (!mProtectedVmSet) {
                 throw new IllegalStateException("setProtectedVm must be called explicitly");
@@ -497,7 +489,11 @@
         @SystemApi
         @NonNull
         public Builder setApkPath(@NonNull String apkPath) {
-            mApkPath = requireNonNull(apkPath);
+            requireNonNull(apkPath, "apkPath must not be null");
+            if (!apkPath.startsWith("/")) {
+                throw new IllegalArgumentException("APK path must be an absolute path");
+            }
+            mApkPath = apkPath;
             return this;
         }
 
@@ -512,7 +508,8 @@
         @TestApi
         @NonNull
         public Builder setPayloadConfigPath(@NonNull String payloadConfigPath) {
-            mPayloadConfigPath = requireNonNull(payloadConfigPath);
+            mPayloadConfigPath =
+                    requireNonNull(payloadConfigPath, "payloadConfigPath must not be null");
             return this;
         }
 
@@ -525,7 +522,8 @@
         @SystemApi
         @NonNull
         public Builder setPayloadBinaryPath(@NonNull String payloadBinaryPath) {
-            mPayloadBinaryPath = requireNonNull(payloadBinaryPath);
+            mPayloadBinaryPath =
+                    requireNonNull(payloadBinaryPath, "payloadBinaryPath must not be null");
             return this;
         }
 
@@ -537,6 +535,9 @@
         @SystemApi
         @NonNull
         public Builder setDebugLevel(@DebugLevel int debugLevel) {
+            if (debugLevel != DEBUG_LEVEL_NONE && debugLevel != DEBUG_LEVEL_FULL) {
+                throw new IllegalArgumentException("Invalid debugLevel: " + debugLevel);
+            }
             mDebugLevel = debugLevel;
             return this;
         }
@@ -551,20 +552,34 @@
         @SystemApi
         @NonNull
         public Builder setProtectedVm(boolean protectedVm) {
+            if (protectedVm) {
+                if (!HypervisorProperties.hypervisor_protected_vm_supported().orElse(false)) {
+                    throw new UnsupportedOperationException(
+                            "Protected VMs are not supported on this device.");
+                }
+            } else {
+                if (!HypervisorProperties.hypervisor_vm_supported().orElse(false)) {
+                    throw new UnsupportedOperationException(
+                            "Unprotected VMs are not supported on this device.");
+                }
+            }
             mProtectedVm = protectedVm;
             mProtectedVmSet = true;
             return this;
         }
 
         /**
-         * Sets the amount of RAM to give the VM, in mebibytes. If zero or not explicitly set then a
-         * default size will be used.
+         * Sets the amount of RAM to give the VM, in mebibytes. If not explicitly set then a default
+         * size will be used.
          *
          * @hide
          */
         @SystemApi
         @NonNull
-        public Builder setMemoryMib(@IntRange(from = 0) int memoryMib) {
+        public Builder setMemoryMib(@IntRange(from = 1) int memoryMib) {
+            if (memoryMib <= 0) {
+                throw new IllegalArgumentException("Memory size must be positive");
+            }
             mMemoryMib = memoryMib;
             return this;
         }
@@ -577,13 +592,24 @@
          */
         @SystemApi
         @NonNull
-        public Builder setNumCpus(@IntRange(from = 1) int num) {
-            mNumCpus = num;
+        public Builder setNumCpus(@IntRange(from = 1) int numCpus) {
+            int availableCpus = Runtime.getRuntime().availableProcessors();
+            if (numCpus < 1 || numCpus > availableCpus) {
+                throw new IllegalArgumentException(
+                        "Number of vCPUs ("
+                                + numCpus
+                                + ") is out of "
+                                + "range [1, "
+                                + availableCpus
+                                + "]");
+            }
+            mNumCpus = numCpus;
             return this;
         }
 
         /**
-         * Sets the size (in KB) of encrypted storage available to the VM.
+         * Sets the size (in KB) of encrypted storage available to the VM. If not set, no encrypted
+         * storage is provided.
          *
          * <p>The storage is encrypted with a key deterministically derived from the VM identity
          *
@@ -599,7 +625,10 @@
          */
         @SystemApi
         @NonNull
-        public Builder setEncryptedStorageKib(@IntRange(from = 0) long encryptedStorageKib) {
+        public Builder setEncryptedStorageKib(@IntRange(from = 1) long encryptedStorageKib) {
+            if (encryptedStorageKib <= 0) {
+                throw new IllegalArgumentException("Encrypted Storage size must be positive");
+            }
             mEncryptedStorageKib = encryptedStorageKib;
             return this;
         }
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index 3c490f4..6a37b88 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -77,7 +77,6 @@
 
 const APEX_CONFIG_DONE_PROP: &str = "apex_config.done";
 const DEBUGGABLE_PROP: &str = "ro.boot.microdroid.debuggable";
-const APK_MOUNT_DONE_PROP: &str = "microdroid_manager.apk.mounted";
 
 // SYNC WITH virtualizationservice/src/crosvm.rs
 const FAILURE_SERIAL_DEVICE: &str = "/dev/ttyS1";
@@ -383,15 +382,16 @@
         None
     };
 
+    let mut zipfuse = Zipfuse::default();
+
     // Before reading a file from the APK, start zipfuse
-    run_zipfuse(
+    zipfuse.mount(
         MountForExec::Allowed,
         "fscontext=u:object_r:zipfusefs:s0,context=u:object_r:system_file:s0",
         Path::new("/dev/block/mapper/microdroid-apk"),
         Path::new(VM_APK_CONTENTS_PATH),
-        Some(APK_MOUNT_DONE_PROP),
-    )
-    .context("Failed to run zipfuse")?;
+        "microdroid_manager.apk.mounted".to_owned(),
+    )?;
 
     // Restricted APIs are only allowed to be used by platform or test components. Infer this from
     // the use of a VM config file since those can only be used by platform and test components.
@@ -414,7 +414,7 @@
             verified_data.extra_apks_data.len()
         ));
     }
-    mount_extra_apks(&config)?;
+    mount_extra_apks(&config, &mut zipfuse)?;
 
     // Wait until apex config is done. (e.g. linker configuration for apexes)
     wait_for_apex_config_done()?;
@@ -428,8 +428,8 @@
         control_service("stop", "tombstoned")?;
     }
 
-    // Wait until zipfuse has mounted the APK so we can access the payload
-    wait_for_property_true(APK_MOUNT_DONE_PROP).context("Failed waiting for APK mount done")?;
+    // Wait until zipfuse has mounted the APKs so we can access the payload
+    zipfuse.wait_until_done()?;
 
     register_vm_payload_service(allow_restricted_apis, service.clone(), dice_context)?;
 
@@ -480,21 +480,40 @@
     Disallowed,
 }
 
-fn run_zipfuse(
-    noexec: MountForExec,
-    option: &str,
-    zip_path: &Path,
-    mount_dir: &Path,
-    ready_prop: Option<&str>,
-) -> Result<Child> {
-    let mut cmd = Command::new(ZIPFUSE_BIN);
-    if let MountForExec::Disallowed = noexec {
-        cmd.arg("--noexec");
+#[derive(Default)]
+struct Zipfuse {
+    ready_properties: Vec<String>,
+}
+
+impl Zipfuse {
+    fn mount(
+        &mut self,
+        noexec: MountForExec,
+        option: &str,
+        zip_path: &Path,
+        mount_dir: &Path,
+        ready_prop: String,
+    ) -> Result<Child> {
+        let mut cmd = Command::new(ZIPFUSE_BIN);
+        if let MountForExec::Disallowed = noexec {
+            cmd.arg("--noexec");
+        }
+        cmd.args(["-p", &ready_prop, "-o", option]);
+        cmd.arg(zip_path).arg(mount_dir);
+        self.ready_properties.push(ready_prop);
+        cmd.spawn().with_context(|| format!("Failed to run zipfuse for {mount_dir:?}"))
     }
-    if let Some(property_name) = ready_prop {
-        cmd.args(["-p", property_name]);
+
+    fn wait_until_done(self) -> Result<()> {
+        // We check the last-started check first in the hope that by the time it is done
+        // all or most of the others will also be done, minimising the number of times we
+        // block on a property.
+        for property in self.ready_properties.into_iter().rev() {
+            wait_for_property_true(&property)
+                .with_context(|| format!("Failed waiting for {property}"))?;
+        }
+        Ok(())
     }
-    cmd.arg("-o").arg(option).arg(zip_path).arg(mount_dir).spawn().context("Spawn zipfuse")
 }
 
 fn write_apex_payload_data(
@@ -664,21 +683,20 @@
     })
 }
 
-fn mount_extra_apks(config: &VmPayloadConfig) -> Result<()> {
+fn mount_extra_apks(config: &VmPayloadConfig, zipfuse: &mut Zipfuse) -> Result<()> {
     // For now, only the number of apks is important, as the mount point and dm-verity name is fixed
     for i in 0..config.extra_apks.len() {
-        let mount_dir = format!("/mnt/extra-apk/{}", i);
+        let mount_dir = format!("/mnt/extra-apk/{i}");
         create_dir(Path::new(&mount_dir)).context("Failed to create mount dir for extra apks")?;
 
         // don't wait, just detach
-        run_zipfuse(
+        zipfuse.mount(
             MountForExec::Disallowed,
             "fscontext=u:object_r:zipfusefs:s0,context=u:object_r:extra_apk_file:s0",
-            Path::new(&format!("/dev/block/mapper/extra-apk-{}", i)),
+            Path::new(&format!("/dev/block/mapper/extra-apk-{i}")),
             Path::new(&mount_dir),
-            None,
-        )
-        .context("Failed to zipfuse extra apks")?;
+            format!("microdroid_manager.extra_apk.mounted.{i}"),
+        )?;
     }
 
     Ok(())
diff --git a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
index 2cd4e51..25f2310 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -458,10 +458,10 @@
         VirtualMachineConfig.Builder builder =
                 newVmConfigBuilder()
                         .setPayloadBinaryPath("MicrodroidTestNativeLib.so")
-                        .setApkPath("relative/path/to.apk")
                         .setDebugLevel(DEBUG_LEVEL_FULL)
                         .setMemoryMib(minMemoryRequired());
-        assertThrows(IllegalArgumentException.class, () -> builder.build());
+        assertThrows(
+                IllegalArgumentException.class, () -> builder.setApkPath("relative/path/to.apk"));
     }
 
     @Test
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index 3e4323d..072afec 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -463,9 +463,8 @@
             let service = VirtualMachineService::new_binder(self.state.clone(), cid).as_binder();
 
             // Start VM service listening for connections from the new CID on port=CID.
-            // TODO(b/245727626): Only accept connections from the new VM.
             let port = cid;
-            match RpcServer::new_vsock(service, port) {
+            match RpcServer::new_vsock(service, cid, port) {
                 Ok(vm_server) => {
                     vm_server.start();
                     return Ok((VmContext::new(global_context, vm_server), cid));
diff --git a/vm_payload/src/api.rs b/vm_payload/src/api.rs
index 28b440e..66c8ef7 100644
--- a/vm_payload/src/api.rs
+++ b/vm_payload/src/api.rs
@@ -136,7 +136,7 @@
     // safely be taken by new_spibinder.
     let service = unsafe { new_spibinder(service) };
     if let Some(service) = service {
-        match RpcServer::new_vsock(service, port) {
+        match RpcServer::new_vsock(service, libc::VMADDR_CID_HOST, port) {
             Ok(server) => {
                 if let Some(on_ready) = on_ready {
                     // SAFETY: We're calling the callback with the parameter specified within the