@@ -121,13 +121,14 @@ pub fn worker_event_loop<F, Fut>(
121
121
"Node and worker version mismatch, node needs restarting, forcing shutdown" ,
122
122
) ;
123
123
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) ;
127
126
return
128
127
}
129
128
}
130
129
130
+ remove_env_vars ( debug_id) ;
131
+
131
132
// Run the main worker loop.
132
133
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." ) ;
133
134
let err = rt
@@ -142,14 +143,61 @@ pub fn worker_event_loop<F, Fut>(
142
143
// It's never `Ok` because it's `Ok(Never)`.
143
144
. unwrap_err ( ) ;
144
145
145
- gum :: debug! ( target : LOG_TARGET , % worker_pid, "quitting pvf worker ({}): {:?}" , debug_id , err) ;
146
+ worker_shutdown_message ( debug_id , worker_pid, err) ;
146
147
147
148
// We don't want tokio to wait for the tasks to finish. We want to bring down the worker as fast
148
149
// as possible and not wait for stalled validation to finish. This isn't strictly necessary now,
149
150
// but may be in the future.
150
151
rt. shutdown_background ( ) ;
151
152
}
152
153
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
+
153
201
/// Loop that runs in the CPU time monitor thread on prepare and execute jobs. Continuously wakes up
154
202
/// and then either blocks for the remaining CPU time, or returns if we exceed the CPU timeout.
155
203
///
0 commit comments