add flag to forward specific env vars (while isolation remains enabled)

This commit is contained in:
Ralf Jung 2022-03-05 11:09:50 -05:00
parent a715171534
commit 3adc203c1c
5 changed files with 29 additions and 7 deletions

View File

@ -236,10 +236,13 @@ environment variable:
execution with a "permission denied" error being returned to the program.
`warn` prints a full backtrace when that happen; `warn-nobacktrace` is less
verbose. `hide` hides the warning entirely.
* `-Zmiri-env-exclude=<var>` keeps the `var` environment variable isolated from
the host so that it cannot be accessed by the program. Can be used multiple
times to exclude several variables. On Windows, the `TERM` environment
variable is excluded by default.
* `-Zmiri-env-exclude=<var>` keeps the `var` environment variable isolated from the host so that it
cannot be accessed by the program. Can be used multiple times to exclude several variables. On
Windows, the `TERM` environment variable is excluded by default. This has no effect unless
`-Zmiri-disable-validation` is also set.
* `-Zmiri-env-forward=<var>` forwards the `var` environment variable to the interpreted program. Can
be used multiple times to forward several variables. This has no effect if
`-Zmiri-disable-validation` is set.
* `-Zmiri-ignore-leaks` disables the memory leak checker, and also allows some
remaining threads to exist when the main thread exits.
* `-Zmiri-measureme=<name>` enables `measureme` profiling for the interpreted program.

View File

@ -399,6 +399,11 @@ fn main() {
.excluded_env_vars
.push(arg.strip_prefix("-Zmiri-env-exclude=").unwrap().to_owned());
}
arg if arg.starts_with("-Zmiri-env-forward=") => {
miri_config
.forwarded_env_vars
.push(arg.strip_prefix("-Zmiri-env-forward=").unwrap().to_owned());
}
arg if arg.starts_with("-Zmiri-track-pointer-tag=") => {
let id: u64 =
match arg.strip_prefix("-Zmiri-track-pointer-tag=").unwrap().parse() {

View File

@ -86,6 +86,8 @@ pub struct MiriConfig {
pub ignore_leaks: bool,
/// Environment variables that should always be isolated from the host.
pub excluded_env_vars: Vec<String>,
/// Environment variables that should always be forwarded from the host.
pub forwarded_env_vars: Vec<String>,
/// Command-line arguments passed to the interpreted program.
pub args: Vec<String>,
/// The seed to use when non-determinism or randomness are required (e.g. ptr-to-int cast, `getrandom()`).
@ -122,6 +124,7 @@ impl Default for MiriConfig {
isolated_op: IsolatedOp::Reject(RejectOpWith::Abort),
ignore_leaks: false,
excluded_env_vars: vec![],
forwarded_env_vars: vec![],
args: vec![],
seed: None,
tracked_pointer_tag: None,
@ -157,7 +160,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
MemoryExtra::new(&config),
);
// Complete initialization.
EnvVars::init(&mut ecx, config.excluded_env_vars)?;
EnvVars::init(&mut ecx, config.excluded_env_vars, config.forwarded_env_vars)?;
MemoryExtra::init_extern_statics(&mut ecx)?;
// Make sure we have MIR. We check MIR for some stable monomorphic function in libcore.

View File

@ -39,6 +39,7 @@ impl<'tcx> EnvVars<'tcx> {
pub(crate) fn init<'mir>(
ecx: &mut InterpCx<'mir, 'tcx, Evaluator<'mir, 'tcx>>,
mut excluded_env_vars: Vec<String>,
forwarded_env_vars: Vec<String>,
) -> InterpResult<'tcx> {
let target_os = ecx.tcx.sess.target.os.as_str();
if target_os == "windows" {
@ -47,9 +48,14 @@ impl<'tcx> EnvVars<'tcx> {
excluded_env_vars.push("TERM".to_owned());
}
if ecx.machine.communicate() {
// Skip the loop entirely if we don't want to forward anything.
if ecx.machine.communicate() || !forwarded_env_vars.is_empty() {
for (name, value) in env::vars() {
if !excluded_env_vars.contains(&name) {
let forward = match ecx.machine.communicate() {
true => !excluded_env_vars.contains(&name),
false => forwarded_env_vars.contains(&name),
};
if forward {
let var_ptr = match target_os {
"linux" | "macos" =>
alloc_env_var_as_c_str(name.as_ref(), value.as_ref(), ecx)?,

View File

@ -0,0 +1,5 @@
// compile-flags: -Zmiri-env-forward=MIRI_ENV_VAR_TEST
fn main() {
assert_eq!(std::env::var("MIRI_ENV_VAR_TEST"), Ok("0".to_owned()));
}