@@ -121,22 +121,13 @@ pub fn worker_event_loop<F, Fut>(
121121 "Node and worker version mismatch, node needs restarting, forcing shutdown" ,
122122 ) ;
123123 kill_parent_node_in_emergency ( ) ;
124- let err: io:: Result < Never > =
125- Err ( io:: Error :: new ( io:: ErrorKind :: Unsupported , "Version mismatch" ) ) ;
126- gum:: debug!( target: LOG_TARGET , %worker_pid, "quitting pvf worker({}): {:?}" , debug_id, err) ;
124+ let err = io:: Error :: new ( io:: ErrorKind :: Unsupported , "Version mismatch" ) ;
125+ worker_shutdown_message ( debug_id, worker_pid, err) ;
127126 return
128127 }
129128 }
130129
131- // Delete all env vars to prevent malicious code from accessing them.
132- for ( key, _) in std:: env:: vars ( ) {
133- // TODO: *theoretically* the value (or mere presence) of `RUST_LOG` can be a source of
134- // randomness for malicious code. In the future we can remove it also and log in the host;
135- // see <https://github.com/paritytech/polkadot/issues/7117>.
136- if key != "RUST_LOG" {
137- std:: env:: remove_var ( key) ;
138- }
139- }
130+ remove_env_vars ( debug_id) ;
140131
141132 // Run the main worker loop.
142133 let rt = Runtime :: new ( ) . expect ( "Creates tokio runtime. If this panics the worker will die and the host will detect that and deal with it." ) ;
@@ -152,14 +143,61 @@ pub fn worker_event_loop<F, Fut>(
152143 // It's never `Ok` because it's `Ok(Never)`.
153144 . unwrap_err ( ) ;
154145
155- gum :: debug! ( target : LOG_TARGET , % worker_pid, "quitting pvf worker ({}): {:?}" , debug_id , err) ;
146+ worker_shutdown_message ( debug_id , worker_pid, err) ;
156147
157148 // We don't want tokio to wait for the tasks to finish. We want to bring down the worker as fast
158149 // as possible and not wait for stalled validation to finish. This isn't strictly necessary now,
159150 // but may be in the future.
160151 rt. shutdown_background ( ) ;
161152}
162153
154+ /// Delete all env vars to prevent malicious code from accessing them.
155+ fn remove_env_vars ( debug_id : & ' static str ) {
156+ for ( key, value) in std:: env:: vars_os ( ) {
157+ // TODO: *theoretically* the value (or mere presence) of `RUST_LOG` can be a source of
158+ // randomness for malicious code. In the future we can remove it also and log in the host;
159+ // see <https://github.com/paritytech/polkadot/issues/7117>.
160+ if key == "RUST_LOG" {
161+ continue
162+ }
163+
164+ // In case of a key or value that would cause [`env::remove_var` to
165+ // panic](https://doc.rust-lang.org/std/env/fn.remove_var.html#panics), we first log a
166+ // warning and then proceed to attempt to remove the env var.
167+ let mut err_reasons = vec ! [ ] ;
168+ let ( key_str, value_str) = ( key. to_str ( ) , value. to_str ( ) ) ;
169+ if key. is_empty ( ) {
170+ err_reasons. push ( "key is empty" ) ;
171+ }
172+ if key_str. is_some_and ( |s| s. contains ( '=' ) ) {
173+ err_reasons. push ( "key contains '='" ) ;
174+ }
175+ if key_str. is_some_and ( |s| s. contains ( '\0' ) ) {
176+ err_reasons. push ( "key contains null character" ) ;
177+ }
178+ if value_str. is_some_and ( |s| s. contains ( '\0' ) ) {
179+ err_reasons. push ( "value contains null character" ) ;
180+ }
181+ if !err_reasons. is_empty ( ) {
182+ gum:: warn!(
183+ target: LOG_TARGET ,
184+ %debug_id,
185+ ?key,
186+ ?value,
187+ "Attempting to remove badly-formatted env var, this may cause the PVF worker to crash. Please remove it yourself. Reasons: {:?}" ,
188+ err_reasons
189+ ) ;
190+ }
191+
192+ std:: env:: remove_var ( key) ;
193+ }
194+ }
195+
196+ /// Provide a consistent message on worker shutdown.
197+ fn worker_shutdown_message ( debug_id : & ' static str , worker_pid : u32 , err : io:: Error ) {
198+ gum:: debug!( target: LOG_TARGET , %worker_pid, "quitting pvf worker ({}): {:?}" , debug_id, err) ;
199+ }
200+
163201/// Loop that runs in the CPU time monitor thread on prepare and execute jobs. Continuously wakes up
164202/// and then either blocks for the remaining CPU time, or returns if we exceed the CPU timeout.
165203///
0 commit comments