Skip to content

Commit ebbd76a

Browse files
authored
fix(precompile): blst dangling pointers, cleanup (bluealloy#1391)
* fix(precompile): blst dangling pointers, cleanup * chore: correct error message
1 parent a4b466a commit ebbd76a

13 files changed

+111
-193
lines changed

crates/precompile/src/bls12_381/g1.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1+
use super::utils::{fp_to_bytes, remove_padding, PADDED_FP_LENGTH};
12
use blst::{blst_fp_from_bendian, blst_p1_affine, blst_p1_affine_in_g1};
23
use revm_primitives::{Bytes, PrecompileError};
34

4-
use super::utils::{fp_to_bytes, remove_padding, PADDED_FP_LENGTH};
5-
65
/// Length of each of the elements in a g1 operation input.
76
pub(super) const G1_INPUT_ITEM_LENGTH: usize = 128;
87
/// Output length of a g1 operation.
@@ -20,10 +19,10 @@ pub(super) fn encode_g1_point(input: *const blst_p1_affine) -> Bytes {
2019
}
2120

2221
/// Extracts a G1 point in Affine format from a 128 byte slice representation.
23-
pub(super) fn extract_g1_input(input: &[u8]) -> Result<*const blst_p1_affine, PrecompileError> {
22+
pub(super) fn extract_g1_input(input: &[u8]) -> Result<blst_p1_affine, PrecompileError> {
2423
if input.len() != G1_INPUT_ITEM_LENGTH {
2524
return Err(PrecompileError::Other(format!(
26-
"Input should be {G1_INPUT_ITEM_LENGTH} bits, was {}",
25+
"Input should be {G1_INPUT_ITEM_LENGTH} bytes, was {}",
2726
input.len()
2827
)));
2928
}
@@ -39,10 +38,8 @@ pub(super) fn extract_g1_input(input: &[u8]) -> Result<*const blst_p1_affine, Pr
3938
}
4039

4140
// SAFETY: out is a blst value.
42-
unsafe {
43-
if !blst_p1_affine_in_g1(&out) {
44-
return Err(PrecompileError::Other("Element not in G1".to_string()));
45-
}
41+
if unsafe { !blst_p1_affine_in_g1(&out) } {
42+
return Err(PrecompileError::Other("Element not in G1".to_string()));
4643
}
47-
Ok(&mut out as *const _)
44+
Ok(out)
4845
}

crates/precompile/src/bls12_381/g1_add.rs

+8-16
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1+
use super::g1::{encode_g1_point, extract_g1_input, G1_INPUT_ITEM_LENGTH};
2+
use crate::{u64_to_address, PrecompileWithAddress};
13
use blst::{
24
blst_p1, blst_p1_add_or_double_affine, blst_p1_affine, blst_p1_from_affine, blst_p1_to_affine,
35
};
46
use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult};
57

6-
use crate::{u64_to_address, PrecompileWithAddress};
7-
8-
use super::g1::{encode_g1_point, extract_g1_input, G1_INPUT_ITEM_LENGTH};
9-
108
/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G1ADD precompile.
119
pub const PRECOMPILE: PrecompileWithAddress =
1210
PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(g1_add));
@@ -30,31 +28,25 @@ fn g1_add(input: &Bytes, gas_limit: u64) -> PrecompileResult {
3028

3129
if input.len() != INPUT_LENGTH {
3230
return Err(PrecompileError::Other(format!(
33-
"G1ADD Input should be {INPUT_LENGTH} bits, was {}",
31+
"G1ADD input should be {INPUT_LENGTH} bytes, was {}",
3432
input.len()
3533
)));
3634
}
3735

38-
let a_aff = extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH])?;
39-
let b_aff = extract_g1_input(&input[G1_INPUT_ITEM_LENGTH..])?;
36+
let a_aff = &extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH])?;
37+
let b_aff = &extract_g1_input(&input[G1_INPUT_ITEM_LENGTH..])?;
4038

4139
let mut b = blst_p1::default();
4240
// SAFETY: b and b_aff are blst values.
43-
unsafe {
44-
blst_p1_from_affine(&mut b, b_aff);
45-
}
41+
unsafe { blst_p1_from_affine(&mut b, b_aff) };
4642

4743
let mut p = blst_p1::default();
4844
// SAFETY: p, b and a_aff are blst values.
49-
unsafe {
50-
blst_p1_add_or_double_affine(&mut p, &b, a_aff);
51-
}
45+
unsafe { blst_p1_add_or_double_affine(&mut p, &b, a_aff) };
5246

5347
let mut p_aff = blst_p1_affine::default();
5448
// SAFETY: p_aff and p are blst values.
55-
unsafe {
56-
blst_p1_to_affine(&mut p_aff, &p);
57-
}
49+
unsafe { blst_p1_to_affine(&mut p_aff, &p) };
5850

5951
let out = encode_g1_point(&p_aff);
6052
Ok((BASE_GAS_FEE, out))

crates/precompile/src/bls12_381/g1_msm.rs

+6-13
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
use blst::{blst_p1, blst_p1_affine, blst_p1_from_affine, blst_p1_to_affine, p1_affines};
2-
use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult};
3-
4-
use crate::{u64_to_address, PrecompileWithAddress};
5-
61
use super::{
72
g1::{encode_g1_point, extract_g1_input, G1_INPUT_ITEM_LENGTH},
83
g1_mul,
94
msm::msm_required_gas,
105
utils::{extract_scalar_input, NBITS, SCALAR_LENGTH},
116
};
7+
use crate::{u64_to_address, PrecompileWithAddress};
8+
use blst::{blst_p1, blst_p1_affine, blst_p1_from_affine, blst_p1_to_affine, p1_affines};
9+
use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult};
1210

1311
/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G1MSM precompile.
1412
pub const PRECOMPILE: PrecompileWithAddress =
@@ -43,15 +41,12 @@ fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult {
4341
let mut g1_points: Vec<blst_p1> = Vec::with_capacity(k);
4442
let mut scalars: Vec<u8> = Vec::with_capacity(k * SCALAR_LENGTH);
4543
for i in 0..k {
46-
let p0_aff = extract_g1_input(
44+
let p0_aff = &extract_g1_input(
4745
&input[i * g1_mul::INPUT_LENGTH..i * g1_mul::INPUT_LENGTH + G1_INPUT_ITEM_LENGTH],
4846
)?;
4947
let mut p0 = blst_p1::default();
5048
// SAFETY: p0 and p0_aff are blst values.
51-
unsafe {
52-
blst_p1_from_affine(&mut p0, p0_aff);
53-
}
54-
49+
unsafe { blst_p1_from_affine(&mut p0, p0_aff) };
5550
g1_points.push(p0);
5651

5752
scalars.extend_from_slice(
@@ -68,9 +63,7 @@ fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult {
6863

6964
let mut multiexp_aff = blst_p1_affine::default();
7065
// SAFETY: multiexp_aff and multiexp are blst values.
71-
unsafe {
72-
blst_p1_to_affine(&mut multiexp_aff, &multiexp);
73-
}
66+
unsafe { blst_p1_to_affine(&mut multiexp_aff, &multiexp) };
7467

7568
let out = encode_g1_point(&multiexp_aff);
7669
Ok((required_gas, out))

crates/precompile/src/bls12_381/g1_mul.rs

+8-16
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
use blst::{blst_p1, blst_p1_affine, blst_p1_from_affine, blst_p1_mult, blst_p1_to_affine};
2-
use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult};
3-
4-
use crate::{u64_to_address, PrecompileWithAddress};
5-
61
use super::{
72
g1::{encode_g1_point, extract_g1_input, G1_INPUT_ITEM_LENGTH},
83
utils::{extract_scalar_input, NBITS},
94
};
5+
use crate::{u64_to_address, PrecompileWithAddress};
6+
use blst::{blst_p1, blst_p1_affine, blst_p1_from_affine, blst_p1_mult, blst_p1_to_affine};
7+
use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult};
108

119
/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G1MUL precompile.
1210
pub const PRECOMPILE: PrecompileWithAddress =
@@ -31,30 +29,24 @@ pub fn g1_mul(input: &Bytes, gas_limit: u64) -> PrecompileResult {
3129
}
3230
if input.len() != INPUT_LENGTH {
3331
return Err(PrecompileError::Other(format!(
34-
"G1MUL Input should be {INPUT_LENGTH} bits, was {}",
32+
"G1MUL input should be {INPUT_LENGTH} bytes, was {}",
3533
input.len()
3634
)));
3735
}
3836

39-
let p0_aff = extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH])?;
37+
let p0_aff = &extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH])?;
4038
let mut p0 = blst_p1::default();
4139
// SAFETY: p0 and p0_aff are blst values.
42-
unsafe {
43-
blst_p1_from_affine(&mut p0, p0_aff);
44-
}
40+
unsafe { blst_p1_from_affine(&mut p0, p0_aff) };
4541

