Skip to content

Commit aaf584b

Browse files
committed
Prevent huge memory allocations from bad data
If we get bad width/height data for the image bail out instead of doing a huge allocation that will crash the program. This was caught using afl-fuzz
1 parent b134a6a commit aaf584b

File tree

16 files changed

+33
-21
lines changed

16 files changed

+33
-21
lines changed

src/decoders/arw.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ impl<'a> ArwDecoder<'a> {
141141

142142
fn decode_arw1(buf: &[u8], width: usize, height: usize) -> Vec<u16> {
143143
let mut pump = BitPumpMSB::new(buf);
144-
let mut out: Vec<u16> = vec![0; width*height];
144+
let mut out: Vec<u16> = alloc_image!(width, height);
145145

146146
let mut sum: i32 = 0;
147147
for x in 0..width {

src/decoders/basics.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ pub static LITTLE_ENDIAN: Endian = Endian{big: false};
8383
pub fn decode_threaded<F>(width: usize, height: usize, closure: &F) -> Vec<u16>
8484
where F : Fn(&mut [u16], usize)+Sync {
8585

86-
let mut out: Vec<u16> = vec![0; width*height];
86+
let mut out: Vec<u16> = alloc_image!(width, height);
8787
out.par_chunks_mut(width).enumerate().for_each(|(row, line)| {
8888
closure(line, row);
8989
});
@@ -93,7 +93,7 @@ pub fn decode_threaded<F>(width: usize, height: usize, closure: &F) -> Vec<u16>
9393
pub fn decode_threaded_multiline<F>(width: usize, height: usize, lines: usize, closure: &F) -> Vec<u16>
9494
where F : Fn(&mut [u16], usize)+Sync {
9595

96-
let mut out: Vec<u16> = vec![0; width*height];
96+
let mut out: Vec<u16> = alloc_image!(width, height);
9797
out.par_chunks_mut(width*lines).enumerate().for_each(|(row, line)| {
9898
closure(line, row*lines);
9999
});

src/decoders/cr2.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ impl<'a> Decoder for Cr2Decoder<'a> {
4444
let mut width = ljpegwidth;
4545
let mut height = decompressor.height();
4646
let cpp = if decompressor.super_h() == 2 {3} else {1};
47-
let mut ljpegout = vec![0 as u16; width*height];
47+
let mut ljpegout = alloc_image!(width, height);
4848
try!(decompressor.decode(&mut ljpegout, 0, width, width, height));
4949

5050
// Linearize the output (applies only to D2000 as far as I can tell)
@@ -87,7 +87,7 @@ impl<'a> Decoder for Cr2Decoder<'a> {
8787
if canoncol.get_usize(0) == 0 {
8888
(width, height, cpp, ljpegout)
8989
} else {
90-
let mut out = vec![0 as u16; width*height];
90+
let mut out = alloc_image!(width, height);
9191
let mut fieldwidths = Vec::new();
9292
for _ in 0..canoncol.get_usize(0) {
9393
fieldwidths.push(canoncol.get_usize(1));

src/decoders/crw.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ impl<'a> CrwDecoder<'a> {
189189
}
190190

191191
fn decode_compressed(&self, cam: &Camera, width: usize, height: usize) -> Result<Vec<u16>,String> {
192-
let mut out = vec![0 as u16; width*height];
192+
let mut out = alloc_image!(width, height);
193193

194194
let dectable = fetch_tag!(self.ciff, CiffTag::DecoderTable).get_usize(0);
195195
if dectable > 2 {

src/decoders/dcr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl<'a> DcrDecoder<'a> {
6161
}
6262

6363
fn decode_kodak65000(buf: &[u8], curve: &LookupTable, width: usize, height: usize) -> Vec<u16> {
64-
let mut out: Vec<u16> = vec![0; width*height];
64+
let mut out: Vec<u16> = alloc_image!(width, height);
6565
let mut input = ByteStream::new(buf, LITTLE_ENDIAN);
6666

6767
let mut random: u32 = 0;

src/decoders/dng.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ impl<'a> DngDecoder<'a> {
200200
}
201201
let offset = offsets.get_usize(0);
202202
let src = &self.buffer[offset..];
203-
let mut out = vec![0 as u16; width*height];
203+
let mut out = alloc_image!(width, height);
204204
let decompressor = try!(LjpegDecompressor::new(src));
205205
try!(decompressor.decode(&mut out, 0, width, width, height));
206206
Ok(out)

src/decoders/kdc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ impl<'a> KdcDecoder<'a> {
8282
}
8383

8484
fn decode_dc120(src: &[u8], width: usize, height: usize) -> Vec<u16> {
85-
let mut out = vec![0u16; width*height];
85+
let mut out = alloc_image!(width, height);
8686

8787
let mul: [usize;4] = [162, 192, 187, 92];
8888
let add: [usize;4] = [ 0, 636, 424, 212];

src/decoders/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,18 @@ macro_rules! fetch_ifd {
2525
);
2626
}
2727

28+
macro_rules! alloc_image {
29+
($width:expr, $height:expr) => (
30+
{
31+
if $width * $height > 500000000 {
32+
panic!("rawloader: surely there's no such thing as a >500MP image!");
33+
}
34+
let mut out: Vec<u16> = vec![0; $width * $height];
35+
out
36+
}
37+
);
38+
}
39+
2840
extern crate toml;
2941
use self::toml::Value;
3042
mod image;

src/decoders/mos.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ impl<'a> MosDecoder<'a> {
8989
let decompressor = try!(LjpegDecompressor::new_full(src, true, true));
9090
let ljpegout = try!(decompressor.decode_leaf(width, height));
9191
if cam.find_hint("interlaced") {
92-
let mut out = vec![0 as u16; width*height];
92+
let mut out = alloc_image!(width, height);
9393
for (row,line) in ljpegout.chunks_exact(width).enumerate() {
9494
let orow = if row & 1 == 1 {height-1-row/2} else {row/2};
9595
out[orow*width .. (orow+1)*width].copy_from_slice(line);

src/decoders/nef.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ impl<'a> NefDecoder<'a> {
285285
}
286286
let curve = LookupTable::new(&points[0..max]);
287287

288-
let mut out = vec![0 as u16; width * height];
288+
let mut out = alloc_image!(width, height);
289289
let mut pump = BitPumpMSB::new(src);
290290
let mut random = pump.peek_bits(24);
291291

0 commit comments

Comments
 (0)