From 12dff54a6acf271e367a8fb0c3d149d6554d9d90 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Wed, 5 Apr 2023 00:54:46 -0700 Subject: [PATCH] Fix same issue in bootstrap --- src/bootstrap/util.rs | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 9a6aaffe22b..8cea8c97407 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -212,18 +212,35 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> { struct Align8(T); let mut data = Align8([0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize]); let db = data.0.as_mut_ptr() as *mut REPARSE_MOUNTPOINT_DATA_BUFFER; - let buf = core::ptr::addr_of_mut!((*db).ReparseTarget) as *mut u16; - let mut i = 0; + let end = db.cast::().add(MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize); + let reparse_target_slice = { + let buf_start = core::ptr::addr_of_mut!((*db).ReparseTarget).cast::(); + // Compute offset in bytes and then divide so that we round down + // rather than hit any UB (admittedly this arithmetic should work + // out so that this isn't necessary) + let buf_len_bytes = + usize::try_from(end.offset_from(buf_start.cast::())).unwrap(); + let buf_len_wchars = buf_len_bytes / core::mem::size_of::(); + core::slice::from_raw_parts_mut(buf_start, buf_len_wchars) + }; + // FIXME: this conversion is very hacky - let v = br"\??\"; - let v = v.iter().map(|x| *x as u16); - for c in v.chain(target.as_os_str().encode_wide().skip(4)) { - *buf.offset(i) = c; + let iter = br"\??\" + .iter() + .map(|x| *x as u16) + .chain(path.iter().copied()) + .chain(core::iter::once(0)); + let mut i = 0; + for c in iter { + if i >= reparse_target_slice.len() { + return Err(io::Error::new( + io::ErrorKind::Other, + format!("path too long for reparse target: {target:?}"), + )); + } + reparse_target_slice[i] = c; i += 1; } - *buf.offset(i) = 0; - i += 1; - (*db).ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; (*db).ReparseTargetMaximumLength = (i * 2) as u16; (*db).ReparseTargetLength = ((i - 1) * 2) as u16;