Sunday, April 5, 2020

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

memory-safety 2

Memory safety example 3

Dangling Pointers in C

If you try to free a pointer and then try to access it, the C compiler won’t complains it. But you will be come to know that bug in the run time.

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 
  4 int main(){
  5 
  6   int* ptr = (int*) malloc(2*sizeof(int));
  7 
  8   *ptr= 10;
  9    ptr++;
 10   *ptr = 20;
 11 
 12   free(ptr);
 13 
 14   printf("pointer values are %d",*ptr);
 15 
 16 }

This is the runtime error: I know that you hate runt ime errors . But that is what happens when we try to access pointers that are already freed. We won’t any clue until we encounter this error in C.

======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f97ccd4e7e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7f97ccd5737a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f97ccd5b53c]
./a.out[0x4005f1]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f97cccf7830]
./a.out[0x4004e9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:06 6554103                            /home/naveen/rustprojects/mar2020/C_Rust_$omp/a.out
00600000-00601000 r--p 00000000 08:06 6554103                            /home/naveen/rustprojects/mar2020/C_Rust_$omp/a.out
00601000-00602000 rw-p 00001000 08:06 6554103                            /home/naveen/rustprojects/mar2020/C_Rust_$omp/a.out
020fa000-0211b000 rw-p 00000000 00:00 0                                  [heap]
7f97c8000000-7f97c8021000 rw-p 00000000 00:00 0 

But Rust save us here.

Rust:

 1 fn main() {
  2 
  3     let a = vec!(10,11,14); //  vector 'a' is initialized.
  4     let p = &a ; // reference to the value in 'a'.
  5 
  6     drop(a);   //free the memory allocated for 'a'
  7     
  8     //we can try to access  values in 'a' through reference 'p'
  9     println!(" values in a = {:?}",*p);
 10 }
                


The famous error comes in compile time itself

Rust complains “borrow later used here” means we dropped the value and but still trying to access it.

borrow means: when we create a reference to the value, we are just borrowing the value.In this case the ownership of the value still remains with ‘a’.

So when we dropped the value ‘a’. The borrowed reference is also become invalid and we can’t use it later point in the program.

error[E0505]: cannot move out of `a` because it is borrowed
  --> src/main.rs:9:10
   |
7  |     let p = &a ; // reference to the value in 'a'.
   |             -- borrow of `a` occurs here
8  |     
9  |     drop(a);   //free the memory allocated for 'a'
   |          ^ move out of `a` occurs here
...
12 |     println!(" values in a = {:?}",*p);
   |                                    -- borrow later used here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0505`.
error: could not compile `dangling`.

To learn more, run the command again with --verbose.

Saturday, April 4, 2020

sqlite is beautiful

I got amazed seeing the byte code instructions listing from the explain command in sqlite. It is such a beautiful design that opcodes are listed from the underlying virtual machine. This helps easy to learn more on the virtual machine design and opcodes.

sqlite> explain select * from tbl1 where a > 20;
addr  opcode         p1    p2    p3    p4             p5  comment     
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     10    0                    00  Start at 10 
1     OpenRead       0     2     0     2              00  root=2 iDb=0; tbl1
2     Rewind         0     9     0                    00             
3       Column         0     0     1                    00  r[1]=tbl1.a 
4       Le             2     8     1     (BINARY)       51  if r[1]<=r[2] goto 8
5       Column         0     0     3                    00  r[3]=tbl1.a 
6       Column         0     1     4                    00  r[4]=tbl1.b 
7       ResultRow      3     2     0                    00  output=r[3..4]
8     Next           0     3     0                    01             
9     Halt           0     0     0                    00             
10    Transaction    0     0     1     0              01  usesStmtJournal=0
11    Integer        20    2     0                    00  r[2]=20     
12    Goto           0     1     0                    00             


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