Skip to content

Commit 7716a5c

Browse files
authored
Rust time crate CVE and general bugs (#155)
* compiling with time=0.3.17 but not clear if working properly yet * remove time package in favor of std::time and chrono * rust formatting cleanup
1 parent 0a9aca5 commit 7716a5c

File tree

6 files changed

+46
-34
lines changed

6 files changed

+46
-34
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ serde_derive = "^1.0.0"
2121
lazycell = "^0.5"
2222
libc = "~0.2"
2323
aes-gcm = "0.8.0"
24-
time = "0.1.*"
24+
chrono = "0.4.23"
2525
pnet = "0.31.0"
2626
arrayref = "0.3.2"
2727
log = "0.3.6"

src/flow_tracker.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::collections::{HashSet, VecDeque};
2-
use time::precise_time_ns;
2+
use util::precise_time_ns;
33

44
use pnet::packet::tcp::TcpPacket;
55
use pnet::packet::udp::UdpPacket;
@@ -171,7 +171,7 @@ impl FlowNoSrcPort {
171171

172172
pub struct SchedEvent {
173173
// Nanoseconds since an unspecified epoch (precise_time_ns()).
174-
drop_time: u64,
174+
drop_time: u128,
175175
flow: Flow,
176176
}
177177

@@ -191,7 +191,7 @@ pub struct FlowTracker {
191191
}
192192

193193
// Amount of time that we timeout all flows
194-
const TIMEOUT_TRACKED_NS: u64 = 30 * 1000 * 1000 * 1000;
194+
const TIMEOUT_TRACKED_NS: u128 = 30 * 1000 * 1000 * 1000;
195195
//const FIN_TIMEOUT_NS: u64 = 2*1000*1000*1000;
196196

197197
impl Default for FlowTracker {

src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ extern crate libc;
55
#[macro_use]
66
extern crate log;
77
extern crate aes_gcm;
8+
extern crate chrono;
89
extern crate errno;
910
extern crate hex;
1011
extern crate pnet;
1112
extern crate rand;
12-
extern crate time;
1313

1414
extern crate protobuf;
1515
extern crate redis;
@@ -20,7 +20,7 @@ extern crate tuntap; // https://github.com/ewust/tuntap.rs
2020
extern crate zmq;
2121

2222
use std::mem::transmute;
23-
use time::precise_time_ns;
23+
use util::precise_time_ns;
2424

2525
use serde_derive::Deserialize;
2626
use std::env;
@@ -93,7 +93,7 @@ pub struct PerCoreStats {
9393
// For computing measurement duration (because period won't be exactly 1
9494
// sec). Value is nanoseconds since an unspecified epoch. (It's a time,
9595
// not a duration).
96-
last_measure_time: u64,
96+
last_measure_time: u128,
9797

9898
pub not_in_tree_this_period: u64,
9999
pub in_tree_this_period: u64,

src/logging.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
extern crate chrono;
12
extern crate log;
2-
extern crate time;
33

4+
use chrono::Local;
45
use log::{LogLevel, LogMetadata, LogRecord};
56

67
pub struct SimpleLogger {
@@ -22,9 +23,10 @@ impl log::Log for SimpleLogger {
2223
&& !s.starts_with("tick_to")
2324
&& !s.starts_with("ticking"))
2425
{
25-
let t = time::now();
26+
let t = Local::now();
27+
// let t = time::OffsetDateTime::now_local().unwrap();
2628
// unwrap relies on "%b %d, %Y %T" being a valid format string.
27-
let t_s = time::strftime("%Y-%m-%d %H:%M:%S.%f %z", &t).unwrap();
29+
let t_s = t.format("%Y-%m-%d %H:%M:%S.%f %z").to_string();
2830
println!("{} (Core {}) {}: {}", t_s, self.lcore_id, record.level(), s);
2931
}
3032
}

src/sessions.rs

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,16 @@ use std::sync::{Arc, RwLock};
4646
use std::thread;
4747

4848
use redis;
49-
use time::precise_time_ns;
49+
use util::precise_time_ns;
5050

5151
use flow_tracker::{FlowNoSrcPort, FLOW_CLIENT_LOG};
5252
use protobuf::Message;
5353
use signalling::StationToDetector;
5454

55-
const S2NS: u64 = 1000 * 1000 * 1000;
55+
const S2NS: u128 = 1000 * 1000 * 1000;
5656
// time to add beyond original timeout if a session is still receiving packets
5757
// that need to be forwarded to the data plane proxying logic. (300 s = 5 mins)
58-
const TIMEOUT_PHANTOMS_NS: u64 = 300 * S2NS;
58+
const TIMEOUT_PHANTOMS_NS: u128 = 300 * S2NS;
5959

6060
// We _can_ filter by phantom port if we so choose, and randomize the port that
6161
// the clients connect to. However we are currently using exclusively port 443.
@@ -93,13 +93,13 @@ pub struct SessionDetails {
9393
pub client_ip: IpAddr,
9494
pub phantom_ip: IpAddr,
9595
pub phantom_port: u16,
96-
timeout: u64,
96+
timeout: u128,
9797
}
9898

9999
impl SessionDetails {
100100
// This function parses acceptable Session Details and returns an error if
101101
// the details provided do not fit current requirements for parsing
102-
pub fn new(client_ip: &str, phantom_ip: &str, timeout: u64) -> SessionResult {
102+
pub fn new(client_ip: &str, phantom_ip: &str, timeout: u128) -> SessionResult {
103103
let phantom: IpAddr = match phantom_ip.parse() {
104104
Ok(ip) => ip,
105105
Err(_) => return Err(SessionError::InvalidPhantom),
@@ -141,7 +141,7 @@ impl From<&StationToDetector> for SessionResult {
141141
fn from(s2d: &StationToDetector) -> Self {
142142
let source = s2d.get_client_ip();
143143
let phantom = s2d.get_phantom_ip();
144-
SessionDetails::new(source, phantom, s2d.get_timeout_ns())
144+
SessionDetails::new(source, phantom, u128::from(s2d.get_timeout_ns()))
145145
}
146146
}
147147

@@ -173,7 +173,7 @@ pub struct SessionTracker {
173173
// Note: In the future phantom port can be optionally added to the key
174174
// string to further filter incoming connections. This is left off for now
175175
// to allow for testing of source-refraction.
176-
pub tracked_sessions: Arc<RwLock<HashMap<String, u64>>>,
176+
pub tracked_sessions: Arc<RwLock<HashMap<String, u128>>>,
177177
}
178178

179179
impl Default for SessionTracker {
@@ -253,7 +253,7 @@ impl SessionTracker {
253253
self.try_update_session_timeout(key, TIMEOUT_PHANTOMS_NS);
254254
}
255255

256-
fn try_update_session_timeout(&mut self, key: String, extra_time: u64) {
256+
fn try_update_session_timeout(&mut self, key: String, extra_time: u128) {
257257
// Get writable map
258258
let mut mmap = self.tracked_sessions.write().expect("RwLock broken");
259259

@@ -313,7 +313,7 @@ impl SessionTracker {
313313
}
314314

315315
// No returns in this function so that it runs for the lifetime of the process.
316-
fn ingest_from_pubsub(map: Arc<RwLock<HashMap<String, u64>>>) {
316+
fn ingest_from_pubsub(map: Arc<RwLock<HashMap<String, u128>>>) {
317317
let mut con = get_redis_conn();
318318
let mut pubsub = con.as_pubsub();
319319
pubsub
@@ -400,6 +400,8 @@ mod tests {
400400
use signalling::StationToDetector;
401401
use std::{thread, time};
402402

403+
const S2NS_U64: u64 = 1000 * 1000 * 1000;
404+
403405
#[test]
404406
#[ignore] // Requires redis to run properly.
405407
fn test_session_tracker_pubsub() {
@@ -411,18 +413,18 @@ mod tests {
411413
// redis::cmd("PUBLISH").arg("dark_decoy_map").arg(octs).execute(&self.redis_conn);
412414
let st = SessionTracker::new();
413415

414-
let test_tuples = [
416+
let test_tuples: [(&str, &str, u64); 8] = [
415417
// (client_ip, phantom_ip, timeout)
416418
("172.128.0.2", "8.0.0.1", 1), // timeout immediately
417-
("192.168.0.1", "10.10.0.1", 5 * S2NS),
418-
("192.168.0.1", "192.0.0.127", 5 * S2NS),
419-
("", "2345::6789", 5 * S2NS),
419+
("192.168.0.1", "10.10.0.1", 5 * S2NS_U64),
420+
("192.168.0.1", "192.0.0.127", 5 * S2NS_U64),
421+
("", "2345::6789", 5 * S2NS_U64),
420422
// duplicate with shorter timeout should not drop
421-
("2601::123:abcd", "2001::1234", 5 * S2NS),
422-
("::1", "2001::1234", S2NS),
423+
("2601::123:abcd", "2001::1234", 5 * S2NS_U64),
424+
("::1", "2001::1234", S2NS_U64),
423425
// duplicate with long timeout should prevent drop
424426
("7.0.0.2", "8.8.8.8", 1),
425-
("7.0.0.2", "8.8.8.8", 5 * S2NS),
427+
("7.0.0.2", "8.8.8.8", 5 * S2NS_U64),
426428
];
427429

428430
st.spawn_update_thread();
@@ -500,7 +502,7 @@ mod tests {
500502
};
501503
// assert_eq!(entry.0, sd.client_ip.to_string());
502504
assert_eq!(entry.1, sd.phantom_ip.to_string());
503-
assert_eq!(entry.2, sd.timeout)
505+
assert_eq!(u128::from(entry.2), sd.timeout)
504506
}
505507

506508
for entry in &test_tuples_bad {
@@ -574,19 +576,19 @@ mod tests {
574576
let test_tuples = [
575577
// (client_ip, phantom_ip, timeout)
576578
("172.128.0.2", "8.0.0.1", 1, false), // timeout immediately
577-
("192.168.0.1", "10.10.0.1", 5 * S2NS, true),
578-
("192.168.0.1", "192.0.0.127", 5 * S2NS, true),
579+
("192.168.0.1", "10.10.0.1", 5 * S2NS_U64, true),
580+
("192.168.0.1", "192.0.0.127", 5 * S2NS_U64, true),
579581
// client registering with v4 will also create registrations for v6 just in-case
580-
("192.168.0.1", "2801::1234", 5 * S2NS, true),
582+
("192.168.0.1", "2801::1234", 5 * S2NS_U64, true),
581583
// duplicate with shorter timeout should not drop
582-
("2601::123:abcd", "2001::1234", 5 * S2NS, true),
583-
("::1", "2001::1234", S2NS, true),
584+
("2601::123:abcd", "2001::1234", 5 * S2NS_U64, true),
585+
("::1", "2001::1234", S2NS_U64, true),
584586
// duplicate with long timeout should prevent drop
585587
("7.0.0.2", "8.8.8.8", 1, true),
586-
("7.0.0.2", "8.8.8.8", 5 * S2NS, true),
588+
("7.0.0.2", "8.8.8.8", 5 * S2NS_U64, true),
587589
];
588590
for entry in &test_tuples {
589-
let s1 = SessionDetails::new(entry.0, entry.1, entry.2).unwrap();
591+
let s1 = SessionDetails::new(entry.0, entry.1, u128::from(entry.2)).unwrap();
590592
st.insert_session(s1);
591593
}
592594

src/util.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::error::Error;
88
use std::fs::File;
99
use std::io::prelude::*;
1010
use std::io::BufReader;
11+
use std::time::SystemTime;
1112

1213
use pnet::packet::ipv4::Ipv4Packet;
1314
use pnet::packet::ipv6::Ipv6Packet;
@@ -250,6 +251,13 @@ impl FSP {
250251
}
251252
}
252253

254+
pub fn precise_time_ns() -> u128 {
255+
let duration_since_epoch = SystemTime::now()
256+
.duration_since(SystemTime::UNIX_EPOCH)
257+
.unwrap();
258+
duration_since_epoch.as_nanos()
259+
}
260+
253261
#[cfg(test)]
254262
mod tests {
255263
use super::*;

0 commit comments

Comments
 (0)