@@ -5,10 +5,50 @@ use nix::{
55 unistd:: { close, read, write} ,
66} ;
77
8+ use crate :: validator:: { Validator , ValidatorImpl } ;
9+
810thread_local ! {
911 static MEM_VALIDATE_PIPE : RefCell <[ i32 ; 2 ] > = RefCell :: new( [ -1 , -1 ] ) ;
1012}
1113
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+
1252#[ inline]
1353#[ cfg( target_os = "linux" ) ]
1454fn create_pipe ( ) -> nix:: Result < ( i32 , i32 ) > {
@@ -58,65 +98,29 @@ fn open_pipe() -> nix::Result<()> {
5898 } )
5999}
60100
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-
97101#[ cfg( test) ]
98102mod test {
99- use super :: * ;
103+ use crate :: addr_validate ;
100104
101105 #[ test]
102106 fn validate_stack ( ) {
103107 let i = 0 ;
104108
105- assert ! ( validate ( & i as * const _ as * const libc:: c_void) ) ;
109+ assert ! ( addr_validate ( & i as * const _ as * const libc:: c_void) ) ;
106110 }
107111
108112 #[ test]
109113 fn validate_heap ( ) {
110114 let vec = vec ! [ 0 ; 1000 ] ;
111115
112116 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) ) ;
114118 }
115119 }
116120
117121 #[ test]
118122 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) )
121125 }
122126}
0 commit comments