Skip to content

Commit 5a6e1d9

Browse files
committed
- use array len to mlock/munlock
- reduce size to 4MB in tests, as this is how much we can lock
1 parent be0cdff commit 5a6e1d9

File tree

7 files changed

+24
-21
lines changed

7 files changed

+24
-21
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "zeroize"
3-
version = "0.4.0"
3+
version = "0.4.2"
44
edition = "2021"
55

66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
Securely clear secrets from memory. Built on stable Rust primitives which guarantee memory is zeroed using an operation will not be 'optimized away' by the compiler.
88

9-
It uses [zeroize](https://crates.io/crates/zeroize) crate under the hood to zeroize and [libsodium-sys](https://crates.io/crates/libsodium-sys) for `mlock()` and `munlock()`.
9+
It uses [zeroize](https://crates.io/crates/zeroize) crate under the hood to zeroize and [libsodium-sys](https://crates.io/crates/libsodium-sys) for `mlock()` and `munlock()`. **Maximum you can mlock is 4MB**.
1010
It can work with `bytearray` and `numpy array`.
1111

1212
> [!WARNING]
@@ -29,11 +29,11 @@ if __name__ == "__main__":
2929
print("allocate memory")
3030

3131
# regular array
32-
# max size you can lock is 4MB, at least on Linux
32+
# Maximum you can mlock is 4MB
3333
arr = bytearray(b"1234567890")
3434

3535
# numpy array
36-
# max size you can lock is 4MB, at least on Linux
36+
# Maximum you can mlock is 4MB
3737
arr_np = np.array([0] * 10, dtype=np.uint8)
3838
arr_np[:] = arr
3939
assert arr_np.tobytes() == b"1234567890"
@@ -72,7 +72,7 @@ from zeroize import zeroize1, mlock, munlock
7272

7373
if __name__ == "__main__":
7474
try:
75-
# max size you can lock is 4MB, at least on Linux
75+
# Maximum you can mlock is 4MB
7676
sensitive_data = bytearray(b"Sensitive Information")
7777
mlock(sensitive_data)
7878

@@ -89,6 +89,8 @@ if __name__ == "__main__":
8989
else:
9090
# This is the parent process
9191
os.wait() # Wait for the child process to exit
92+
93+
print("all good, bye!")
9294

9395
finally:
9496
# Unlock the memory

examples/lock_and_zeroize.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
print("allocate memory")
1010

1111
# regular array
12+
# Maximum you can mlock is 4MB
1213
arr = bytearray(b"1234567890")
1314

1415
# numpy array
16+
# Maximum you can mlock is 4MB
1517
arr_np = np.array([0] * 10, dtype=np.uint8)
1618
arr_np[:] = arr
1719
assert arr_np.tobytes() == b"1234567890"

examples/zeroize_before_fork.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
if __name__ == "__main__":
88
try:
9-
# max size you can lock is 4MB, at least on Linux
9+
# Maximum you can mlock is 4MB
1010
sensitive_data = bytearray(b"Sensitive Information")
1111
mlock(sensitive_data)
1212

@@ -23,6 +23,8 @@
2323
else:
2424
# This is the parent process
2525
os.wait() # Wait for the child process to exit
26+
27+
print("all good, bye!")
2628

2729
finally:
2830
# Unlock the memory

src/lib.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ use libsodium_sys::{
1111
};
1212
use numpy::{PyArray1, PyArrayMethods};
1313
use pyo3::prelude::*;
14-
use pyo3::pybacked::PyBackedBytes;
15-
use pyo3::types::{PyByteArray, PyBytes, PyCFunction};
14+
use pyo3::types::{PyByteArray, PyBytes};
1615
use zeroize_rs::Zeroize;
1716

1817
/// The global [`sync::Once`] that ensures we only perform
@@ -48,7 +47,8 @@ fn mlock<'py>(arr: &Bound<'py, PyAny>) -> PyResult<()> {
4847
));
4948
}
5049
unsafe {
51-
if !_mlock(as_array_mut(arr)?.as_mut_ptr()) {
50+
let arr = as_array_mut(arr)?;
51+
if !_mlock(arr.as_mut_ptr(), arr.len()) {
5252
return Err(PyErr::new::<pyo3::exceptions::PyTypeError, _>(
5353
"mlock failed",
5454
));
@@ -65,7 +65,8 @@ fn munlock<'py>(arr: &Bound<'py, PyAny>) -> PyResult<()> {
6565
));
6666
}
6767
unsafe {
68-
if !_munlock(as_array_mut(arr)?.as_mut_ptr()) {
68+
let arr = as_array_mut(arr)?;
69+
if !_munlock(arr.as_mut_ptr(), arr.len()) {
6970
return Err(PyErr::new::<pyo3::exceptions::PyTypeError, _>(
7071
"mlock failed",
7172
));
@@ -159,13 +160,13 @@ fn init() -> bool {
159160
}
160161

161162
/// Calls the platform's underlying `mlock(2)` implementation.
162-
unsafe fn _mlock<T>(ptr: *mut T) -> bool {
163-
sodium_mlock(ptr.cast(), mem::size_of::<T>()) == 0
163+
unsafe fn _mlock<T>(ptr: *mut T, len: usize) -> bool {
164+
sodium_mlock(ptr.cast(), len) == 0
164165
}
165166

166167
/// Calls the platform's underlying `munlock(2)` implementation.
167-
unsafe fn _munlock<T>(ptr: *mut T) -> bool {
168-
sodium_munlock(ptr.cast(), mem::size_of::<T>()) == 0
168+
unsafe fn _munlock<T>(ptr: *mut T, len: usize) -> bool {
169+
sodium_munlock(ptr.cast(), len) == 0
169170
}
170171

171172
#[cfg(test)]

tests/test_zeroize.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,6 @@
1212
1,
1313
2,
1414
4,
15-
8,
16-
16,
17-
32,
18-
64,
19-
128,
2015
]
2116

2217

@@ -43,8 +38,9 @@ def test_zeroize1_sizes(self):
4338
try:
4439
arr = bytearray(int(size * 1024 * 1024))
4540
arr_np = np.random.randint(
46-
0, 256, int(size * 1024 * 1024), dtype=np.uint8
41+
0, 256, int(size), dtype=np.uint8
4742
)
43+
print(f"Testing size: {size} MB")
4844
mlock(arr)
4945
mlock(arr_np)
5046
zeroize1(arr)

0 commit comments

Comments
 (0)