Skip to content

Commit 01fd923

Browse files
bjorn3folkertdev
authored andcommitted
Make ZSTDv07_getFrameParams safe
1 parent b6e5558 commit 01fd923

File tree

2 files changed

+47
-63
lines changed

2 files changed

+47
-63
lines changed

lib/decompress/zstd_decompress.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -192,14 +192,8 @@ fn get_decompressed_size_legacy(src: &[u8]) -> Option<u64> {
192192
}
193193
}
194194
7 => {
195-
let mut fParams_1 = ZSTDv07_frameParams {
196-
frameContentSize: 0,
197-
windowSize: 0,
198-
dictID: 0,
199-
checksumFlag: 0,
200-
};
201-
202-
match unsafe { ZSTDv07_getFrameParams(&mut fParams_1, ptr, src.len() as _) } {
195+
let mut fParams_1 = ZSTDv07_frameParams::default();
196+
match ZSTDv07_getFrameParams(&mut fParams_1, src) {
203197
Ok(0) => Some(fParams_1.frameContentSize),
204198
_ => None,
205199
}

lib/legacy/zstd_v07.rs

Lines changed: 45 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ use libc::{free, malloc};
55

66
use crate::lib::common::error_private::Error;
77
use crate::lib::common::mem::{
8-
MEM_32bits, MEM_64bits, MEM_readLE16, MEM_readLE32, MEM_readLE64, MEM_readLEST, MEM_writeLE16,
8+
MEM_32bits, MEM_64bits, MEM_readLE16, MEM_readLE32, MEM_readLEST, MEM_writeLE16,
99
};
1010
use crate::lib::common::xxhash::{
1111
XXH64_state_t, ZSTD_XXH64_digest, ZSTD_XXH64_reset, ZSTD_XXH64_update,
1212
};
1313
use crate::lib::decompress::huf_decompress::DTableDesc;
1414

15-
#[derive(Copy, Clone)]
15+
#[derive(Copy, Clone, Default)]
1616
#[repr(C)]
1717
pub(crate) struct ZSTDv07_frameParams {
1818
pub(crate) frameContentSize: core::ffi::c_ulonglong,
@@ -2099,39 +2099,35 @@ fn ZSTDv07_frameHeaderSize(src: &[u8]) -> Result<usize, Error> {
20992099
(directMode != 0 && ZSTDv07_fcs_fieldSize[fcsId] == 0) as core::ffi::c_int as usize,
21002100
))
21012101
}
2102-
pub(crate) unsafe fn ZSTDv07_getFrameParams(
2103-
fparamsPtr: *mut ZSTDv07_frameParams,
2104-
src: *const core::ffi::c_void,
2105-
srcSize: usize,
2102+
pub(crate) fn ZSTDv07_getFrameParams(
2103+
fparamsPtr: &mut ZSTDv07_frameParams,
2104+
src: &[u8],
21062105
) -> Result<usize, Error> {
2107-
let ip = src as *const u8;
2108-
if srcSize < ZSTDv07_frameHeaderSize_min {
2106+
if src.len() < ZSTDv07_frameHeaderSize_min {
21092107
return Ok(ZSTDv07_frameHeaderSize_min);
21102108
}
2111-
ptr::write_bytes(
2112-
fparamsPtr as *mut u8,
2113-
0,
2114-
::core::mem::size_of::<ZSTDv07_frameParams>(),
2115-
);
2116-
if MEM_readLE32(src) != ZSTDv07_MAGICNUMBER {
2117-
if MEM_readLE32(src) & 0xfffffff0 == ZSTDv07_MAGIC_SKIPPABLE_START {
2118-
if srcSize < ZSTDv07_skippableHeaderSize {
2109+
*fparamsPtr = ZSTDv07_frameParams::default();
2110+
2111+
let (magic, ip) = src.split_first_chunk::<4>().unwrap();
2112+
let magic = u32::from_le_bytes(*magic);
2113+
if magic != ZSTDv07_MAGICNUMBER {
2114+
if magic & 0xfffffff0 == ZSTDv07_MAGIC_SKIPPABLE_START {
2115+
if src.len() < ZSTDv07_skippableHeaderSize {
21192116
return Ok(ZSTDv07_skippableHeaderSize);
21202117
}
2121-
(*fparamsPtr).frameContentSize =
2122-
MEM_readLE32((src as *const core::ffi::c_char).add(4) as *const core::ffi::c_void)
2123-
as core::ffi::c_ulonglong;
2124-
(*fparamsPtr).windowSize = 0;
2118+
fparamsPtr.frameContentSize =
2119+
u32::from_le_bytes(*ip.first_chunk().unwrap()) as core::ffi::c_ulonglong;
2120+
fparamsPtr.windowSize = 0;
21252121
return Ok(0);
21262122
}
21272123
return Err(Error::prefix_unknown);
21282124
}
2129-
let fhsize = ZSTDv07_frameHeaderSize(core::slice::from_raw_parts(src.cast::<u8>(), srcSize))?;
2130-
if srcSize < fhsize {
2125+
let fhsize = ZSTDv07_frameHeaderSize(src)?;
2126+
if src.len() < fhsize {
21312127
return Ok(fhsize);
21322128
}
2133-
let fhdByte = *ip.add(4);
2134-
let mut pos = 5_usize;
2129+
let fhdByte = ip[0];
2130+
let mut pos = 1_usize;
21352131
let dictIDSizeCode = (fhdByte & 3) as u32;
21362132
let checksumFlag = (fhdByte >> 2 & 1) as u32;
21372133
let directMode = (fhdByte >> 5 & 1) as u32;
@@ -2149,9 +2145,8 @@ pub(crate) unsafe fn ZSTDv07_getFrameParams(
21492145
return Err(Error::frameParameter_unsupported);
21502146
}
21512147
if directMode == 0 {
2152-
let fresh39 = pos;
2153-
pos = pos.wrapping_add(1);
2154-
let wlByte = *ip.add(fresh39);
2148+
let wlByte = ip[pos];
2149+
pos += 1;
21552150
let windowLog = ((wlByte as core::ffi::c_int >> 3) + ZSTDv07_WINDOWLOG_ABSOLUTEMIN) as u32;
21562151
if windowLog
21572152
> (if MEM_32bits() {
@@ -2169,35 +2164,35 @@ pub(crate) unsafe fn ZSTDv07_getFrameParams(
21692164
match dictIDSizeCode {
21702165
0 => {}
21712166
1 => {
2172-
dictID = *ip.add(pos) as u32;
2173-
pos = pos.wrapping_add(1);
2167+
dictID = u32::from(ip[pos]);
2168+
pos += 1;
21742169
}
21752170
2 => {
2176-
dictID = MEM_readLE16(ip.add(pos) as *const core::ffi::c_void) as u32;
2177-
pos = pos.wrapping_add(2);
2171+
dictID = u32::from(u16::from_le_bytes(ip[pos..pos + 2].try_into().unwrap()));
2172+
pos += 2;
21782173
}
21792174
3 => {
2180-
dictID = MEM_readLE32(ip.add(pos) as *const core::ffi::c_void);
2181-
pos = pos.wrapping_add(4);
2175+
dictID = u32::from_le_bytes(ip[pos..pos + 4].try_into().unwrap());
2176+
pos += 4;
21822177
}
21832178
_ => unreachable!(),
21842179
}
21852180
match fcsID {
21862181
0 => {
21872182
if directMode != 0 {
2188-
frameContentSize = *ip.add(pos) as u64;
2183+
frameContentSize = ip[pos] as u64;
21892184
}
21902185
}
21912186
1 => {
2192-
frameContentSize = (MEM_readLE16(ip.add(pos) as *const core::ffi::c_void)
2187+
frameContentSize = (u16::from_le_bytes(ip[pos..pos + 2].try_into().unwrap())
21932188
as core::ffi::c_int
21942189
+ 256) as u64;
21952190
}
21962191
2 => {
2197-
frameContentSize = MEM_readLE32(ip.add(pos) as *const core::ffi::c_void) as u64;
2192+
frameContentSize = u64::from(u32::from_le_bytes(ip[pos..pos + 4].try_into().unwrap()));
21982193
}
21992194
3 => {
2200-
frameContentSize = MEM_readLE64(ip.add(pos) as *const core::ffi::c_void);
2195+
frameContentSize = u64::from_le_bytes(ip[pos..pos + 8].try_into().unwrap());
22012196
}
22022197
_ => unreachable!(),
22032198
}
@@ -2207,18 +2202,14 @@ pub(crate) unsafe fn ZSTDv07_getFrameParams(
22072202
if windowSize > windowSizeMax {
22082203
return Err(Error::frameParameter_unsupported);
22092204
}
2210-
(*fparamsPtr).frameContentSize = frameContentSize as core::ffi::c_ulonglong;
2211-
(*fparamsPtr).windowSize = windowSize;
2212-
(*fparamsPtr).dictID = dictID;
2213-
(*fparamsPtr).checksumFlag = checksumFlag;
2205+
fparamsPtr.frameContentSize = frameContentSize as core::ffi::c_ulonglong;
2206+
fparamsPtr.windowSize = windowSize;
2207+
fparamsPtr.dictID = dictID;
2208+
fparamsPtr.checksumFlag = checksumFlag;
22142209
Ok(0)
22152210
}
2216-
unsafe fn ZSTDv07_decodeFrameHeader(
2217-
dctx: *mut ZSTDv07_DCtx,
2218-
src: *const core::ffi::c_void,
2219-
srcSize: usize,
2220-
) -> Result<usize, Error> {
2221-
let result = ZSTDv07_getFrameParams(&mut (*dctx).fParams, src, srcSize);
2211+
unsafe fn ZSTDv07_decodeFrameHeader(dctx: *mut ZSTDv07_DCtx, src: &[u8]) -> Result<usize, Error> {
2212+
let result = ZSTDv07_getFrameParams(&mut (*dctx).fParams, src);
22222213
if (*dctx).fParams.dictID != 0 && (*dctx).dictID != (*dctx).fParams.dictID {
22232214
return Err(Error::dictionary_wrong);
22242215
}
@@ -2936,7 +2927,11 @@ unsafe fn ZSTDv07_decompressFrame(
29362927
if srcSize < frameHeaderSize.wrapping_add(ZSTDv07_blockHeaderSize) {
29372928
return Err(Error::srcSize_wrong);
29382929
}
2939-
if ZSTDv07_decodeFrameHeader(dctx, src, frameHeaderSize) != Ok(0) {
2930+
if ZSTDv07_decodeFrameHeader(
2931+
dctx,
2932+
core::slice::from_raw_parts(src.cast::<u8>(), frameHeaderSize),
2933+
) != Ok(0)
2934+
{
29402935
return Err(Error::corruption_detected);
29412936
}
29422937
ip = ip.add(frameHeaderSize);
@@ -3210,11 +3205,7 @@ unsafe fn ZSTDv07_decompressContinue(
32103205
.add(ZSTDv07_frameHeaderSize_min),
32113206
(*dctx).expected,
32123207
);
3213-
ZSTDv07_decodeFrameHeader(
3214-
dctx,
3215-
((*dctx).headerBuffer).as_mut_ptr() as *const core::ffi::c_void,
3216-
(*dctx).headerSize,
3217-
)?;
3208+
ZSTDv07_decodeFrameHeader(dctx, &(&(*dctx).headerBuffer)[..(*dctx).headerSize])?;
32183209
(*dctx).expected = ZSTDv07_blockHeaderSize;
32193210
(*dctx).stage = ZSTDds_decodeBlockHeader;
32203211
Ok(0)
@@ -3443,8 +3434,7 @@ pub(crate) unsafe fn ZBUFFv07_decompressContinue(
34433434
ZBUFFds_loadHeader => {
34443435
let hSize = ZSTDv07_getFrameParams(
34453436
&mut (*zbd).fParams,
3446-
((*zbd).headerBuffer).as_mut_ptr() as *const core::ffi::c_void,
3447-
(*zbd).lhSize,
3437+
&(&(*zbd).headerBuffer)[..(*zbd).lhSize],
34483438
)?;
34493439
if hSize != 0 {
34503440
// if hSize!=0, hSize > zbd->lhSize

0 commit comments

Comments
 (0)