Skip to content

Commit

Permalink
Check Slatepack file size before loading contents
Browse files Browse the repository at this point in the history
Check Slatepack file size is within valid range before loading contents
into memory
  • Loading branch information
Nym Seddon committed Jul 30, 2020
1 parent 0d51211 commit 494ba63
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 10 deletions.
15 changes: 13 additions & 2 deletions impls/src/adapters/slatepack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
// limitations under the License.

/// Slatepack Output 'plugin' implementation
use std::fs::File;
use std::fs::{metadata, File};
use std::io::{Read, Write};
use std::path::PathBuf;

use crate::libwallet::{Error, ErrorKind, Slate, Slatepack, SlatepackBin, Slatepacker};
use crate::libwallet::{slatepack, Error, ErrorKind, Slate, Slatepack, SlatepackBin, Slatepacker};
use crate::{SlateGetter, SlatePutter};
use grin_wallet_util::byte_ser;

Expand All @@ -39,6 +39,17 @@ impl<'a> PathToSlatepack<'a> {
}

pub fn get_slatepack_file_contents(&self) -> Result<Vec<u8>, Error> {
let metadata = metadata(&self.pathbuf)?;
let len = metadata.len();
let min_len = slatepack::min_size();
let max_len = slatepack::max_size();
if len < min_len || len > max_len {
let msg = format!(
"Data is invalid length: {} | min: {}, max: {} |",
len, min_len, max_len
);
return Err(ErrorKind::SlatepackDeser(msg).into());
}
let mut pub_tx_f = File::open(&self.pathbuf)?;
let mut data = Vec::new();
pub_tx_f.read_to_end(&mut data)?;
Expand Down
2 changes: 1 addition & 1 deletion libwallet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ mod error;
mod internal;
mod slate;
pub mod slate_versions;
mod slatepack;
pub mod slatepack;
mod types;

pub use crate::error::{Error, ErrorKind};
Expand Down
12 changes: 11 additions & 1 deletion libwallet/src/slatepack/armor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
// Finally add armor framing and space/newline formatting as desired

use crate::{Error, ErrorKind};
use grin_wallet_util::byte_ser;
use grin_wallet_util::{byte_ser, grin_api::max_tx_size};
use regex::Regex;
use sha2::{Digest, Sha256};
use std::str;
Expand All @@ -34,6 +34,16 @@ static FOOTER: &str = ". ENDSLATEPACK.";
const WORD_LENGTH: usize = 15;
const WORDS_PER_LINE: usize = 200;

/// Maximum size for an armored Slatepack file
pub fn max_size() -> u64 {
max_tx_size() + HEADER.len() as u64 + FOOTER.len() as u64
}

/// Minimum size for an armored Slatepack file or stream
pub fn min_size() -> u64 {
HEADER.len() as u64
}

lazy_static! {
static ref HEADER_REGEX: Regex =
Regex::new(concat!(r"^[>\n\r\t ]*BEGINSLATEPACK[>\n\r\t ]*$")).unwrap();
Expand Down
2 changes: 1 addition & 1 deletion libwallet/src/slatepack/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ mod packer;
mod types;

pub use self::address::SlatepackAddress;
pub use self::armor::SlatepackArmor;
pub use self::armor::{max_size, min_size, SlatepackArmor};
pub use self::packer::{Slatepacker, SlatepackerArgs};
pub use self::types::{Slatepack, SlatepackBin};
5 changes: 0 additions & 5 deletions libwallet/src/slatepack/packer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,6 @@ impl<'a> Slatepacker<'a> {

/// return slatepack
pub fn deser_slatepack(&self, data: Vec<u8>, decrypt: bool) -> Result<Slatepack, Error> {
// check if data is armored, if so, remove and continue
if data.len() < super::armor::HEADER.len() {
let msg = format!("Data too short");
return Err(ErrorKind::SlatepackDeser(msg).into());
}
let test_header = Vec::from_iter(data[0..super::armor::HEADER.len()].iter().cloned());
let data = match String::from_utf8(test_header) {
Ok(s) => {
Expand Down

0 comments on commit 494ba63

Please sign in to comment.