This repository was archived by the owner on Mar 7, 2021. It is now read-only.
File tree Expand file tree Collapse file tree 7 files changed +58
-1
lines changed Expand file tree Collapse file tree 7 files changed +58
-1
lines changed Original file line number Diff line number Diff line change @@ -16,10 +16,12 @@ const INCLUDED_FUNCTIONS: &[&str] = &[
16
16
"kill_litter_super" ,
17
17
"register_sysctl" ,
18
18
"unregister_sysctl_table" ,
19
+ "access_ok" ,
19
20
] ;
20
21
const INCLUDED_VARS : & [ & str ] = & [
21
22
"EINVAL" ,
22
23
"ENOMEM" ,
24
+ "EFAULT" ,
23
25
"__this_module" ,
24
26
"FS_REQUIRES_DEV" ,
25
27
"FS_BINARY_MOUNTDATA" ,
@@ -28,6 +30,7 @@ const INCLUDED_VARS: &[&str] = &[
28
30
"FS_RENAME_DOES_D_MOVE" ,
29
31
"BINDINGS_GFP_KERNEL" ,
30
32
"KERN_INFO" ,
33
+ "VERIFY_WRITE" ,
31
34
] ;
32
35
33
36
fn main ( ) {
@@ -74,6 +77,7 @@ fn main() {
74
77
let mut builder = cc:: Build :: new ( ) ;
75
78
println ! ( "cargo:rerun-if-env-changed=CLANG" ) ;
76
79
builder. compiler ( env:: var ( "CLANG" ) . unwrap_or ( "clang" . to_string ( ) ) ) ;
80
+ builder. warnings ( false ) ;
77
81
builder. file ( "src/helpers.c" ) ;
78
82
for arg in shlex:: split ( & output) . unwrap ( ) {
79
83
builder. flag ( & arg) ;
Original file line number Diff line number Diff line change 1
1
#include <linux/module.h>
2
2
#include <linux/fs.h>
3
3
#include <linux/slab.h>
4
+ #include <linux/uaccess.h>
4
5
5
6
// Bindgen gets confused at certain things
6
7
//
Original file line number Diff line number Diff line change @@ -6,6 +6,7 @@ pub struct Error(c_types::c_int);
6
6
impl Error {
7
7
pub const EINVAL : Self = Error ( -( bindings:: EINVAL as i32 ) ) ;
8
8
pub const ENOMEM : Self = Error ( -( bindings:: ENOMEM as i32 ) ) ;
9
+ pub const EFAULT : Self = Error ( -( bindings:: EFAULT as i32 ) ) ;
9
10
10
11
pub fn from_kernel_errno ( errno : c_types:: c_int ) -> Error {
11
12
return Error ( errno) ;
Original file line number Diff line number Diff line change 1
1
#include <linux/bug.h>
2
2
#include <linux/printk.h>
3
+ #include <linux/uaccess.h>
4
+
3
5
4
6
int printk_helper (const unsigned char * s , int len )
5
7
{
@@ -10,3 +12,8 @@ void bug_helper(void)
10
12
{
11
13
BUG ();
12
14
}
15
+
16
+ int access_ok_helper (unsigned int mode , const void __user * addr , unsigned long n )
17
+ {
18
+ return access_ok (mode , addr , n );
19
+ }
Original file line number Diff line number Diff line change @@ -13,6 +13,7 @@ pub mod filesystem;
13
13
pub mod printk;
14
14
pub mod sysctl;
15
15
mod types;
16
+ pub mod user_ptr;
16
17
17
18
pub use alloc:: format;
18
19
pub use error:: { Error , KernelResult } ;
Original file line number Diff line number Diff line change @@ -7,6 +7,7 @@ use bindings;
7
7
use c_types;
8
8
use error;
9
9
use types;
10
+ use user_ptr:: UserSlicePtr ;
10
11
11
12
pub struct Sysctl < T : Sync > {
12
13
inner : Box < T > ,
@@ -21,7 +22,20 @@ unsafe extern "C" fn proc_handler<T>(
21
22
len : * mut usize ,
22
23
ppos : * mut bindings:: loff_t ,
23
24
) -> c_types:: c_int {
24
- unimplemented ! ( ) ;
25
+ let data = match UserSlicePtr :: new ( buffer, * len) {
26
+ Ok ( ptr) => ptr,
27
+ Err ( e) => return e. to_kernel_errno ( ) ,
28
+ } ;
29
+ let storage = ( * ctl) . data as * mut T as Box < T > ;
30
+ let ( bytes_processed, result) = if write != 0 {
31
+ let data = data. read_all ( ) ?;
32
+ storage. store_value ( & data)
33
+ } else {
34
+ storage. read_value ( & data)
35
+ } ;
36
+ * len -= bytes_processed;
37
+ * ppos += bytes_processed;
38
+ return result;
25
39
}
26
40
27
41
impl < T : Sync > Sysctl < T > {
Original file line number Diff line number Diff line change
1
+ use alloc:: Vec ;
2
+
3
+ use bindings;
4
+ use c_types;
5
+ use error;
6
+
7
+ extern "C" {
8
+ fn access_ok_helper (
9
+ mode : c_types:: c_uint ,
10
+ addr : * const c_types:: c_void ,
11
+ len : c_types:: c_ulong ,
12
+ ) -> c_types:: c_int ;
13
+ }
14
+
15
+ pub struct UserSlicePtr ( * mut c_types:: c_void , usize ) ;
16
+
17
+ impl UserSlicePtr {
18
+ pub fn new ( ptr : * mut c_types:: c_void , length : usize ) -> error:: KernelResult < UserSlicePtr > {
19
+ if unsafe { access_ok_helper ( bindings:: VERIFY_WRITE , ptr, length as c_types:: c_ulong ) } != 0
20
+ {
21
+ return Err ( error:: Error :: EFAULT ) ;
22
+ }
23
+ return Ok ( UserSlicePtr ( ptr, length) ) ;
24
+ }
25
+
26
+ pub fn read_all ( self ) -> error:: KernelResult < Vec < u8 > > {
27
+ unimplemented ! ( ) ;
28
+ }
29
+ }
You can’t perform that action at this time.
0 commit comments