@@ -12,133 +12,89 @@ It can work with `bytearray` and `numpy array`.
12
12
13
13
> [ !WARNING]
14
14
> ** In the case of [ Copy-on-write fork] ( https://en.wikipedia.org/wiki/Copy-on-write ) you need to zeroize the memory before forking the child process, see example below.
15
- > Also by itself it doesn't work if memory is moved or moved to swap. You can use ` zeroize.mlock() ` and ` zeroize.mlock_np () ` to lock the memory, max size you can lock is 4MB, at least on Linux, see example below.**
15
+ > Also by itself it doesn't work if memory is moved or moved to swap. You can use ` zeroize.mlock() ` and ` zeroize.mlock () ` to lock the memory, max size you can lock is 4MB, at least on Linux, see example below.**
16
16
17
17
# Examples
18
18
19
19
## Lock and zeroize memory
20
20
21
21
``` python
22
- from zeroize import zeroize1, zeroize_np
23
- import numpy as np
24
- import ctypes
25
-
26
-
27
- # Load the C standard library
28
- LIBC = ctypes.CDLL(" libc.so.6" )
29
- MLOCK = LIBC .mlock
30
- MUNLOCK = LIBC .munlock
31
-
32
- # Define mlock and munlock argument types
33
- MLOCK .argtypes = [ctypes.c_void_p, ctypes.c_size_t]
34
- MUNLOCK .argtypes = [ctypes.c_void_p, ctypes.c_size_t]
35
-
36
-
37
- def lock_memory (buffer ):
38
- """ Locks the memory of the given buffer."""
39
- address = ctypes.addressof(ctypes.c_char.from_buffer(buffer))
40
- size = len (buffer)
41
- if MLOCK(address, size) != 0 :
42
- raise RuntimeError (" Failed to lock memory" )
22
+ """ By itself it doesn't work if memory is moved or moved to swap. You can use `crypes` with `libc.mlock()` to lock the memory"""
43
23
24
+ from zeroize import zeroize1, mlock, munlock
25
+ import numpy as np
44
26
45
- def unlock_memory (buffer ):
46
- """ Unlocks the memory of the given buffer."""
47
- address = ctypes.addressof(ctypes.c_char.from_buffer(buffer))
48
- size = len (buffer)
49
- if MUNLOCK(address, size) != 0 :
50
- raise RuntimeError (" Failed to unlock memory" )
51
27
28
+ if __name__ == " __main__" :
29
+ try :
30
+ print (" allocate memory" )
52
31
53
- try :
54
- print (" allocate memory" )
32
+ # regular array
33
+ # max size you can lock is 4MB, at least on Linux
34
+ arr = bytearray (b " 1234567890" )
55
35
56
- # regular array
57
- arr = bytearray (b " 1234567890" )
36
+ # numpy array
37
+ # max size you can lock is 4MB, at least on Linux
38
+ arr_np = np.array([0 ] * 10 , dtype = np.uint8)
39
+ arr_np[:] = arr
40
+ assert arr_np.tobytes() == b " 1234567890"
58
41
59
- # numpy array
60
- arr_np = np.array([0 ] * 10 , dtype = np.uint8)
61
- arr_np[:] = arr
62
- assert arr_np.tobytes() == b " 1234567890"
42
+ print (" locking memory" )
63
43
64
- print (" locking memory" )
44
+ mlock(arr)
45
+ mlock(arr_np)
65
46
66
- lock_memory(arr)
67
- lock_memory(arr_np)
47
+ print (" zeroize'ing...: " )
48
+ zeroize1(arr)
49
+ zeroize1(arr_np)
68
50
69
- print (" zeroize'ing...: " )
70
- zeroize1( arr)
71
- zeroize_np (arr_np)
51
+ print (" checking if is zeroized " )
52
+ assert arr == bytearray ( b " \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 " )
53
+ assert all (arr_np == 0 )
72
54
73
- print (" checking if is zeroized" )
74
- assert arr == bytearray (b " \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 " )
75
- assert all (arr_np == 0 )
55
+ print (" all good, bye!" )
76
56
77
- print (" all good, bye!" )
78
- finally :
79
- # Unlock the memory
80
- print (" unlocking memory" )
81
- unlock_memory(arr)
82
- unlock_memory(arr_np)
57
+ finally :
58
+ # Unlock the memory
59
+ print (" unlocking memory" )
60
+ munlock(arr)
61
+ munlock(arr_np)
83
62
```
84
63
85
- ## Zeroing memory before starting child process
64
+ ## Zeroing memory before forking child process
86
65
87
66
This mitigates the problems that appears on [ Copy-on-write fork] ( https://en.wikipedia.org/wiki/Copy-on-write ) . You need to zeroize the data before forking the child process.
88
67
``` python
89
- import os
90
- from zeroize import zeroize1, zeroize_np
91
- import numpy as np
92
- import ctypes
93
-
94
-
95
- # Load the C standard library
96
- LIBC = ctypes.CDLL(" libc.so.6" )
97
- MLOCK = LIBC .mlock
98
- MUNLOCK = LIBC .munlock
99
-
100
- # Define mlock and munlock argument types
101
- MLOCK .argtypes = [ctypes.c_void_p, ctypes.c_size_t]
102
- MUNLOCK .argtypes = [ctypes.c_void_p, ctypes.c_size_t]
103
-
104
-
105
- def lock_memory (buffer ):
106
- """ Locks the memory of the given buffer."""
107
- address = ctypes.addressof(ctypes.c_char.from_buffer(buffer))
108
- size = len (buffer)
109
- if MLOCK(address, size) != 0 :
110
- raise RuntimeError (" Failed to lock memory" )
68
+ """ In the case of [Copy-on-write fork](https://en.wikipedia.org/wiki/Copy-on-write) you need to zeroize the memory before forking the child process. """
111
69
70
+ import os
71
+ from zeroize import zeroize1, mlock, munlock
112
72
113
- def unlock_memory (buffer ):
114
- """ Unlocks the memory of the given buffer."""
115
- address = ctypes.addressof(ctypes.c_char.from_buffer(buffer))
116
- size = len (buffer)
117
- if MUNLOCK(address, size) != 0 :
118
- raise RuntimeError (" Failed to unlock memory" )
119
73
74
+ if __name__ == " __main__" :
75
+ try :
76
+ # max size you can lock is 4MB, at least on Linux
77
+ sensitive_data = bytearray (b " Sensitive Information" )
78
+ mlock(sensitive_data)
120
79
121
- try :
122
- sensitive_data = bytearray (b " Sensitive Information" )
123
- lock_memory(sensitive_data)
80
+ print (" Before zeroization:" , sensitive_data)
124
81
125
- print (" Before zeroization:" , sensitive_data)
82
+ zeroize1(sensitive_data)
83
+ print (" After zeroization:" , sensitive_data)
126
84
127
- zeroize1(sensitive_data)
128
- print (" After zeroization:" , sensitive_data)
85
+ # Forking after zeroization to ensure no sensitive data is copied
86
+ pid = os.fork()
87
+ if pid == 0 :
88
+ # This is the child process
89
+ print (" Child process memory after fork:" , sensitive_data)
90
+ else :
91
+ # This is the parent process
92
+ os.wait() # Wait for the child process to exit
129
93
130
- # Forking after zeroization to ensure no sensitive data is copied
131
- pid = os.fork()
132
- if pid == 0 :
133
- # This is the child process
134
- print (" Child process memory after fork:" , sensitive_data)
135
- else :
136
- # This is the parent process
137
- os.wait() # Wait for the child process to exit
138
- finally :
139
- # Unlock the memory
140
- print (" unlocking memory" )
141
- unlock_memory(sensitive_data)
94
+ finally :
95
+ # Unlock the memory
96
+ print (" unlocking memory" )
97
+ munlock(sensitive_data)
142
98
```
143
99
144
100
# Building from source
0 commit comments