Skip to content

Instantly share code, notes, and snippets.

@Muirey03
Created March 20, 2026 10:45
Show Gist options
  • Select an option

  • Save Muirey03/8c8370258e32bafaf99e72ec90258c8d to your computer and use it in GitHub Desktop.

Select an option

Save Muirey03/8c8370258e32bafaf99e72ec90258c8d to your computer and use it in GitHub Desktop.
CVE-2025-43520 - DarkSword
1. cluster_read_ext and cluster_write_ext call cluster_io_type to determine what IO operation to perform
2. cluster_io_type calls vm_map_get_upl with UPL_QUERY_OBJECT_TYPE to query type of the vm_object that backs the user-supplied virtual address range
3. If this object is physically contiguous it returns IO_CONTIG, otherwise it returns IO_DIRECT or IO_COPY
4. If cluster_io_type returns IO_CONTIG, cluster_[read|write]_ext will call the "contig" variant, cluster_[read|write]_contig
5. cluster_[read|write]_contig then calls vm_map_get_upl a second time to get the UPL from the uio
6. It then grabs the first physical page from the UPL using upl_phys_page and performs a physical copy
7. This is a TOCTOU. An attacker can remap the virtual address range so that the region is no longer physically contiguous after the first call to vm_map_get_upl, causing an OOBR/OOBW to physmem
The Patch:
index 806e747ac..c5dee0a7c 100644
--- a/bsd/vfs/vfs_cluster.c
+++ b/bsd/vfs/vfs_cluster.c
@@ -3689,6 +3697,14 @@ next_cwrite:
}
num_upl++;
+ if (!(upl_flags & UPL_PHYS_CONTIG)) {
+ /*
+ * The created UPL needs to have the UPL_PHYS_CONTIG flag.
+ */
+ error = EINVAL;
+ goto wait_for_cwrites;
+ }
+
@@ -6082,6 +6102,14 @@ next_cread:
}
num_upl++;
+ if (!(upl_flags & UPL_PHYS_CONTIG)) {
+ /*
+ * The created UPL needs to have the UPL_PHYS_CONTIG flag.
+ */
+ error = EINVAL;
+ goto wait_for_creads;
+ }
+
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment