Skip to content

Commit 73e470d

Browse files
Check selectors too in whitelist
1 parent 4057eb7 commit 73e470d

File tree

2 files changed

+37
-10
lines changed

2 files changed

+37
-10
lines changed

basic_bootloader/src/bootloader/transaction/rlp_encoded/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ mod test {
222222

223223
#[test]
224224
fn test_on_random_service() {
225-
let input = hex::decode("7df9020d940000000000000000000000000000000000010008b901f4000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f380").unwrap();
225+
let input = hex::decode("7df90324940000000000000000000000000000000000010008b9030bcca2f7bc000400050607000800090a00b000c00d00e00f010100110213010410051617001801091a01b001c10d01e10f020200120223020420052627002802092a02b002c20d02e20f030300130233030430053637003803093a03b003c30d03e30f040400140243040440054647004804094a04b004c40d04e40f050500150253050450055657005805095a05b005c50d05e50f060600160263060460056667006806096a06b006c60d06e60f070700170273070470057677007807097a07b007c70d07e70f080800180283080480058687008808098a08b008c80d08e80f090900190293090490059697009809099a09b009c90d09e90f0a0a001a02a30a04a005a6a700a80a09aa0ab00aca0d0aea0f0b0b001b02b30b04b005b6b700b80b09ba0bb00bcb0d0beb0f0c0c001c02c30c04c005c6c700c80c09ca0cb00ccc0d0cec0f0d0d001d02d30d04d005d6d700d80d09da0db00dcd0d0ded0f0e0e001e02e30e04e005e6e700e80e09ea0eb00ece0d0eee0f0f0f001f02f30f04f005f6f700f80f09fa0fb00fcf0d0fef0f000000100203000400050607000800090a00b000c00d00e00f010100110213010410051617001801091a01b001c10d01e10f020200120223020420052627002802092a02b002c20d02e20f030300130233030430053637003803093a03b003c30d03e30f040400140243040440054647004804094a04b004c40d04e40f050500150253050450055657005805095a05b005c50d05e50f060600160263060460056667006806096a06b006c60d06e60f070700170273070470057677007807097a07b007c70d07e70f080800180283080480058687008808098a08b008c80d08e80f090900190293090490059697009809099a09b009c90d09e90f0a0a001a02a30a04a005a6a700a80a09aa0ab00aca0d0aea0f0b0b001b02b30b04b005b6b700b80b09ba0bb00bcb0d0beb0f0c0c001c02c30c04c005c6c700c80c09ca0cb00ccc0d0cec0f0d0d001d02d30d04d005d6d700d80d09da0db00dcd0d0ded0f0e0e001e02e30e04e005e6e700e80e09ea0eb00ece0d0eee0f0f0f001f02f380").unwrap();
226226
let buffer = UsizeAlignedByteBox::<Global>::from_slice_in(&input, Global);
227227
let _tx =
228228
RlpEncodedTransaction::parse_from_buffer(buffer, 1, BOOTLOADER_FORMAL_ADDRESS).unwrap();

basic_bootloader/src/bootloader/transaction/rlp_encoded/transaction_types/service_tx.rs

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,44 @@ use system_hooks::addresses_constants::{
1616
#[derive(Clone, Copy, Debug)]
1717
pub(crate) struct ServiceTx<'a> {
1818
pub(crate) to: &'a [u8; 20], // NOTE: has to be one of the addresses in SERVICE_DESTINATION_WHITELIST
19-
pub(crate) data: &'a [u8],
19+
pub(crate) data: &'a [u8], // NOTE: has start with one of the selectors in SERVICE_DESTINATION_WHITELIST
2020
salt: u64, // Some salt used by the server to identify service transactions. Ignored by ZKsync OS.
2121
}
2222

23-
const SERVICE_DESTINATION_WHITELIST: &[B160] = &[
24-
L2_INTEROP_ROOT_STORAGE_ADDRESS,
25-
SYSTEM_CONTEXT_ADDRESS,
26-
L2_INTEROP_CENTER_ADDRESS,
23+
/// Selector for
24+
/// addInteropRootsInBatch((uint256,uint256,bytes32[])[])
25+
/// -> 0xcca2f7bc
26+
const ADD_INTEROP_ROOTS_IN_BATCH_SELECTOR: [u8; 4] = [0xcc, 0xa2, 0xf7, 0xbc];
27+
28+
/// Selector for
29+
/// setSettlementLayerChainId(uint256)
30+
/// -> 0x040203e6
31+
const SET_SL_CHAIN_ID_SELECTOR: [u8; 4] = [0x04, 0x02, 0x03, 0xe6];
32+
33+
/// Selector for
34+
/// setInteropFee(uint256)
35+
/// -> 0x08273d8a
36+
const SET_INTEROP_FEE_SELECTOR: [u8; 4] = [0x09, 0x27, 0x3d, 0x8a];
37+
38+
/// Pairs (destination, selector) that service transactions are allowed
39+
/// to interact with.
40+
const SERVICE_DESTINATION_WHITELIST: &[(B160, [u8; 4])] = &[
41+
(
42+
L2_INTEROP_ROOT_STORAGE_ADDRESS,
43+
ADD_INTEROP_ROOTS_IN_BATCH_SELECTOR,
44+
),
45+
(SYSTEM_CONTEXT_ADDRESS, SET_SL_CHAIN_ID_SELECTOR),
46+
(L2_INTEROP_CENTER_ADDRESS, SET_INTEROP_FEE_SELECTOR),
2747
];
2848

49+
fn whitelisted(to: B160, data: &[u8]) -> bool {
50+
let selector: [u8; 4] = match data.get(..4).and_then(|bytes| bytes.try_into().ok()) {
51+
Some(selector) => selector,
52+
None => return false,
53+
};
54+
SERVICE_DESTINATION_WHITELIST.contains(&(to, selector))
55+
}
56+
2957
pub const SERVICE_TX_TYPE: u8 = 0x7d;
3058

3159
impl<'a> EthereumTxType for ServiceTx<'a> {
@@ -46,12 +74,11 @@ impl<'a> RlpListDecode<'a> for ServiceTx<'a> {
4674

4775
let to_b160 = B160::from_be_bytes(*to);
4876

77+
let data = r.bytes()?;
4978
// Validate whitelist
50-
if !SERVICE_DESTINATION_WHITELIST.contains(&to_b160) {
79+
if !whitelisted(to_b160, data) {
5180
return Err(InvalidTransaction::InvalidStructure);
5281
}
53-
54-
let data = r.bytes()?;
5582
let salt = r.u64()?;
5683
Ok(Self { to, data, salt })
5784
}
@@ -112,7 +139,7 @@ mod tests {
112139
#[test]
113140
fn to_in_whitelist_parses() {
114141
let to_bytes: [u8; 20] = L2_INTEROP_ROOT_STORAGE_ADDRESS.to_be_bytes();
115-
let data: Vec<u8> = vec![0xde, 0xad, 0xbe, 0xef];
142+
let data: Vec<u8> = ADD_INTEROP_ROOTS_IN_BATCH_SELECTOR.to_vec();
116143

117144
let bytes = encode_service_tx(&to_bytes, &data, 0);
118145

0 commit comments

Comments
 (0)