forked from bitcoinafterlife/bal-server
security: fix panic on untrusted input (Phase 2 Critical)
- Replace all sqlite::open().unwrap() per-request with shared Arc<Mutex<Connection>> - Add Mutex poisoning recovery in all cfg.lock() and db.lock() calls - Fix std::str::from_utf8().unwrap() with safe match → 400 Bad Request - Fix timestamp_nanos_opt().unwrap() with safe match - Fix panic on RPC client failure (bal-pusher): error log + sleep + retry - Fix ZMQ socket connect with retry loop (bal-pusher) - Add ZMQ_RCVTIMEO=5000 and match recv for graceful timeout (bal-pusher) - Fix ZMQ subscribe error with match instead of unwrap (bal-pusher) - Add unwrap_or for all tbl_stats row fields in echo_stats (prevent NULL panic) - Add panic_regression_tests.rs: test mutex poisoning recovery and NULL unwrap_or All tests pass: cargo test --test panic_regression_tests + sql_injection_tests Build verified: cargo check --bin=bal-server --bin=bal-pusher
This commit is contained in:
@@ -312,7 +312,9 @@ async fn main_result(cfg: &MyConfig, network_params: &NetworkParams) -> Result<(
|
||||
let _ = calculate_stats(&db, network_params.db_field.clone()).await;
|
||||
}
|
||||
Err(erx) => {
|
||||
panic!("impossible to get client {}", erx)
|
||||
error!("impossible to get client: {}, retrying on next block", erx);
|
||||
thread::sleep(Duration::from_secs(5));
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -622,17 +624,38 @@ async fn main() -> std::io::Result<()> {
|
||||
|
||||
let zmq_address = network_params.zmq_listener.clone();
|
||||
info!("zmq listening on: {}", zmq_address);
|
||||
socket.connect(&zmq_address).unwrap();
|
||||
loop {
|
||||
match socket.connect(&zmq_address) {
|
||||
Ok(_) => break,
|
||||
Err(e) => {
|
||||
error!("ZMQ connect failed: {}, retrying in 5s...", e);
|
||||
thread::sleep(Duration::from_secs(5));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
socket.set_subscribe(b"").unwrap();
|
||||
match socket.set_subscribe(b"") {
|
||||
Ok(_) => {},
|
||||
Err(e) => {
|
||||
error!("ZMQ subscribe failed: {}, exiting", e);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
let _ = main_result(&cfg, network_params).await;
|
||||
info!("waiting new blocks..");
|
||||
let mut last_seq: Vec<u8> = [0; 4].to_vec();
|
||||
let mut counter = 0;
|
||||
let max = 100;
|
||||
socket.set_rcvtimeo(5000).unwrap(); // 5 seconds timeout
|
||||
loop {
|
||||
let message = socket.recv_multipart(0).unwrap();
|
||||
let message = match socket.recv_multipart(0) {
|
||||
Ok(m) => m,
|
||||
Err(e) => {
|
||||
warn!("ZMQ recv timeout or error: {}, retrying...", e);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let topic = message[0].clone();
|
||||
let body = message[1].clone();
|
||||
let seq = message[2].clone();
|
||||
|
||||
Reference in New Issue
Block a user