mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-09-14 16:31:03 +03:00
fix(portable): validate executable path boundaries
Reject executables outside the source folder and reuse the package path normalization logic during stale file cleanup. Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
1
libs/portable/app_metadata.toml
Normal file
1
libs/portable/app_metadata.toml
Normal file
@@ -0,0 +1 @@
|
||||
timestamp = 1787231066609
|
||||
@@ -133,11 +133,16 @@ if __name__ == '__main__':
|
||||
# So we need to check if the executable is in the folder, and if so, concat again.
|
||||
if os.path.exists(os.path.join(folder, options.executable)):
|
||||
options.executable = os.path.join(folder, options.executable)
|
||||
folder_path = os.path.abspath(folder)
|
||||
exe: str = os.path.abspath(options.executable)
|
||||
if not exe.startswith(os.path.abspath(folder)):
|
||||
try:
|
||||
in_source_folder = os.path.commonpath([folder_path, exe]) == folder_path
|
||||
except ValueError:
|
||||
in_source_folder = False
|
||||
if not in_source_folder:
|
||||
print("The executable must locate in source folder")
|
||||
exit(-1)
|
||||
exe = '.' + exe[len(os.path.abspath(folder)):]
|
||||
exe = '.' + exe[len(folder_path):]
|
||||
print("Executable path: " + exe)
|
||||
print("Compression level: " + str(options.level))
|
||||
md5_table = generate_md5_table(
|
||||
|
||||
@@ -90,7 +90,7 @@ fn merge(
|
||||
(files, exe)
|
||||
}
|
||||
|
||||
fn normalize_path(path: &str) -> String {
|
||||
pub(crate) fn normalize_path(path: &str) -> String {
|
||||
path.replace('\\', "/")
|
||||
.trim_start_matches("./")
|
||||
.to_lowercase()
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::{
|
||||
process::{Command, Stdio},
|
||||
};
|
||||
|
||||
use bin_reader::BinaryReader;
|
||||
use bin_reader::{normalize_path, BinaryReader};
|
||||
|
||||
pub mod bin_reader;
|
||||
#[cfg(windows)]
|
||||
@@ -84,12 +84,6 @@ fn previous_package_files(dir: &Path) -> Vec<String> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn normalized(path: &str) -> String {
|
||||
path.replace('\\', "/")
|
||||
.trim_start_matches("./")
|
||||
.to_lowercase()
|
||||
}
|
||||
|
||||
// meta.toml is plain text in a user-writable directory, and it now drives deletion,
|
||||
// so the path is rebuilt from plain components rather than joined as written. A
|
||||
// prefix, root or parent component would otherwise escape the extraction directory:
|
||||
@@ -133,10 +127,11 @@ fn remove_dropped_package_files_with<F>(
|
||||
where
|
||||
F: FnMut(&Path) -> std::io::Result<()>,
|
||||
{
|
||||
let keep: std::collections::HashSet<String> = current.iter().map(|p| normalized(p)).collect();
|
||||
let keep: std::collections::HashSet<String> =
|
||||
current.iter().map(|p| normalize_path(p)).collect();
|
||||
let mut failed = Vec::new();
|
||||
for previous in previous_package_files(dir) {
|
||||
if keep.contains(&normalized(&previous)) {
|
||||
if keep.contains(&normalize_path(&previous)) {
|
||||
continue;
|
||||
}
|
||||
let Some(path) = resolve_within(dir, &previous) else {
|
||||
|
||||
Reference in New Issue
Block a user