4642
let input_scalar0 = extract_scalar_input(&input[G1_INPUT_ITEM_LENGTH..])?;
4743

4844
let mut p = blst_p1::default();
4945
// SAFETY: input_scalar0.b has fixed size, p and p0 are blst values.
50-
unsafe {
51-
blst_p1_mult(&mut p, &p0, input_scalar0.b.as_ptr(), NBITS);
52-
}
46+
unsafe { blst_p1_mult(&mut p, &p0, input_scalar0.b.as_ptr(), NBITS) };
5347
let mut p_aff = blst_p1_affine::default();
5448
// SAFETY: p_aff and p are blst values.
55-
unsafe {
56-
blst_p1_to_affine(&mut p_aff, &p);
57-
}
49+
unsafe { blst_p1_to_affine(&mut p_aff, &p) };
5850

5951
let out = encode_g1_point(&p_aff);
6052
Ok((BASE_GAS_FEE, out))

crates/precompile/src/bls12_381/g2.rs

+21-27
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,41 @@
1+
use super::utils::{fp_to_bytes, remove_padding, FP_LENGTH, PADDED_FP_LENGTH};
12
use blst::{blst_fp_from_bendian, blst_p2_affine, blst_p2_affine_in_g2};
23
use revm_primitives::{Bytes, PrecompileError};
34

4-
use super::utils::{fp_to_bytes, remove_padding, FP_LENGTH, PADDED_FP_LENGTH};
5-
65
/// Length of each of the elements in a g2 operation input.
76
pub(super) const G2_INPUT_ITEM_LENGTH: usize = 256;
87
/// Output length of a g2 operation.
98
const G2_OUTPUT_LENGTH: usize = 256;
109

