96 lines
2.8 KiB
Rust
96 lines
2.8 KiB
Rust
use super::Stage;
|
|
use std::collections::BTreeMap;
|
|
use std::fs;
|
|
use std::os::unix::fs::MetadataExt;
|
|
|
|
#[allow(dead_code)]
|
|
#[path = "support/native_elf.rs"]
|
|
mod elf;
|
|
|
|
fn prepared(files: &BTreeMap<String, (Vec<u8>, bool)>) -> Stage {
|
|
let stage = Stage::new().unwrap();
|
|
for (path, (bytes, executable)) in files {
|
|
stage
|
|
.write(&format!("input/{path}"), bytes, *executable)
|
|
.unwrap();
|
|
}
|
|
stage
|
|
}
|
|
|
|
#[test]
|
|
fn signed_tool_libraries_share_bytes_without_replacing_host_glibc() {
|
|
let names = [
|
|
"libbfd.so",
|
|
"libstdc++.so.6",
|
|
"libgcc_s.so.1",
|
|
"libc.so.6",
|
|
"libm.so.6",
|
|
"libmvec.so.1",
|
|
"libanl.so.1",
|
|
"libdl.so.2",
|
|
"libpthread.so.0",
|
|
"librt.so.1",
|
|
"libutil.so.1",
|
|
"libresolv.so.2",
|
|
"ld-linux-x86-64.so.2",
|
|
"ld-linux-aarch64.so.1",
|
|
];
|
|
let files = names
|
|
.into_iter()
|
|
.map(|name| {
|
|
(
|
|
format!("rootfs/usr/lib/fixture/{name}"),
|
|
(elf::library(name, &[]), false),
|
|
)
|
|
})
|
|
.collect();
|
|
let stage = prepared(&files);
|
|
stage.link_tool_libraries(&files).unwrap();
|
|
for name in names {
|
|
let destination = stage.0.join("input/lib").join(name);
|
|
if matches!(name, "libbfd.so" | "libstdc++.so.6" | "libgcc_s.so.1") {
|
|
let source = stage.0.join("input/rootfs/usr/lib/fixture").join(name);
|
|
assert_eq!(
|
|
fs::metadata(&source).unwrap().ino(),
|
|
fs::metadata(&destination).unwrap().ino()
|
|
);
|
|
assert_eq!(fs::read(source).unwrap(), fs::read(destination).unwrap());
|
|
} else {
|
|
assert!(!destination.exists());
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn duplicate_sonames_require_identical_signed_bytes() {
|
|
let original = elf::library("libfixture.so", &[]);
|
|
let mut files = BTreeMap::from([
|
|
("rootfs/usr/lib/first.so".into(), (original.clone(), false)),
|
|
("rootfs/usr/lib/second.so".into(), (original, false)),
|
|
]);
|
|
let stage = prepared(&files);
|
|
stage.link_tool_libraries(&files).unwrap();
|
|
files.get_mut("rootfs/usr/lib/second.so").unwrap().0 =
|
|
elf::library("libfixture.so", &["libc.so.6"]);
|
|
let stage = prepared(&files);
|
|
assert!(
|
|
stage
|
|
.link_tool_libraries(&files)
|
|
.unwrap_err()
|
|
.contains("conflicting SONAMEs")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn tool_library_names_cannot_escape_the_owned_search_directory() {
|
|
for name in ["../escape.so", "/escape.so", "nested/escape.so"] {
|
|
let files = BTreeMap::from([(
|
|
"rootfs/usr/lib/fixture.so".into(),
|
|
(elf::library(name, &[]), false),
|
|
)]);
|
|
let stage = prepared(&files);
|
|
assert!(stage.link_tool_libraries(&files).is_err());
|
|
assert!(!stage.0.join("input/escape.so").exists());
|
|
}
|
|
}
|