From bac2509ccd74c5ee97c1c1c891164878c6e68e80 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Fri, 8 Jul 2022 12:27:17 +0200 Subject: [PATCH] Fix leaks for setuid/setgid too. --- src/platform/redox/mod.rs | 19 +++++++++++++------ src/platform/redox/redox-exec/src/lib.rs | 4 ++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index ab5deedb..b456e85d 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -385,9 +385,12 @@ impl Pal for Sys { } if !is_interpreted && wants_setugid { + // Make sure the last file descriptor not covered by O_CLOEXEC is not leaked. + drop(file); + let name = CStr::from_bytes_with_nul(b"escalate:\0").expect("string should be valid"); // We are now going to invoke `escalate:` rather than loading the program ourselves. - let mut escalate_fd = match File::open(name, fcntl::O_WRONLY | fcntl::O_CLOEXEC) { + let mut escalate_fd = match File::open(name, fcntl::O_WRONLY) { Ok(f) => f, Err(_) => return -1, }; @@ -408,7 +411,7 @@ impl Pal for Sys { } // Second, we write the flattened args and envs with NUL characters separating - // individual items. + // individual items. This can be copied directly into the new executable's memory. if escalate_fd.write_all(&flatten_with_nul(args)).is_err() { return -1; } @@ -416,10 +419,14 @@ impl Pal for Sys { return -1; } - // escalated will take care of the rest when responding to SYS_CLOSE. - // FIXME: close escalate_fd - if escalate_fd.write(&[]).is_err() { - return -1; + // Closing will notify the scheme, and from that point we will no longer have control + // over this process (unless it fails). We do this manually since drop cannot handle + // errors. + let fd = *escalate_fd as usize; + core::mem::forget(escalate_fd); + + if let Err(err) = syscall::close(fd) { + return e(Err(err)) as c_int; } unreachable!() diff --git a/src/platform/redox/redox-exec/src/lib.rs b/src/platform/redox/redox-exec/src/lib.rs index aba5125c..aecb2b1b 100644 --- a/src/platform/redox/redox-exec/src/lib.rs +++ b/src/platform/redox/redox-exec/src/lib.rs @@ -61,7 +61,7 @@ where let mut tree = BTreeMap::new(); tree.insert(0, PAGE_SIZE); - const BUFSZ: usize = 16384; + const BUFSZ: usize = 65536; let mut buf = vec! [0_u8; BUFSZ]; read_all(*image_file as usize, Some(header.e_phoff), &mut phs).map_err(|_| Error::new(EIO))?; @@ -91,7 +91,7 @@ where syscall::lseek(*image_file as usize, segment.p_offset as isize, SEEK_SET).map_err(|_| Error::new(EIO))?; syscall::lseek(*memory_fd, segment.p_vaddr as isize, SEEK_SET).map_err(|_| Error::new(EIO))?; - for size in core::iter::repeat(BUFSZ).take((segment.p_filesz as usize) / BUFSZ).chain(Some((segment.p_filesz as usize) % BUFSZ)) { + for size in core::iter::repeat(buf.len()).take((segment.p_filesz as usize) / buf.len()).chain(Some((segment.p_filesz as usize) % buf.len())) { read_all(*image_file as usize, None, &mut buf[..size]).map_err(|_| Error::new(EIO))?; let _ = syscall::write(*memory_fd, &buf[..size]).map_err(|_| Error::new(EIO))?; } -- GitLab