Wednesday, April 1, 2020

How do C and Rust programs differs in memory safety - Example 2

memory-safety 2

Memory safety example 2

This is one of the well known problem in C programming language - Array Overflow.
C compiler really won’t care the boundary of arrays , you can even point to the value beyond array length using a pointer as if you are traversing through it.

C Program

  1 
  2 int main(){
  3 
  4     int a[3] =  {1,2,3 };
  5     char c = 'a';
  6     char d = 'b';
  //pointer to the array, 
  //usually array itself is a pointer
  // to the first address of the array 
  7     printf("array = %d " , *a );
  8     printf("array = %d " , *(a+1) );
  9     printf("array = %d " , *(a+2) );
 10     
 11     
 12     //memory overflow , we are trying to access beyond array's length
 13     //but compiling is not complaining
 14 
 15     printf("array = %d " , *(a+3) );
 16     printf("array = %d " , a[5] );
 17 
 18 }

Output is

array = 1 array = 2 array = 3 array = 0 array = 32764 

We will see how Rust program restricts this vulnerability .

Rust Program

trying to create pointer and dereferencing it below, but compiler catches it

 1 
  2 fn main() {
  3 
  4     let a = [1,2,4];
  5 
  6     let p = &a;
  7     
  8     println!("array ={:?}",*p+1);
  9 
 10 }

error is

--> src/main.rs:8:31
  |
8 |     println!("array ={:?}",*(p+1)); 
  |                              -^- {integer}
  |                              |
  |                              &[{integer}; 3]


if you try to access it through index, as a[3] , below is the error


error: this operation will panic at runtime
 --> src/main.rs:8:26
  |
8 |    println!("array = {}",a[3]);
  |                          ^^^^ index out of bounds: the len is 3 but the index is 3
  |
  = note: `#[deny(unconditional_panic)]` on by default

Tuesday, March 31, 2020

How do C and Rust programs differs in memory-safety - example 1

ownership

How do C and Rust differs in memory safety ? example 1

Looks at the below program, how crazy the ‘main’ function snatches the password from the function ‘assign’. We only return the pointer to the ‘user’, but ‘main’ gets ‘password’ from it.

It took some trials for me to find number nine(9) as the offset (byte) ( difference between the “user” and " password" address ) .

C code

 l 1 
  2 #include<stdlib.h>
  3 
  4 char* assign(){
  5 
  6     char password = 'a'; //password stored here
  7     char b[3] = "ab";
  8 
  9     int* username = &b;
 10 
 11     return username;
 12 }
 13 
 14 
 15 
 16 int main(){
 17 
 18   char* user = NULL;
 19 
 20   user  = assign();
 
 21   // you can just do some address offseting with "-" or "+" to get the "password" field
 
 22   printf("%c\n",*(user - 9));
 23 
 24 }

Output is ‘a’ which is the password here.

a

Rust code:

In rust it is very difficult or not even possible ( I don’t know a method) without unsafe code to offset the address and get another variables or string slices(literals).

Interestingly “password” and “username” variables are referring to the program memory itself ( not stack or heap ) as &str ( string slice) hard coding in program binary.

We can try with "unsafe " code to do some manipulation on the username address to snatch the “password”.

But if you are making sure that no ‘unsafe’ code in your program , you can avoid this scenario in rust or you will catch those scenario on compile time itself ( that is AWESOME! )

 2 fn assign() -> &'static str{
  3 
  4     let password = "q";
  5     let username = "asdasd";
  6 
  7     let q = username;
  8 
  9 
 10     println!("pointer = {:p}, {:p}",password,q);
 11 
 12     q
 13 
 14 }
 15 
 16 
 17 fn main() {
 18 
 19   let p:&str = assign();
 20 
 21   let ptr: *const u8 = p.as_ptr();
 22 
   /// you really need to write unsafe code and
   /// do some trick to get offset address of the 
   /// "password" here. The + , - operators won't work with address in rust.
   
 23   unsafe {
 24           println!("Hello, world! : {}",*ptr.sub(1) as char);
 25   }
 26 
 27 }

          

Output is

pointer = 0x5638e3aa3d70, 0x5638e3aa3d71
Hello, world! : q

Sunday, March 29, 2020

Rust Traits Must know points

Reading and understanding Traits is a pre-requisite before starting to read any code base in Rust.

Most of the scenarios and examples are mentioned here,

https://doc.rust-lang.org/1.8.0/book/traits.html