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
@@ -50,6 +50,12 @@ use std::cmp::*;
|
||||
use serde;
|
||||
use rustc_serialize::hex::{FromHex, FromHexError, ToHex};
|
||||
|
||||
/// Conversion from decimal string error
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum FromDecStrErr {
|
||||
/// Value does not fit into type
|
||||
InvalidLength
|
||||
}
|
||||
|
||||
macro_rules! impl_map_from {
|
||||
($thing:ident, $from:ty, $to:ty) => {
|
||||
@@ -493,10 +499,8 @@ pub trait Uint: Sized + Default + FromStr + From<u64> + fmt::Debug + fmt::Displa
|
||||
/// Returns the largest value that can be represented by this integer type.
|
||||
fn max_value() -> Self;
|
||||
|
||||
/// Error type for converting from a decimal string.
|
||||
type FromDecStrErr;
|
||||
/// Convert from a decimal string.
|
||||
fn from_dec_str(value: &str) -> Result<Self, Self::FromDecStrErr>;
|
||||
fn from_dec_str(value: &str) -> Result<Self, FromDecStrErr>;
|
||||
|
||||
/// Conversion to u32
|
||||
fn low_u32(&self) -> u32;
|
||||
@@ -553,17 +557,22 @@ macro_rules! construct_uint {
|
||||
pub struct $name(pub [u64; $n_words]);
|
||||
|
||||
impl Uint for $name {
|
||||
type FromDecStrErr = FromHexError;
|
||||
|
||||
/// TODO: optimize, throw appropriate err
|
||||
fn from_dec_str(value: &str) -> Result<Self, Self::FromDecStrErr> {
|
||||
Ok(value.bytes()
|
||||
.map(|b| b - 48)
|
||||
.fold($name::from(0u64), | acc, c |
|
||||
// fast multiplication by 10
|
||||
// (acc << 3) + (acc << 1) => acc * 10
|
||||
(acc << 3) + (acc << 1) + $name::from(c)
|
||||
))
|
||||
fn from_dec_str(value: &str) -> Result<Self, FromDecStrErr> {
|
||||
let mut res = Self::default();
|
||||
for b in value.bytes().map(|b| b - 48) {
|
||||
let (r, overflow) = res.overflowing_mul_u32(10);
|
||||
if overflow {
|
||||
return Err(FromDecStrErr::InvalidLength);
|
||||
}
|
||||
let (r, overflow) = r.overflowing_add(b.into());
|
||||
if overflow {
|
||||
return Err(FromDecStrErr::InvalidLength);
|
||||
}
|
||||
res = r;
|
||||
}
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -1433,6 +1442,7 @@ known_heap_size!(0, U128, U256);
|
||||
mod tests {
|
||||
use uint::{Uint, U128, U256, U512};
|
||||
use std::str::FromStr;
|
||||
use super::FromDecStrErr;
|
||||
|
||||
#[test]
|
||||
pub fn uint256_from() {
|
||||
@@ -1802,6 +1812,7 @@ mod tests {
|
||||
fn uint256_from_dec_str() {
|
||||
assert_eq!(U256::from_dec_str("10").unwrap(), U256::from(10u64));
|
||||
assert_eq!(U256::from_dec_str("1024").unwrap(), U256::from(1024u64));
|
||||
assert_eq!(U256::from_dec_str("115792089237316195423570985008687907853269984665640564039457584007913129639936"), Err(FromDecStrErr::InvalidLength));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user