1110
/// Encodes a G2 point in affine format into a byte slice with padded elements.
12-
pub(super) fn encode_g2_point(input: *const blst_p2_affine) -> Bytes {
11+
pub(super) fn encode_g2_point(input: &blst_p2_affine) -> Bytes {
1312
let mut out = vec![0u8; G2_OUTPUT_LENGTH];
14-
// SAFETY: out comes from fixed length array, input is a blst value.
15-
unsafe {
16-
fp_to_bytes(&mut out[..PADDED_FP_LENGTH], &(*input).x.fp[0]);
17-
fp_to_bytes(
18-
&mut out[PADDED_FP_LENGTH..2 * PADDED_FP_LENGTH],
19-
&(*input).x.fp[1],
20-
);
21-
fp_to_bytes(
22-
&mut out[2 * PADDED_FP_LENGTH..3 * PADDED_FP_LENGTH],
23-
&(*input).y.fp[0],
24-
);
25-
fp_to_bytes(
26-
&mut out[3 * PADDED_FP_LENGTH..4 * PADDED_FP_LENGTH],
27-
&(*input).y.fp[1],
28-
);
29-
}
13+
fp_to_bytes(&mut out[..PADDED_FP_LENGTH], &input.x.fp[0]);
14+
fp_to_bytes(
15+
&mut out[PADDED_FP_LENGTH..2 * PADDED_FP_LENGTH],
16+
&input.x.fp[1],
17+
);
18+
fp_to_bytes(
19+
&mut out[2 * PADDED_FP_LENGTH..3 * PADDED_FP_LENGTH],
20+
&input.y.fp[0],
21+
);
22+
fp_to_bytes(
23+
&mut out[3 * PADDED_FP_LENGTH..4 * PADDED_FP_LENGTH],
24+
&input.y.fp[1],
25+
);
3026
out.into()
3127
}
3228

3329
/// Extracts a G2 point in Affine format from a 256 byte slice representation.
34-
pub(super) fn extract_g2_input(input: &[u8]) -> Result<*const blst_p2_affine, PrecompileError> {
30+
pub(super) fn extract_g2_input(input: &[u8]) -> Result<blst_p2_affine, PrecompileError> {
3531
if input.len() != G2_INPUT_ITEM_LENGTH {
3632
return Err(PrecompileError::Other(format!(
37-
"Input should be {G2_INPUT_ITEM_LENGTH} bits, was {}",
33+
"Input should be {G2_INPUT_ITEM_LENGTH} bytes, was {}",
3834
input.len()
3935
)));
4036
}
4137

42-
let mut input_fps: [[u8; FP_LENGTH]; 4] = [[0; FP_LENGTH]; 4];
38+
let mut input_fps: [&[u8; FP_LENGTH]; 4] = [&[0; FP_LENGTH]; 4];
4339
for i in 0..4 {
4440
input_fps[i] = remove_padding(&input[i * PADDED_FP_LENGTH..(i + 1) * PADDED_FP_LENGTH])?;
4541
}
@@ -54,11 +50,9 @@ pub(super) fn extract_g2_input(input: &[u8]) -> Result<*const blst_p2_affine, Pr
5450
}
5551

5652
// SAFETY: out is a blst value.
57-
unsafe {
58-
if !blst_p2_affine_in_g2(&out) {
59-
return Err(PrecompileError::Other("Element not in G2".to_string()));
60-
}
53+
if unsafe { !blst_p2_affine_in_g2(&out) } {
54+
return Err(PrecompileError::Other("Element not in G2".to_string()));
6155
}
6256

63-
Ok(&mut out as *const _)
57+
Ok(out)
6458
}

crates/precompile/src/bls12_381/g2_add.rs

+8-16
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1+
use super::g2::{encode_g2_point, extract_g2_input, G2_INPUT_ITEM_LENGTH};
2+
use crate::{u64_to_address, PrecompileWithAddress};
13
use blst::{
24
blst_p2, blst_p2_add_or_double_affine, blst_p2_affine, blst_p2_from_affine, blst_p2_to_affine,
35
};
46
use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult};
57

6-
use crate::{u64_to_address, PrecompileWithAddress};
7-
8-
use super::g2::{encode_g2_point, extract_g2_input, G2_INPUT_ITEM_LENGTH};
9-
108
/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G2ADD precompile.
119
pub const PRECOMPILE: PrecompileWithAddress =
1210
PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(g2_add));
@@ -31,31 +29,25 @@ fn g2_add(input: &Bytes, gas_limit: u64) -> PrecompileResult {
3129

3230
if input.len() != INPUT_LENGTH {
3331
return Err(PrecompileError::Other(format!(
34-
"G2ADD Input should be {INPUT_LENGTH} bits, was {}",
32+
"G2ADD input should be {INPUT_LENGTH} bytes, was {}",
3533
input.len()
3634
)));
3735
}
3836

39-
let a_aff = extract_g2_input(&input[..G2_INPUT_ITEM_LENGTH])?;
40-
let b_aff = extract_g2_input(&input[G2_INPUT_ITEM_LENGTH..])?;
37+
let a_aff = &extract_g2_input(&input[..G2_INPUT_ITEM_LENGTH])?;
38+
let b_aff = &extract_g2_input(&input[G2_INPUT_ITEM_LENGTH..])?;
4139

4240
let mut b = blst_p2::default();
4341
// SAFETY: b and b_aff are blst values.
44-
unsafe {
45-
blst_p2_from_affine(&mut b, b_aff);
46-
}
42+
unsafe { blst_p2_from_affine(&mut b, b_aff) };
4743

4844
let mut p = blst_p2::default();
4945
// SAFETY: p, b and a_aff are blst values.
50-
unsafe {
51-
blst_p2_add_or_double_affine(&mut p, &b, a_aff);
52-
}
46+
unsafe { blst_p2_add_or_double_affine(&mut p, &b, a_aff) };
5347

5448
let mut p_aff = blst_p2_affine::default();
5549
// SAFETY: p_aff and p are blst values.
56-
unsafe {
57-
blst_p2_to_affine(&mut p_aff, &p);
58-
}
50+
unsafe { blst_p2_to_affine(&mut p_aff, &p) };
5951

6052
let out = encode_g2_point(&p_aff);
6153
Ok((BASE_GAS_FEE, out))

crates/precompile/src/bls12_381/g2_msm.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
use blst::{blst_p2, blst_p2_affine, blst_p2_from_affine, blst_p2_to_affine, p2_affines};
2-
use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult};
3-
4-
use crate::{u64_to_address, PrecompileWithAddress};
5-
61
use super::{
72
g2::{encode_g2_point, extract_g2_input, G2_INPUT_ITEM_LENGTH},
83
g2_mul,
94
msm::msm_required_gas,
105
utils::{extract_scalar_input, NBITS, SCALAR_LENGTH},
116
};
7+
use crate::{u64_to_address, PrecompileWithAddress};
8+
use blst::{blst_p2, blst_p2_affine, blst_p2_from_affine, blst_p2_to_affine, p2_affines};
9+
use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult};
1210

