Skip to content

Commit 6d3e839

Browse files
committed
implement blacklist/whitelist and align with me_cleaner
Ignore REMOVABLE_PARTS for now and remove all partitions but FTPR by default. Always remove NVRAM and zero-size entries from FPT. Use the same precedence for whitelist/blacklist (retention/deletion) as me_cleaner does. Adjust test script accordingly. Signed-off-by: Daniel Maslowski <[email protected]>
1 parent b144d9f commit 6d3e839

File tree

8 files changed

+89
-21
lines changed

8 files changed

+89
-21
lines changed

scripts/testall.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ cargo run --release -- me clean -S -O x230_clean_S.rom ./fixtures/x230.rom
1212
cargo run --release -- me clean -r -O x230_clean_reloc.rom ./fixtures/x230.rom
1313
#me_cleaner -r -t -O ./fixtures/x230_cleaned_trunc.rom ./fixtures/x230.rom
1414
cargo run --release -- me clean -r -t -O x230_clean_trunc.rom ./fixtures/x230.rom
15+
#me_cleaner -w MFS -O ./fixtures/x230_cleaned_w_MFS.rom ./fixtures/x230.rom
16+
cargo run --release -- me clean -w MFS -O x230_clean_w_MFS.rom ./fixtures/x230.rom
17+
#me_cleaner -b MFS -O ./fixtures/x230_cleaned_b_MFS.rom ./fixtures/x230.rom
18+
cargo run --release -- me clean -b MFS -O x230_clean_b_MFS.rom ./fixtures/x230.rom
19+
#me_cleaner -w EFFS -O ./fixtures/x230_cleaned_w_EFFS.rom ./fixtures/x230.rom
20+
cargo run --release -- me clean -w EFFS -O x230_clean_w_EFFS.rom ./fixtures/x230.rom
21+
#me_cleaner -b EFFS -O ./fixtures/x230_cleaned_b_EFFS.rom ./fixtures/x230.rom
22+
cargo run --release -- me clean -b EFFS -O x230_clean_b_EFFS.rom ./fixtures/x230.rom
1523

1624
#me_cleaner -O ./fixtures/x270_cleaned_simple.rom ./fixtures/x270.rom
1725
cargo run --release -- me clean -O x270_clean.rom ./fixtures/x270.rom
@@ -25,17 +33,33 @@ cargo run --release -- me clean -S -O x270_clean_S.rom ./fixtures/x270.rom
2533
cargo run --release -- me clean -r -O x270_clean_reloc.rom ./fixtures/x270.rom
2634
#me_cleaner -r -t -O ./fixtures/x270_cleaned_trunc.rom ./fixtures/x270.rom
2735
cargo run --release -- me clean -r -t -O x270_clean_trunc.rom ./fixtures/x270.rom
36+
#me_cleaner -w MFS -O ./fixtures/x270_cleaned_w_MFS.rom ./fixtures/x270.rom
37+
cargo run --release -- me clean -w MFS -O x270_clean_w_MFS.rom ./fixtures/x270.rom
38+
#me_cleaner -b MFS -O ./fixtures/x270_cleaned_b_MFS.rom ./fixtures/x270.rom
39+
cargo run --release -- me clean -b MFS -O x270_clean_b_MFS.rom ./fixtures/x270.rom
40+
#me_cleaner -w EFFS -O ./fixtures/x270_cleaned_w_EFFS.rom ./fixtures/x270.rom
41+
cargo run --release -- me clean -w EFFS -O x270_clean_w_EFFS.rom ./fixtures/x270.rom
42+
#me_cleaner -b EFFS -O ./fixtures/x270_cleaned_b_EFFS.rom ./fixtures/x270.rom
43+
cargo run --release -- me clean -b EFFS -O x270_clean_b_EFFS.rom ./fixtures/x270.rom
2844

2945
./scripts/bdiffstat x230_clean.rom fixtures/x230_cleaned_simple.rom
3046
./scripts/bdiffstat x230_clean_k.rom fixtures/x230_cleaned_k.rom
3147
./scripts/bdiffstat x230_clean_s.rom fixtures/x230_cleaned_s.rom
3248
./scripts/bdiffstat x230_clean_S.rom fixtures/x230_cleaned_S.rom
3349
./scripts/bdiffstat x230_clean_reloc.rom fixtures/x230_cleaned_reloc.rom
3450
./scripts/bdiffstat x230_clean_trunc.rom fixtures/x230_cleaned_trunc.rom
51+
./scripts/bdiffstat x230_clean_w_MFS.rom fixtures/x230_cleaned_w_MFS.rom
52+
./scripts/bdiffstat x230_clean_b_MFS.rom fixtures/x230_cleaned_b_MFS.rom
53+
./scripts/bdiffstat x230_clean_w_EFFS.rom fixtures/x230_cleaned_w_EFFS.rom
54+
./scripts/bdiffstat x230_clean_b_EFFS.rom fixtures/x230_cleaned_b_EFFS.rom
3555

