Security audit issues fixed (#1279)
* Restrict network key file permissions * Check for overflow in str to bigint conversion * RLP decoder overflow check
This commit is contained in:
committed by
Gav Wood
parent
b562480173
commit
71131c41e5
@@ -18,6 +18,7 @@
|
||||
|
||||
use common::*;
|
||||
use std::path::{PathBuf};
|
||||
use path::restrict_permissions_owner;
|
||||
|
||||
const CURRENT_DECLARED_VERSION: u64 = 3;
|
||||
const MAX_KEY_FILE_LEN: u64 = 1024 * 80;
|
||||
@@ -465,23 +466,6 @@ pub struct KeyDirectory {
|
||||
cache_usage: RwLock<VecDeque<Uuid>>,
|
||||
}
|
||||
|
||||
/// Restricts the permissions of given path only to the owner.
|
||||
#[cfg(not(windows))]
|
||||
pub fn restrict_permissions_owner(file_path: &Path) -> Result<(), i32> {
|
||||
let cstr = ::std::ffi::CString::new(file_path.to_str().unwrap()).unwrap();
|
||||
match unsafe { ::libc::chmod(cstr.as_ptr(), ::libc::S_IWUSR | ::libc::S_IRUSR) } {
|
||||
0 => Ok(()),
|
||||
x => Err(x),
|
||||
}
|
||||
}
|
||||
|
||||
/// Restricts the permissions of given path only to the owner.
|
||||
#[cfg(windows)]
|
||||
pub fn restrict_permissions_owner(_file_path: &Path) -> Result<(), i32> {
|
||||
//TODO: implement me
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl KeyDirectory {
|
||||
/// Initializes new cache directory context with a given `path`
|
||||
pub fn new(path: &Path) -> KeyDirectory {
|
||||
|
||||
@@ -41,6 +41,7 @@ use network::stats::NetworkStats;
|
||||
use network::error::{NetworkError, DisconnectReason};
|
||||
use network::discovery::{Discovery, TableUpdates, NodeEntry};
|
||||
use network::ip_utils::{map_external_address, select_public_address};
|
||||
use path::restrict_permissions_owner;
|
||||
|
||||
type Slab<T> = ::slab::Slab<T, usize>;
|
||||
|
||||
@@ -946,13 +947,17 @@ fn save_key(path: &Path, key: &Secret) {
|
||||
return;
|
||||
};
|
||||
path_buf.push("key");
|
||||
let mut file = match fs::File::create(path_buf.as_path()) {
|
||||
let path = path_buf.as_path();
|
||||
let mut file = match fs::File::create(&path) {
|
||||
Ok(file) => file,
|
||||
Err(e) => {
|
||||
warn!("Error creating key file: {:?}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
if let Err(e) = restrict_permissions_owner(&path) {
|
||||
warn!(target: "network", "Failed to modify permissions of the file (chmod: {})", e);
|
||||
}
|
||||
if let Err(e) = file.write(&key.hex().into_bytes()) {
|
||||
warn!("Error writing key file: {:?}", e);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Path utilities
|
||||
use std::path::Path;
|
||||
|
||||
/// Default ethereum paths
|
||||
pub mod ethereum {
|
||||
@@ -62,3 +63,21 @@ pub mod ethereum {
|
||||
pth
|
||||
}
|
||||
}
|
||||
|
||||
/// Restricts the permissions of given path only to the owner.
|
||||
#[cfg(not(windows))]
|
||||
pub fn restrict_permissions_owner(file_path: &Path) -> Result<(), i32> {
|
||||
let cstr = ::std::ffi::CString::new(file_path.to_str().unwrap()).unwrap();
|
||||
match unsafe { ::libc::chmod(cstr.as_ptr(), ::libc::S_IWUSR | ::libc::S_IRUSR) } {
|
||||
0 => Ok(()),
|
||||
x => Err(x),
|
||||
}
|
||||
}
|
||||
|
||||
/// Restricts the permissions of given path only to the owner.
|
||||
#[cfg(windows)]
|
||||
pub fn restrict_permissions_owner(_file_path: &Path) -> Result<(), i32> {
|
||||
//TODO: implement me
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -429,3 +429,10 @@ fn test_rlp_nested_empty_list_encode() {
|
||||
assert_eq!(stream.drain()[..], [0xc2u8, 0xc0u8, 40u8][..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rlp_list_length_overflow() {
|
||||
let data: Vec<u8> = vec![0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00];
|
||||
let rlp = UntrustedRlp::new(&data);
|
||||
let as_val: Result<String, DecoderError> = rlp.val_at(0);
|
||||
assert_eq!(Err(DecoderError::RlpIsTooShort), as_val);
|
||||
}
|
||||
|
||||
@@ -334,9 +334,9 @@ impl<'a> BasicDecoder<'a> {
|
||||
/// Return first item info.
|
||||
fn payload_info(bytes: &[u8]) -> Result<PayloadInfo, DecoderError> {
|
||||
let item = try!(PayloadInfo::from(bytes));
|
||||
match item.header_len + item.value_len <= bytes.len() {
|
||||
true => Ok(item),
|
||||
false => Err(DecoderError::RlpIsTooShort),
|
||||
match item.header_len.checked_add(item.value_len) {
|
||||
Some(x) if x <= bytes.len() => Ok(item),
|
||||
_ => Err(DecoderError::RlpIsTooShort),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user