1311
/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G2MSM precompile.
1412
pub const PRECOMPILE: PrecompileWithAddress =
@@ -43,14 +41,12 @@ fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult {
4341
let mut g2_points: Vec<blst_p2> = Vec::with_capacity(k);
4442
let mut scalars: Vec<u8> = Vec::with_capacity(k * SCALAR_LENGTH);
4543
for i in 0..k {
46-
let p0_aff = extract_g2_input(
44+
let p0_aff = &extract_g2_input(
4745
&input[i * g2_mul::INPUT_LENGTH..i * g2_mul::INPUT_LENGTH + G2_INPUT_ITEM_LENGTH],
4846
)?;
4947
let mut p0 = blst_p2::default();
5048
// SAFETY: p0 and p0_aff are blst values.
51-
unsafe {
52-
blst_p2_from_affine(&mut p0, p0_aff);
53-
}
49+
unsafe { blst_p2_from_affine(&mut p0, p0_aff) };
5450

5551
g2_points.push(p0);
5652

@@ -68,9 +64,7 @@ fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult {
6864

6965
let mut multiexp_aff = blst_p2_affine::default();
7066
// SAFETY: multiexp_aff and multiexp are blst values.
71-
unsafe {
72-
blst_p2_to_affine(&mut multiexp_aff, &multiexp);
73-
}
67+
unsafe { blst_p2_to_affine(&mut multiexp_aff, &multiexp) };
7468

7569
let out = encode_g2_point(&multiexp_aff);
7670
Ok((required_gas, out))

0 commit comments

Comments
 (0)