3656
./scripts/bdiffstat x270_clean.rom fixtures/x270_cleaned_simple.rom
3757
./scripts/bdiffstat x270_clean_k.rom fixtures/x270_cleaned_k.rom
3858
./scripts/bdiffstat x270_clean_s.rom fixtures/x270_cleaned_s.rom
3959
./scripts/bdiffstat x270_clean_S.rom fixtures/x270_cleaned_S.rom
4060
./scripts/bdiffstat x270_clean_reloc.rom fixtures/x270_cleaned_reloc.rom
4161
./scripts/bdiffstat x270_clean_trunc.rom fixtures/x270_cleaned_trunc.rom
62+
./scripts/bdiffstat x270_clean_w_MFS.rom fixtures/x270_cleaned_w_MFS.rom
63+
./scripts/bdiffstat x270_clean_b_MFS.rom fixtures/x270_cleaned_b_MFS.rom
64+
./scripts/bdiffstat x270_clean_w_EFFS.rom fixtures/x270_cleaned_w_EFFS.rom
65+
./scripts/bdiffstat x270_clean_b_EFFS.rom fixtures/x270_cleaned_b_EFFS.rom

src/clean.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ use log::warn;
88
pub struct Options {
99
pub keep_modules: bool,
1010
pub relocate: bool,
11+
pub parts_force_retention: Vec<String>,
12+
pub parts_force_deletion: Vec<String>,
1113
pub disable_me: bool,
1214
pub disable_me_only: bool,
1315
}
@@ -40,6 +42,8 @@ pub fn clean(
4042
let mut new_me = me.clone();
4143
let opts = ClearOptions {
4244
keep_modules: options.keep_modules,
45+
parts_force_retention: options.parts_force_retention,
46+
parts_force_deletion: options.parts_force_deletion,
4347
};
4448
new_me.fpt_area.clean(&opts);
4549
if options.relocate {

src/main.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use std::fs;
1212
use std::io::Write;
1313

14-
use clap::{Parser, Subcommand, ValueEnum};
14+
use clap::{Parser, Subcommand};
1515
use log::{debug, error, info};
1616

1717
mod clean;
@@ -148,10 +148,10 @@ fn main() {
148148
};
149149
debug!(" Soft disable ME: {disable_me}");
150150
debug!("");
151-
if let Some(allowlist) = whitelist {
151+
if let Some(allowlist) = &whitelist {
152152
debug!("Allowlist: {allowlist:?}");
153153
}
154-
if let Some(blocklist) = blacklist {
154+
if let Some(blocklist) = &blacklist {
155155
debug!("Blocklist: {blocklist:?}");
156156
}
157157
debug!("");
@@ -181,6 +181,8 @@ fn main() {
181181
relocate,
182182
disable_me: soft_disable,
183183
disable_me_only: soft_disable_only,
184+
parts_force_retention: whitelist.unwrap_or(vec![]),
185+
parts_force_deletion: blacklist.unwrap_or(vec![]),
184186
};
185187
match clean::clean(&fw.ifd, &me, &mut data, opts) {
186188
Ok(data) => {

src/me.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ impl FPTArea {
5353
/// Clear out fully removable partitions and adjust FPT
5454
pub fn clean(&mut self, options: &ClearOptions) {
5555
let mut fpt = self.fpt.clone();
56-
fpt.clear();
56+
fpt.clear(options);
5757
self.fpt = fpt;
5858
let mut parts = self.partitions.clone();
5959
parts.clear(options);

src/part/fpt.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ use serde::{Deserialize, Serialize};
2323
use zerocopy::{AlignmentError, ConvertError, FromBytes, IntoBytes, Ref, SizeError};
2424
use zerocopy_derive::{FromBytes, Immutable, IntoBytes};
2525

26-
use crate::{EMPTY, ver::Version};
26+
use crate::{
27+
part::part::{retain, ClearOptions},
28+
ver::Version,
29+
EMPTY,
30+
};
2731

2832
pub const FTPR: &str = "FTPR";
2933
pub const FTUP: &str = "FTUP";
@@ -358,16 +362,28 @@ impl<'a> FPT {
358362
}
359363

360364
/// Remove all entries but FTPR, adjusting header and checksum
361-
pub fn clear(&mut self) {
365+
///
366+
/// Honor force retention/deletion lists, except for NVRAM entries and
367+
/// empty partitions, i.e. those of size 0; these are always removed.
368+
pub fn clear(&mut self, options: &ClearOptions) {
362369
self.entries = self
363370
.entries
364371
.iter()
365-
.filter_map(|e| if e.name() == FTPR { Some(*e) } else { None })
372+
.filter(|e| {
373+
let f = e.flags;
374+
retain(e.name(), options) && e.size() > 0 && f.kind() != PartitionKind::NVRAM
375+
})
376+
.map(|e| *e)
366377
.collect();
367378
self.header.entries = self.entries.len() as u32;
368-
// clear EFFS presence flag
369-
// TODO: define bitfield, parameterize via API
370-
self.header.flash_layout_or_flags &= 0xffff_fffe;
379+
// clear EFFS presence flag if applicable
380+
if (!options.parts_force_retention.contains(&EFFS.into())
381+
&& options.parts_force_deletion.len() == 0)
382+
|| options.parts_force_deletion.contains(&EFFS.into())
383+
{
384+
// TODO: define bitfield, parameterize via API
385+
self.header.flash_layout_or_flags &= 0xffff_fffe;
386+
}
371387
self.header.checksum = self.header_checksum();
372388
}
373389

@@ -428,7 +444,12 @@ fn checksum() {
428444
#[test]
429445
fn clear() {
430446
let mut fpt = FPT::parse(&DATA).unwrap().unwrap();
431-
fpt.clear();
447+
let opts = ClearOptions {
448+
keep_modules: false,
449+
parts_force_retention: vec![],
450+
parts_force_deletion: vec![],
451+
};
452+
fpt.clear(&opts);
432453
let s = fpt.original_size;
433454
let cleaned = &fpt.to_vec();
434455
assert_eq!(cleaned, &FPT_CLEANED[..s]);

src/part/gen2.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::dump48;
66
use crate::part::{
77
fpt::{FPT, FPTEntry, FTPR},
88
part::{
9-
ClearOptions, DataPartition, Partition, UnknownOrMalformedPartition, dir_clean,
9+
ClearOptions, DataPartition, Partition, UnknownOrMalformedPartition, dir_clean, retain,
1010
strs_to_strings,
1111
},
1212
};
@@ -131,7 +131,8 @@ pub fn clean(parts: &Vec<Gen2Partition>, options: &ClearOptions) -> Vec<Gen2Part
131131
.iter()
132132
.filter(|p| {
133133
let e = p.entry();
134-
if e.name() == FTPR {
134+
let n = e.name();
135+
if retain(n, options) {
135136
info!("Retain {e}");
136137
true
137138
} else {

src/part/gen3.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ use crate::dir::{
66
};
77
use crate::dump48;
88
use crate::part::{
9-
fpt::{DIR_PARTS, FPT, FPTEntry, FS_PARTS, FTPR, REMOVABLE_PARTS},
10-
part::{ClearOptions, Partition, UnknownOrMalformedPartition, dir_clean, strs_to_strings},
9+
fpt::{DIR_PARTS, FPT, FPTEntry, FS_PARTS, FTPR},
10+
part::{
11+
ClearOptions, Partition, UnknownOrMalformedPartition, dir_clean, retain, strs_to_strings,
12+
},
1113
};
1214

1315
#[derive(Serialize, Deserialize, Clone, Debug)]
@@ -156,12 +158,13 @@ pub fn clean(parts: &Vec<Gen3Partition>, options: &ClearOptions) -> Vec<Gen3Part
156158
.iter()
157159
.filter(|p| {
158160
let e = p.entry();
159-
if REMOVABLE_PARTS.contains(&e.name().as_str()) {
160-
info!("Remove {e}");
161-
false
162-
} else {
161+
let n = e.name();
162+
if retain(n, options) {
163163
info!("Retain {e}");
164164
true
165+
} else {
166+
info!("Remove {e}");
167+
false
165168
}
166169
})
167170
.map(|p| p.clone())

src/part/part.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use serde::{Deserialize, Serialize};
22

3-
use crate::{EMPTY, Removables, part::fpt::FPTEntry};
3+
use crate::{
4+
EMPTY, Removables,
5+
part::fpt::{FPTEntry, FTPR},
6+
};
47

58
#[derive(Serialize, Deserialize, Clone, Debug)]
69
pub struct DataPartition {
@@ -61,9 +64,19 @@ pub fn strs_to_strings(strs: &[&str]) -> Vec<String> {
6164

6265
pub struct ClearOptions {
6366
pub keep_modules: bool,
67+
pub parts_force_retention: Vec<String>,
68+
pub parts_force_deletion: Vec<String>,
6469
}
6570

66-
// Clear out removable ranges in the FTPR directory
71+
/// Shared logic for deciding whether a partition should be retained.
72+
pub fn retain(part_name: String, options: &ClearOptions) -> bool {
73+
part_name == FTPR
74+
|| options.parts_force_retention.contains(&part_name)
75+
|| (options.parts_force_deletion.len() > 0
76+
&& !options.parts_force_deletion.contains(&part_name))
77+
}
78+
79+
/// Clear out removable ranges in the FTPR directory
6780
pub fn dir_clean(dir: &dyn Removables, retention_list: &Vec<String>, data: &mut Vec<u8>) {
6881
use log::info;
6982
for r in dir.removables(&retention_list) {

0 commit comments

Comments
 (0)