Skip to content

Commit 926af64

Browse files
committed
Auto merge of #1999 - RalfJung:forward-env, r=oli-obk
add flag to forward specific env vars (while isolation remains enabled) The flag is called `-Zmiri-env-forward=<var>`, but I am open to bikeshedding. ;)
2 parents 0242acc + ceec2b3 commit 926af64

File tree

5 files changed

+30
-8
lines changed

5 files changed

+30
-8
lines changed

README.md

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

src/bin/miri.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,11 @@ fn main() {
399399
.excluded_env_vars
400400
.push(arg.strip_prefix("-Zmiri-env-exclude=").unwrap().to_owned());
401401
}
402+
arg if arg.starts_with("-Zmiri-env-forward=") => {
403+
miri_config
404+
.forwarded_env_vars
405+
.push(arg.strip_prefix("-Zmiri-env-forward=").unwrap().to_owned());
406+
}
402407
arg if arg.starts_with("-Zmiri-track-pointer-tag=") => {
403408
let id: u64 =
404409
match arg.strip_prefix("-Zmiri-track-pointer-tag=").unwrap().parse() {

src/eval.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ pub struct MiriConfig {
8686
pub ignore_leaks: bool,
8787
/// Environment variables that should always be isolated from the host.
8888
pub excluded_env_vars: Vec<String>,
89+
/// Environment variables that should always be forwarded from the host.
90+
pub forwarded_env_vars: Vec<String>,
8991
/// Command-line arguments passed to the interpreted program.
9092
pub args: Vec<String>,
9193
/// 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 {
122124
isolated_op: IsolatedOp::Reject(RejectOpWith::Abort),
123125
ignore_leaks: false,
124126
excluded_env_vars: vec![],
127+
forwarded_env_vars: vec![],
125128
args: vec![],
126129
seed: None,
127130
tracked_pointer_tag: None,
@@ -157,7 +160,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
157160
MemoryExtra::new(&config),
158161
);
159162
// Complete initialization.
160-
EnvVars::init(&mut ecx, config.excluded_env_vars)?;
163+
EnvVars::init(&mut ecx, config.excluded_env_vars, config.forwarded_env_vars)?;
161164
MemoryExtra::init_extern_statics(&mut ecx)?;
162165

163166
// Make sure we have MIR. We check MIR for some stable monomorphic function in libcore.

src/shims/env.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ impl<'tcx> EnvVars<'tcx> {
3939
pub(crate) fn init<'mir>(
4040
ecx: &mut InterpCx<'mir, 'tcx, Evaluator<'mir, 'tcx>>,
4141
mut excluded_env_vars: Vec<String>,
42+
forwarded_env_vars: Vec<String>,
4243
) -> InterpResult<'tcx> {
4344
let target_os = ecx.tcx.sess.target.os.as_str();
4445
if target_os == "windows" {
@@ -47,9 +48,14 @@ impl<'tcx> EnvVars<'tcx> {
4748
excluded_env_vars.push("TERM".to_owned());
4849
}
4950

50-
if ecx.machine.communicate() {
51-
for (name, value) in env::vars() {
52-
if !excluded_env_vars.contains(&name) {
51+
// Skip the loop entirely if we don't want to forward anything.
52+
if ecx.machine.communicate() || !forwarded_env_vars.is_empty() {
53+
for (name, value) in env::vars_os() {
54+
let forward = match ecx.machine.communicate() {
55+
true => !excluded_env_vars.iter().any(|v| v.as_str() == &name),
56+
false => forwarded_env_vars.iter().any(|v| v.as_str() == &name),
57+
};
58+
if forward {
5359
let var_ptr = match target_os {
5460
"linux" | "macos" =>
5561
alloc_env_var_as_c_str(name.as_ref(), value.as_ref(), ecx)?,

tests/run-pass/env-forward.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// compile-flags: -Zmiri-env-forward=MIRI_ENV_VAR_TEST
2+
3+
fn main() {
4+
assert_eq!(std::env::var("MIRI_ENV_VAR_TEST"), Ok("0".to_owned()));
5+
}

0 commit comments

Comments
 (0)