Skip to content

Commit 8261309

Browse files
Fix panic when loading an invalid superblock
1 parent 8db2967 commit 8261309

File tree

5 files changed

+36
-1
lines changed

5 files changed

+36
-1
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
* Fixed a panic when loading an invalid superblock.
6+
37
## 0.6.0
48

59
* MSRV increased to `1.81`.

src/error.rs

+4
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ pub enum Corrupt {
154154
/// Superblock checksum is invalid.
155155
SuperblockChecksum,
156156

157+
/// The block size in the superblock is invalid.
158+
InvalidBlockSize,
159+
157160
/// The number of block groups does not fit in a [`u32`].
158161
TooManyBlockGroups,
159162

@@ -232,6 +235,7 @@ impl Display for Corrupt {
232235
Self::SuperblockChecksum => {
233236
write!(f, "invalid superblock checksum")
234237
}
238+
Self::InvalidBlockSize => write!(f, "invalid block size"),
235239
Self::TooManyBlockGroups => write!(f, "too many block groups"),
236240
Self::BlockGroupDescriptor(block_group_num) => {
237241
write!(f, "block group descriptor {block_group_num} is invalid")

src/superblock.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ impl Superblock {
6565

6666
let blocks_count = u64_from_hilo(s_blocks_count_hi, s_blocks_count_lo);
6767

68-
let block_size = 2u32.pow(10 + s_log_block_size);
68+
let block_size = calc_block_size(s_log_block_size)
69+
.ok_or(Ext4Error::Corrupt(Corrupt::InvalidBlockSize))?;
6970

7071
if s_magic != 0xef53 {
7172
return Err(Ext4Error::Corrupt(Corrupt::SuperblockMagic));
@@ -132,6 +133,11 @@ impl Superblock {
132133
}
133134
}
134135

136+
fn calc_block_size(s_log_block_size: u32) -> Option<u32> {
137+
let exp = s_log_block_size.checked_add(10)?;
138+
2u32.checked_pow(exp)
139+
}
140+
135141
fn check_incompat_features(
136142
s_feature_incompat: u32,
137143
) -> Result<IncompatibleFeatures, Incompatible> {

test_data/not_ext4.bin

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:e2040d8cde75222a96eecd1e066e546cc0dd51435cdf5897e0d7379b6d6409b8
3+
size 1024

tests/integration/ext4.rs

+18
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,24 @@ fn test_load_path_error() {
7676
));
7777
}
7878

79+
/// Test that loading the data from
80+
/// https://github.com/nicholasbishop/ext4-view-rs/issues/280 does not
81+
/// panic.
82+
#[test]
83+
fn test_invalid_ext4_data() {
84+
// Fill in zeros for the first 1024 bytes, then add the test data.
85+
let mut data = vec![0; 1024];
86+
data.extend(include_bytes!("../../test_data/not_ext4.bin"));
87+
88+
assert_eq!(
89+
*Ext4::load(Box::new(data))
90+
.unwrap_err()
91+
.as_corrupt()
92+
.unwrap(),
93+
Corrupt::InvalidBlockSize
94+
);
95+
}
96+
7997
#[test]
8098
fn test_canonicalize() {
8199
let fs = load_test_disk1();

0 commit comments

Comments
 (0)