Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AddressSanitizer, an unsatisfied detection. #1397

Closed
KeuntaeShin opened this issue Apr 19, 2021 · 5 comments
Closed

AddressSanitizer, an unsatisfied detection. #1397

KeuntaeShin opened this issue Apr 19, 2021 · 5 comments

Comments

@KeuntaeShin
Copy link

KeuntaeShin commented Apr 19, 2021

Code:

int b(int _a) {                                                                                                                                        
     int arr[100];                                                                                                                                    
     int k = 1000;                                                                                                                                  
     return arr[k+100];                                                                                                                                 
 }                                                                                                                                                      
                                                                                                                                                        
 int main(int argc, char **argv) {                                                                                                                      
     printf("[start]\n");                                                                                                                               
     int k = b(argc);                                                                                                                                   
     printf("%d\n", k);                                                                                                                                 
     printf("[end]\n");                                                                                                                                 
     return 1;                                                                                                                                          
 }    

Result:

clang++-9 -O1 -g -fsanitize=address -fno-omit-frame-pointer yup.cc && ls -la ./a.out && ./a.out
-rwxr-xr-x 1 root root 1272640 Apr 19 15:23 ./a.out
[start]
0
[end]

Why above code is not considered as stack-overflow?

@ramosian-glider
Copy link
Member

ramosian-glider commented Apr 19, 2021 via email

@KeuntaeShin
Copy link
Author

KeuntaeShin commented Apr 19, 2021

Experiment A, replace to -O0.

clang++-9 -O0 -g -fsanitize=address -fno-omit-frame-pointer yup.cc && ls -la ./a.out && ./a.out
-rwxr-xr-x 1 root root 1272624 Apr 19 17:02 ./a.out
[start]
809332066
[end]

Experiment B, add volatile:

 int b( volatile int _a) {                                                                                                                              
     volatile int arr[100];                                                                                                                             
     volatile int k = 1000;                                                                                                                             
     return arr[k+100];                                                                                                                                 
 }                                                                                                                                                      
                                                                                                                                                        
 int main(int argc, char **argv) {                                                                                                                      
     printf("[start]\n");                                                                                                                               
     int k = b(argc);                                                                                                                                   
     printf("%d\n", k);                                                                                                                                 
     printf("[end]\n");                                                                                                                                 
     return 1;                                                                                                                                          
 }  

clang++-9 -O0 -g -fsanitize=address -fno-omit-frame-pointer yup.cc && ls -la ./a.out && ./a.out
-rwxr-xr-x 1 root root 1272664 Apr 19 17:04 ./a.out
[start]
0
[end]

@vitalybuka
Copy link
Contributor

vitalybuka commented Apr 19, 2021

Asan by design does not detect accesses to memory owned by non-instrumented code.
With "k = 1000" looks like it hits non-unstrumented libc frames above the main.

Actually even "lucky" invalid access can point into variable of another stack frame and asan will not be able to detect.
Asan uses redzone to detect stack access violation which works if access is slightly off bound which is usually the case.

However I would expect that https://github.com/google/sanitizers/wiki/AddressSanitizerUseAfterReturn will detect cases like this. Unfortunately as-is FakeStack does not poison just allocated memory, so out of bounds accesses which hit not yet used frames will not be detected. This probably can be improved for uar_noreserve=0 case.

@eugenis
Copy link
Contributor

eugenis commented Apr 19, 2021 via email

@KeuntaeShin
Copy link
Author

KeuntaeShin commented Apr 20, 2021

As the eugenis's comment:

Experiment A, change the overread index from 1100 to 110:

Code

int b(int _a) {
int arr[100];
int k = 10;
return arr[k+100];
}

int main(int argc, char **argv) {
printf("[start]\n");
int k = b(argc);
printf("%d\n", k);
printf("[end]\n");
return 1;
}

Result

clang++-9 -O0 -g -fsanitize=address -fno-omit-frame-pointer y
up.cc && ls -la ./a.out && ./a.out
-rwxr-xr-x 1 root root 1272624 Apr 20 10:22 ./a.out
[start]
...
==1633==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff13297d18 at pc 0x0000004c52a5 bp 0x7fff13297b30 sp 0x7fff13297b28
READ of size 4 at 0x7fff13297d18 thread T0
#0 0x4c52a4 in b(int) /git/afl+openssl/afl-training/challenges/heartbleed/yup.cc:6:8
#1 0x4c5371 in main /git/afl+openssl/afl-training/challenges/heartbleed/yup.cc:11:9
#2 0x7fe526f67bf6 in __libc_start_main /build/glibc-S9d2JN/glibc-2.27/csu/../csu/libc-start.c:310
#3 0x41b1b9 in _start (/git/afl+openssl/afl-training/challenges/heartbleed/a.out+0x41b1b9)
...

Additionally, if this kind (overread index that is bigger than the redzones eugenis mentioned) of issues must be detected, then UndefinedBehaviorSanitizer could be utilized:

Code

int b(int _a) {
int arr[100];
int k = 1000;
return arr[k+100];
}

int main(int argc, char **argv) {
printf("[start]\n");
int k = b(argc);
printf("%d\n", k);
printf("[end]\n");
return 1;
}

Result
clang++-9 -O0 -g -fsanitize=undefined -fno-sanitize-recover=all yup.cc && ls -la ./a.out && ./a.out
-rwxr-xr-x 1 root root 341256 Apr 20 10:27 ./a.out
[start]
yup.cc:6:8: runtime error: index 1100 out of bounds for type 'int [100]'

Thanks everyone,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants