X
  • October 16, 2015

Silicon Secured Memory in Action!

Raj Prakash
Architect

Detecting Memory Access Errors using Hardware Support


Here is an example program that shows the hardware detecting four types of errors – buffer overflow, freed memory access, stale pointer access, and freeing a memory more than once.

  1  #include <stdlib.h>
2 #include <stdio.h>
3 int main() {
4 int *area1 = malloc(sizeof(int)*16);
5 int *area2 = malloc(sizeof(int)*100);
6
7 for (int i = 0; i <= 16; i++)
8 area1[i] = 0; // Array Out of Bounds
9
10 free(area1);
11 area1[0] = 0; // Freed Memory Access
12
13 char *area3 = malloc(sizeof(char)*64);
14 if ((void *)area1 == (void *)area3)
15 printf("New area3 is same as old area1\n");
16 area1[0] = 0; // Stale Pointer Access
17
18 free(area3);
19 free(area3);
20
21 return 0;
22 }

This program can be run under discover using Silicon Secured Memory (SSM, previously know as ADI) by passing the flag "-i adi" to discover:

$ cc t.c -g -m64
$ discover -i adi -w – a.out
$ a.out

The first problem that SSM detects is the buffer overflow on line 8, where the array area1 is accessed with index 16 while the highest valid index is 15.


Discover indicates the point in the code where the access occurs, plus the location in the code where the buffer is allocated.

ERROR 1 (ABW): writing to memory beyond array bounds at address 0x200000021047e040:
main() + 0x38 <t.c:8>
5: int *area2 = malloc(sizeof(int)*100);
6:
7: for (int i = 0; i <= 16; i++)
8:=> area1[i] = 0; // Array Out of Bounds
9:
10: free(area1);
11: area1[0] = 0; // Freed Memory Access
_start() + 0x108
was allocated at (64 bytes):
main() + 0x8 <t.c:4>
1: #include
2: #include
3: int main() {
4:=> int *area1 = malloc(sizeof(int)*16);
5: int *area2 = malloc(sizeof(int)*100);
6:
7: for (int i = 0; i <= 16; i++)
_start() + 0x108

The next problem detected is the write to freed memory at line 11, the memory was freed earlier at line 10.

ERROR 2 (FMW): writing to freed memory at address 0x200000021047e000:
main() + 0x6c <t.c:11>
8: area1[i] = 0; // Array Out of Bounds
9:
10: free(area1);
11:=> area1[0] = 0; // Freed Memory Access
12:
13: char *area3 = malloc(sizeof(char)*64);
14: if ((void *)area1 == (void *)area3)
_start() + 0x108
was allocated at (64 bytes):
main() + 0x8 <t.c:4>
1: #include
2: #include
3: int main() {
4:=> int *area1 = malloc(sizeof(int)*16);
5: int *area2 = malloc(sizeof(int)*100);
6:
7: for (int i = 0; i <= 16; i++)
_start() + 0x108
freed at:
main() + 0x5c <t.c:10>
7: for (int i = 0; i <= 16; i++)
8: area1[i] = 0; // Array Out of Bounds
9:
10:=> free(area1);
11: area1[0] = 0; // Freed Memory Access
12:
13: char *area3 = malloc(sizeof(char)*64);
_start() + 0x108

There is a stale pointer access at line 16. The memory pointed to by area1 was freed at line 10, but the memory was reused for area3 at line 13. discover reports this as a write to freed memory – even though the memory has been repurposed. This is an example of the kind of error that it is very hard for a software only solution to detect.

ERROR 3 (FMW): writing to freed memory at address 0x200000021047e000:
main() + 0xb4 <t.c:16>
13: char *area3 = malloc(sizeof(char)*64);
14: if ((void *)area1 == (void *)area3)
15: printf("New area3 is same as old area1\n");
16:=> area1[0] = 0; // Stale pointer access
17:
18: free(area3);
19: free(area3);
_start() + 0x108
was allocated at (64 bytes):
main() + 0x8 <t.c:4>
1: #include <stdlib.h>
2: #include <stdio.h>
3: int main() {
4:=> int *area1 = malloc(sizeof(int)*16);
5: int *area2 = malloc(sizeof(int)*100);
6:
7: for (int i = 0; i <= 16; i++)
_start() + 0x108
freed at:
main() + 0x5c
7: for (int i = 0; i <= 16; i++)
8: area1[i] = 0; // Array Out of Bounds
9:
10:=> free(area1);
11: area1[0] = 0; // Freed Memory Access
12:
13: char *area3 = malloc(sizeof(char)*64);
_start() + 0x108

The final error reported by discover is the double free of area3 at lines 18 and 19.

ERROR 4 (DFM): double freeing memory at address 0x300000021047e000:
main() + 0xc8 <t.c:19>
16: area1[0] = 0; // Stale pointer access
17:
18: free(area3);
19:=> free(area3);
20:
21: return 0;
22: }
_start() + 0x108
was allocated at (64 bytes):
main() + 0x74 <t.c:13>
10: free(area1);
11: area1[0] = 0; // Freed Memory Access
12:
13:=> char *area3 = malloc(sizeof(char)*64);
14: if ((void *)area1 == (void *)area3)
15: printf("New area3 is same as old area1\n");
16: area1[0] = 0; // Stale pointer access
_start() + 0x108
freed at:
main() + 0xbc <t.c:18>
15: printf("New area3 is same as old area1\n");
16: area1[0] = 0; // Stale pointer access
17:
18:=> free(area3);
19: free(area3);
20:
21: return 0;
_start() + 0x108
DISCOVER SUMMARY:
unique errors : 4 (4 total)

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha
Oracle

Integrated Cloud Applications & Platform Services