简体   繁体   中英

C programming heap buffer overflow

I just started coding and have a beginner question. So I have a Binary tree. After I add the first node to it, I would like to search the tree see if there are any duplicated node with the same value. But I keep getting error when I try to search the tree which has only one node: Here is my node:

struct node{
int data;
struct node* left;
struct node* right;};

Here's the function I used to create the first node

struct node* createnode(int num){
struct node *p=malloc(sizeof(struct node*));
p->data=num;
return p;
}

And I added It like this:

struct node *root;
root=createnode(b);

Here is the search function

char * search(int num, struct node *p, int dep){
dep=1;
char *result="n";
if(p==NULL){result="n";return result;}
struct node * root;
root=p;
while(root!=NULL){
if(num==root->data){
result= "y";break;
}
if(num>root->data && root->right!=NULL){
root=root->right;dep++;
}
if(num<root->data&&root->left!=NULL){
root=root->left;dep++;
}
if(num >root->data&&root->right==NULL){
result= "n";break;
}
if(num <root->data&&root->left==NULL){
result="n";break;
}
} 
return result;
       }

Here is the error I got

==6841== ERROR: AddressSanitizer: heap-buffer-overflow on address        0x60040000e000 at pc 0x400eb5 bp 0x7fff3d5302c0 sp 0x7fff3d5302b0
READ of size 8 at 0x60040000e000 thread T0
#0 0x400eb4 (/.autofs/ilab/ilab_users/xy139/night+0x400eb4)
#1 0x402911 (/.autofs/ilab/ilab_users/xy139/night+0x402911)
#2 0x7f2196abdb14 (/usr/lib64/libc-2.17.so+0x21b14)
#3 0x400a78 (/.autofs/ilab/ilab_users/xy139/night+0x400a78)
0x60040000e000 is located 8 bytes to the right of 8-byte region  [0x60040000dff0,0x60040000dff8)
allocated by thread T0 here:
#0 0x7f2196e74129 (/usr/lib64/libasan.so.0.0.0+0x16129)
#1 0x402071 (/.autofs/ilab/ilab_users/xy139/night+0x402071)
#2 0x402899 (/.autofs/ilab/ilab_users/xy139/night+0x402899)
#3 0x7f2196abdb14 (/usr/lib64/libc-2.17.so+0x21b14)
Shadow bytes around the buggy address:
0x0c00ffff9bb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c00ffff9bc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c00ffff9bd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c00ffff9be0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c00ffff9bf0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa 00 fa
=>0x0c00ffff9c00:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c00ffff9c10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c00ffff9c20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c00ffff9c30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c00ffff9c40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c00ffff9c50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable:           00
Partially addressable: 01 02 03 04 05 06 07 
Heap left redzone:     fa
Heap righ redzone:     fb
Freed Heap region:     fd
Stack left redzone:    f1
Stack mid redzone:     f2
Stack right redzone:   f3
Stack partial redzone: f4
Stack after return:    f5
Stack use after scope: f8
Global redzone:        f9
Global init order:     f6
Poisoned by user:      f7
ASan internal:         fe
==6841== ABORTING

I Thank everyone who are willing to help!!!!

struct node *p = malloc(sizeof(struct node*));

You need to allocate enough memory for the struct itself, not a pointer to struct.

struct node *p = malloc(sizeof(struct node));

It is easier to remember to do this if you de-reference the target pointer and pass its size to malloc as an argument like so:

struct node *p = malloc(sizeof(*p));

If you were to change the data type of p in a later revision of a program, then you would not be required to update respective arguments to malloc .

One of the typical errors is allocating the memory not for the size of the structure, but for the pointer to it. Synchronizer showed the solution of the problem in his answer:

struct node *p = malloc(sizeof(struct node));

I should also add, that malloc can return a potentially null pointer ( link ), that's why after allocating the memory it should be checked against null before dereference:

struct node* createnode(int num)
{
  struct node *p = malloc(sizeof(struct node));
  if (p != NULL)                                // <=
  {
    p->data = num;
  }
  return p;
}

It's such a pity that it took so much time to find the error. Perhaps, using static analyzers could help to find bugs earlier. Here you can see how a similar mistake can be made in big projects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM