@@ -5,10 +5,50 @@ use nix::{
5
5
unistd:: { close, read, write} ,
6
6
} ;
7
7
8
+ use crate :: validator:: { Validator , ValidatorImpl } ;
9
+
8
10
thread_local ! {
9
11
static MEM_VALIDATE_PIPE : RefCell <[ i32 ; 2 ] > = RefCell :: new( [ -1 , -1 ] ) ;
10
12
}
11
13
14
+ impl ValidatorImpl for Validator {
15
+ fn addr_validate ( addr : * const libc:: c_void ) -> bool {
16
+ const CHECK_LENGTH : usize = 2 * size_of :: < * const libc:: c_void > ( ) / size_of :: < u8 > ( ) ;
17
+
18
+ // read data in the pipe
19
+ let valid_read = MEM_VALIDATE_PIPE . with ( |pipes| {
20
+ let pipes = pipes. borrow ( ) ;
21
+ loop {
22
+ let mut buf = [ 0u8 ; CHECK_LENGTH ] ;
23
+
24
+ match read ( pipes[ 0 ] , & mut buf) {
25
+ Ok ( bytes) => break bytes > 0 ,
26
+ Err ( _err @ Errno :: EINTR ) => continue ,
27
+ Err ( _err @ Errno :: EAGAIN ) => break true ,
28
+ Err ( _) => break false ,
29
+ }
30
+ }
31
+ } ) ;
32
+
33
+ if !valid_read && open_pipe ( ) . is_err ( ) {
34
+ return false ;
35
+ }
36
+
37
+ MEM_VALIDATE_PIPE . with ( |pipes| {
38
+ let pipes = pipes. borrow ( ) ;
39
+ loop {
40
+ let buf = unsafe { std:: slice:: from_raw_parts ( addr as * const u8 , CHECK_LENGTH ) } ;
41
+
42
+ match write ( pipes[ 1 ] , buf) {
43
+ Ok ( bytes) => break bytes > 0 ,
44
+ Err ( _err @ Errno :: EINTR ) => continue ,
45
+ Err ( _) => break false ,
46
+ }
47
+ }
48
+ } )
49
+ }
50
+ }
51
+
12
52
#[ inline]
13
53
#[ cfg( target_os = "linux" ) ]
14
54
fn create_pipe ( ) -> nix:: Result < ( i32 , i32 ) > {
@@ -58,65 +98,29 @@ fn open_pipe() -> nix::Result<()> {
58
98
} )
59
99
}
60
100
61
- pub fn validate ( addr : * const libc:: c_void ) -> bool {
62
- const CHECK_LENGTH : usize = 2 * size_of :: < * const libc:: c_void > ( ) / size_of :: < u8 > ( ) ;
63
-
64
- // read data in the pipe
65
- let valid_read = MEM_VALIDATE_PIPE . with ( |pipes| {
66
- let pipes = pipes. borrow ( ) ;
67
- loop {
68
- let mut buf = [ 0u8 ; CHECK_LENGTH ] ;
69
-
70
- match read ( pipes[ 0 ] , & mut buf) {
71
- Ok ( bytes) => break bytes > 0 ,
72
- Err ( _err @ Errno :: EINTR ) => continue ,
73
- Err ( _err @ Errno :: EAGAIN ) => break true ,
74
- Err ( _) => break false ,
75
- }
76
- }
77
- } ) ;
78
-
79
- if !valid_read && open_pipe ( ) . is_err ( ) {
80
- return false ;
81
- }
82
-
83
- MEM_VALIDATE_PIPE . with ( |pipes| {
84
- let pipes = pipes. borrow ( ) ;
85
- loop {
86
- let buf = unsafe { std:: slice:: from_raw_parts ( addr as * const u8 , CHECK_LENGTH ) } ;
87
-
88
- match write ( pipes[ 1 ] , buf) {
89
- Ok ( bytes) => break bytes > 0 ,
90
- Err ( _err @ Errno :: EINTR ) => continue ,
91
- Err ( _) => break false ,
92
- }
93
- }
94
- } )
95
- }
96
-
97
101
#[ cfg( test) ]
98
102
mod test {
99
- use super :: * ;
103
+ use crate :: addr_validate ;
100
104
101
105
#[ test]
102
106
fn validate_stack ( ) {
103
107
let i = 0 ;
104
108
105
- assert ! ( validate ( & i as * const _ as * const libc:: c_void) ) ;
109
+ assert ! ( addr_validate ( & i as * const _ as * const libc:: c_void) ) ;
106
110
}
107
111
108
112
#[ test]
109
113
fn validate_heap ( ) {
110
114
let vec = vec ! [ 0 ; 1000 ] ;
111
115
112
116
for i in vec. iter ( ) {
113
- assert ! ( validate ( i as * const _ as * const libc:: c_void) ) ;
117
+ assert ! ( addr_validate ( i as * const _ as * const libc:: c_void) ) ;
114
118
}
115
119
}
116
120
117
121
#[ test]
118
122
fn failed_validate ( ) {
119
- assert ! ( !validate ( std:: ptr:: null:: <libc:: c_void>( ) ) ) ;
120
- assert ! ( !validate ( -1_i32 as usize as * const libc:: c_void) )
123
+ assert ! ( !addr_validate ( std:: ptr:: null:: <libc:: c_void>( ) ) ) ;
124
+ assert ! ( !addr_validate ( -1_i32 as usize as * const libc:: c_void) )
121
125
}
122
126
}
0 commit comments