verifying the safety of user pointer dereferences
DESCRIPTION
Verifying the Safety of User Pointer Dereferences. Suhabe Bugrara [email protected] Stanford University Joint work with Alex Aiken. Unchecked User Pointer Dereferences. Security property of operating systems Two types of pointers in operating systems - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/1.jpg)
Verifying the Safety of User Pointer Dereferences
Suhabe [email protected]
Stanford University
Joint work with Alex Aiken
![Page 2: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/2.jpg)
Unchecked User Pointer Dereferences
• Security property of operating systems• Two types of pointers in operating systems
– kernel pointer: pointer created by the operating system– user pointer: pointer created by a user application and passed to the
operating system via an entry point such as a system call
• Must check that a user pointer points into userspace before dereferencing it
![Page 3: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/3.jpg)
Unchecked User PointerDereferences
1: static ssize_t read_port(…, char * __user buf, …) { 2: unsigned long i = *ppos; 3: char * __user tmp = buf; 4:
![Page 4: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/4.jpg)
Unchecked User PointerDereferences
1: static ssize_t read_port(…, char * __user buf, …) { 2: unsigned long i = *ppos; 3: char * __user tmp = buf; 4:
7: 8: while (count-- > 0 && i < 65536) { 9: if (__put_user(inb(i),tmp) < 0)
//deref10: return -EFAULT; 11: i++; 12: tmp++; 13: }14:15: *ppos = i; 16: return tmp-buf; 17: }
![Page 5: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/5.jpg)
Unchecked User PointerDereferences
1: static ssize_t read_port(…, char * __user buf, …) { 2: unsigned long i = *ppos; 3: char * __user tmp = buf; 4: 5: if (!access_ok(..,buf,...)) //check 6: return -EFAULT; 7: 8: while (count-- > 0 && i < 65536) { 9: if (__put_user(inb(i),tmp) < 0) //deref10: return -EFAULT; 11: i++; 12: tmp++; 13: }14:15: *ppos = i; 16: return tmp-buf; 17: }
![Page 6: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/6.jpg)
Security Vulnerability
• Malicious user could– Take control of the operating system– Overwrite kernel data structures– Read sensitive data out of kernel memory– Crash machine by corrupting data
![Page 7: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/7.jpg)
Goal
• Design a program analysis to prove statically that no unchecked user pointer dereferences exist in the entire operating system
![Page 8: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/8.jpg)
Challenges
• Verification – provide guarantee of correctness
• Precision– report low number of false alarms
• Scalability– analyze more than 6 MLOC
![Page 9: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/9.jpg)
Verification
![Page 10: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/10.jpg)
Verification
• Soundness– If the program analysis reports that no
vulnerabilities exist, then the program contains none
![Page 11: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/11.jpg)
Verification
• Soundness– If the program analysis reports that no
vulnerabilities exist, then the program contains none
• Completeness– If the program analysis reports that a
vulnerability exists, then program contains one
![Page 12: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/12.jpg)
Verification
• Soundness– If the program analysis reports that no
vulnerabilities exist, then the program contains none
• Completeness– If the program analysis reports that a vulnerability
exists, then program contains one
• Impossible for a program analysis to be both sound and complete
![Page 13: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/13.jpg)
Sound and Incomplete Verifier
1. Proves the absence of vulnerabilities
2. May report false alarms
![Page 14: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/14.jpg)
Soundness Caveats
1. Unsafe memory operations
2. Concurrency
3. Inline assembly
4. Analysis fails to analyze some procedures
![Page 15: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/15.jpg)
Precision
• Minimize the number of false alarms
• Reasoning more deeply about program
• Computationally expensive
• High precision inhibits scalability
![Page 16: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/16.jpg)
Example1: void sys_call (int *u, const int cmd) { //u is user pointer
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) { //check u
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u; //dereference u
12: }
![Page 17: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/17.jpg)
One Possible Approach1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user)
![Page 18: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/18.jpg)
One Possible Approach1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user)
(*u,user)
![Page 19: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/19.jpg)
One Possible Approach1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user)
(*u,user)
(*u,user)
![Page 20: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/20.jpg)
One Possible Approach
(*u,user)(*u,checked)
1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user)
(*u,user)
(*u,user)
![Page 21: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/21.jpg)
One Possible Approach
(*u,user) lost precision!
(*u,user)(*u,checked)
1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user)
(*u,user)
(*u,user)
![Page 22: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/22.jpg)
One Possible Approach
…, but, procedure does not contain any vulnerabilities!
(*u,user)(*u,error) emit warning!
(*u,user) lost precision!
(*u,user)(*u,checked)
1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user)
(*u,user)
(*u,user)
![Page 23: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/23.jpg)
Path Sensitivity
• Ability to reason about branch correlations
• Programs use substantial amount of branch correlation in practice
• Important for reducing the number of false alarms
![Page 24: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/24.jpg)
Example1: void sys_call (int *u, int cmd) { //u is user pointer
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) { //check u
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u; //dereference u
12: }
![Page 25: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/25.jpg)
Path Sensitivity
Valid Path
1: void sys_call (int *u, int cmd) { //u is user pointer
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) { //check u
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u; //dereference u
12: }
![Page 26: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/26.jpg)
Path Sensitivity
Valid Path
1: void sys_call (int *u, const int cmd) { //u is user pointer
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) { //check u
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u; //dereference u
12: }
![Page 27: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/27.jpg)
Path Sensitivity
Valid Path
1: void sys_call (int *u, const int cmd) { //u is user pointer
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) { //check u
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u; //dereference u
12: }
![Page 28: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/28.jpg)
Path Sensitivity
Invalid Path!
1: void sys_call (int *u, const int cmd) { //u is user pointer
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) { //check u
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u; //dereference u
12: }
![Page 29: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/29.jpg)
Path Sensitive Analysis1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
![Page 30: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/30.jpg)
Path Sensitive Analysis
(*u,user) true1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
![Page 31: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/31.jpg)
Path Sensitive Analysis
(*u,user) true1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
“guard”
![Page 32: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/32.jpg)
Path Sensitive Analysis
(*u,user) true1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user) true
![Page 33: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/33.jpg)
Path Sensitive Analysis
(*u,user) true1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user) true
(*u,user) true
![Page 34: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/34.jpg)
Path Sensitive Analysis
(*u,user) true(*u,checked) cmd == 1
(*u,user) true1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user) true
(*u,user) true
![Page 35: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/35.jpg)
Path Sensitive Analysis
(*u,user) true(*u,checked) cmd == 1
(*u,user) true(*u,checked) cmd == 1
(*u,user) true 1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user) true
(*u,user) true
![Page 36: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/36.jpg)
Path Sensitive Analysis
(*u,user) true(*u,checked) cmd == 1(*u,error) . . .
(*u,user) true(*u,checked) cmd == 1
(*u,user) true(*u,checked) cmd == 1
(*u,user) true1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user) true
(*u,user) true
![Page 37: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/37.jpg)
Path Sensitive Analysis
(*u,user) true(*u,checked) cmd == 1(*u,error) cmd == 1 &&
. . .
(*u,user) true(*u,checked) cmd == 1
(*u,user) true(*u,checked) cmd == 1
(*u,user) true1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user) true
(*u,user) true
![Page 38: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/38.jpg)
Path Sensitive Analysis
(*u,user) true(*u,checked) cmd == 1(*u,error) cmd == 1 &&
!(cmd == 1) && . . .
(*u,user) true(*u,checked) cmd == 1
(*u,user) true(*u,checked) cmd == 1
(*u,user) true1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user) true
(*u,user) true
![Page 39: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/39.jpg)
Path Sensitive Analysis
(*u,user) true(*u,checked) cmd == 1(*u,error) cmd == 1 &&
!(cmd == 1) && true
. . .
(*u,user) true(*u,checked) cmd == 1
(*u,user) true(*u,checked) cmd == 1
(*u,user) true1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user) true
(*u,user) true
![Page 40: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/40.jpg)
Path Sensitive Analysis
(*u,user) true(*u,checked) cmd == 1(*u,error) cmd == 1 &&
!(cmd == 1) && true
false
(*u,user) true(*u,checked) cmd == 1
(*u,user) true(*u,checked) cmd == 1
(*u,user) true1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user) true
(*u,user) true
![Page 41: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/41.jpg)
Path Sensitive Analysis
(*u,user) true(*u,checked) cmd == 1(*u,error) false
(*u,user) true(*u,checked) cmd == 1
(*u,user) true(*u,checked) cmd == 1
(*u,user) true1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user) true
(*u,user) true
![Page 42: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/42.jpg)
Path Sensitive Analysis
(*u,user) true(*u,checked) cmd == 1(*u,error) false
(*u,user) true(*u,checked) cmd == 1
(*u,user) true(*u,checked) cmd == 1
(*u,user) true1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user) true
(*u,user) true
![Page 43: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/43.jpg)
Scalability
1. Abstraction– Throw away guards at procedure boundaries
2. Compositionality– Analyze each procedure in isolation
![Page 44: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/44.jpg)
Path Sensitive Analysis
(*u,user) true(*u,checked) cmd == 1(*u,error) false
(*u,user) true(*u,checked) cmd == 1
(*u,user) true(*u,checked) cmd == 1
(*u,user) true1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user) true
(*u,user) true
![Page 45: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/45.jpg)
Abstraction
(*u,user) true(*u,checked) cmd == 1(*u,error) false
initial summary
![Page 46: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/46.jpg)
Abstraction
(*u,user) true(*u,checked) cmd == 1(*u,error) false
α =
abstraction function
initial summary
![Page 47: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/47.jpg)
Abstraction
(*u,user) true(*u,checked) cmd == 1(*u,error) false
α =(*u,user) true(*u,checked) false(*u,error) false
abstraction function
initial summary
finalsummary
![Page 48: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/48.jpg)
Abstraction
(*u,user) true(*u,checked) cmd == 1(*u,error) false
(*u,user) true(*u,checked) cmd == 1
(*u,user) true(*u,checked) cmd == 1
(*u,user) true1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user) true
(*u,user) true
![Page 49: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/49.jpg)
Abstraction
(*u,user) true(*u,checked) false(*u,error) false
(*u,user) true(*u,checked) cmd == 1
(*u,user) true(*u,checked) cmd == 1
(*u,user) true1: void sys_call (int *u, const int cmd) {
2: int x;
3:
4: if (cmd == 1) {
5: if (!access_ok(u)) {
6: return;
7: }
8: }
9: …
10: if (cmd == 1)
11: x = *u;
12: }
(*u,user) true
(*u,user) true
![Page 50: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/50.jpg)
Compositionality1: int get (int *v) {
2: int x;
3:
4: x = *v;
5:
6: return x;
7: }
![Page 51: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/51.jpg)
Compositionality
(*v,user) c1
1: int get (int *v) {
2: int x;
3:
4: x = *v;
5:
6: return x;
7: }
![Page 52: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/52.jpg)
Compositionality
(*v,user) c1
1: int get (int *v) {
2: int x;
3:
4: x = *v;
5:
6: return x;
7: }
“context variable”
![Page 53: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/53.jpg)
Compositionality
(*v,user) c1
1: int get (int *v) {
2: int x;
3:
4: x = *v;
5:
6: return x;
7: }
(*v,user) c1
![Page 54: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/54.jpg)
Compositionality
(*v,user) c1
1: int get (int *v) {
2: int x;
3:
4: x = *v;
5:
6: return x;
7: }
(*v,user) c1
(*v,user) c1
(*v,error) c1
![Page 55: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/55.jpg)
Compositionality
(*v,user) c1
1: int get (int *v) {
2: int x;
3:
4: x = *v;
5:
6: return x;
7: }
(*v,user) c1
(*v,user) c1
(*v,error) c1
![Page 56: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/56.jpg)
Fixed Point Computation
• Generate summary of behavior for each procedure with respect to calling context
• Apply summary of callee at call site in caller
• Repeatedly generate and apply summaries until a fixed point is reached
![Page 57: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/57.jpg)
Analysis Passes
1. Alias analysis• computes memory model for each procedure
![Page 58: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/58.jpg)
Analysis Passes
1. Alias analysis• computes memory model for each procedure
2. User state propagation• propagates user states throughout OS
![Page 59: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/59.jpg)
Analysis Passes
1. Alias analysis• computes memory model for each procedure
2. User state propagation• propagates user states throughout OS
3. Unchecked and safety state propagation• determines safety of each dereference site
![Page 60: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/60.jpg)
Linux 2.6.17.1 built for x86
lines of code 6.2 million
procedures 91,543
global variables 40,760
composite types 14,794
initializers 35,317
loops 33,886
system call parameters 627
dereference sites 867,544
![Page 61: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/61.jpg)
Experiment Setup
time bound per procedure 3 minutes
alias analysis time outs ~9 K procedures (10%)
user ptr analysis time outs 154 procedures (0.17%)
compute nodes 25
cpus per node 4
memory per node 6 GB
total run time 3.5 hours
![Page 62: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/62.jpg)
Results
• Verified automatically– 616 out of 627 system call parameters (98.2 %)– 851,686 out of 852,092 dereferences (99.95%)
• Warnings– 11 warnings on system call parameters– 406 warnings on dereferences– 22 annotations required to verify
![Page 63: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/63.jpg)
1: int verify_iovec (struct msghdr *m, ..., char *address, int mode)
2: {
3: int err;
4:
5: if (m->msg_namelen) {
6: if (mode == VERIFY_READ) {
7: err = move_addr_to_kernel (m->msg_name,
8: m->msg_namelen,
9: address);
10: if (err < 0) return err;
11: }
12:
13: m->msg_name = address;
14: } else {
15: m->msg_name = NULL;
16: }
17: ...
18:}
False Alarm: Interprocedural Must-Modify
![Page 64: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/64.jpg)
1: int verify_iovec (struct msghdr *m, ..., char *address, int mode)
2: {
3: int err;
4:
5: if (m->msg_namelen) {
6: if (mode == VERIFY_READ) {
7: err = move_addr_to_kernel (m->msg_name,
8: m->msg_namelen,
9: address);
10: if (err < 0) return err;
11: }
12:
13: m->msg_name = address;
14: } else {
15: m->msg_name = NULL;
16: }
17: ...
18:}
False Alarm: Interprocedural Must-Modify
![Page 65: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/65.jpg)
1: int verify_iovec (struct msghdr *m, ..., char *address, int mode)
2: {
3: int err;
4:
5: if (m->msg_namelen) {
6: if (mode == VERIFY_READ) {
7: err = move_addr_to_kernel (m->msg_name,
8: m->msg_namelen,
9: address);
10: if (err < 0) return err;
11: }
12:
13: m->msg_name = address;
14: } else {
15: m->msg_name = NULL;
16: }
17: ...
18:}
False Alarm: Interprocedural Must-Modify
![Page 66: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/66.jpg)
1: int verify_iovec (struct msghdr *m, ..., char *address, int mode)
2: {
3: int err;
4:
5: if (m->msg_namelen) {
6: if (mode == VERIFY_READ) {
7: err = move_addr_to_kernel (m->msg_name,
8: m->msg_namelen,
9: address);
10: if (err < 0) return err;
11: }
12:
13: m->msg_name = address;
14: } else {
15: m->msg_name = NULL;
16: }
17: ...
18:}
False Alarm: Interprocedural Must-Modify
m->msg_name must-modified under !(m->msg_namelen && mode == VERIFY_READ && err < 0)
![Page 67: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/67.jpg)
False Alarm:Interprocedural Branch Correlation
1: int sound_ioctl(uint cmd, ulong arg) {
2:
3: if (_SIOC_DIR(cmd) != _SIOC_NONE &&
4: _SIOC_DIR(cmd) != 0)
5:
6: if(_SIOC_DIR(cmd)&_SIOC_WRITE)
7: if (!access_ok(arg))
8: return -EFAULT;
9:
10: ...
11: return sound_mixer_ioctl(cmd, arg);
12: }
13: int sound_mixer_ioctl(uint cmd, void *arg) 14: { 15: ... 16: return aci_mixer_ioctl(cmd, arg); 17: }18: 19: 20: int aci_mixer_ioctl(uint cmd, void *arg) 21: {22: switch(cmd) 23: case SOUND_MIXER_WRITE_IGAIN: 24: ...*arg...; 25: ... 26: }
![Page 68: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/68.jpg)
False Alarm:Interprocedural Branch Correlation
1: int sound_ioctl(uint cmd, ulong arg) {
2:
3: if (_SIOC_DIR(cmd) != _SIOC_NONE &&
4: _SIOC_DIR(cmd) != 0)
5:
6: if(_SIOC_DIR(cmd)&_SIOC_WRITE)
7: if (!access_ok(arg))
8: return -EFAULT;
9:
10: ...
11: return sound_mixer_ioctl(cmd, arg);
12: }
13: int sound_mixer_ioctl(uint cmd, void *arg) 14: { 15: ... 16: return aci_mixer_ioctl(cmd, arg); 17: }18: 19: 20: int aci_mixer_ioctl(uint cmd, void *arg) 21: {22: switch(cmd) 23: case SOUND_MIXER_WRITE_IGAIN: 24: ...*arg...; 25: ... 26: }
1
![Page 69: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/69.jpg)
False Alarm:Interprocedural Branch Correlation
1: int sound_ioctl(uint cmd, ulong arg) {
2:
3: if (_SIOC_DIR(cmd) != _SIOC_NONE &&
4: _SIOC_DIR(cmd) != 0)
5:
6: if(_SIOC_DIR(cmd)&_SIOC_WRITE)
7: if (!access_ok(arg))
8: return -EFAULT;
9:
10: ...
11: return sound_mixer_ioctl(cmd, arg);
12: }
13: int sound_mixer_ioctl(uint cmd, void *arg) 14: { 15: ... 16: return aci_mixer_ioctl(cmd, arg); 17: }18: 19: 20: int aci_mixer_ioctl(uint cmd, void *arg) 21: {22: switch(cmd) 23: case SOUND_MIXER_WRITE_IGAIN: 24: ...*arg...; 25: ... 26: }
1. *argchecked under condition_SIOC_DIR(cmd) != _SIOC_NONE && _SIOC_DIR(cmd) != 0 && _SIOC_DIR(cmd)&_SIOC_WRITE
1
![Page 70: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/70.jpg)
False Alarm:Interprocedural Branch Correlation
1: int sound_ioctl(uint cmd, ulong arg) {
2:
3: if (_SIOC_DIR(cmd) != _SIOC_NONE &&
4: _SIOC_DIR(cmd) != 0)
5:
6: if(_SIOC_DIR(cmd)&_SIOC_WRITE)
7: if (!access_ok(arg))
8: return -EFAULT;
9:
10: ...
11: return sound_mixer_ioctl(cmd, arg);
12: }
13: int sound_mixer_ioctl(uint cmd, void *arg) 14: { 15: ... 16: return aci_mixer_ioctl(cmd, arg); 17: }18: 19: 20: int aci_mixer_ioctl(uint cmd, void *arg) 21: {22: switch(cmd) 23: case SOUND_MIXER_WRITE_IGAIN: 24: ...*arg...; 25: ... 26: }
1. *argchecked under condition_SIOC_DIR(cmd) != _SIOC_NONE && _SIOC_DIR(cmd) != 0 && _SIOC_DIR(cmd)&_SIOC_WRITE
1
2
![Page 71: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/71.jpg)
False Alarm:Interprocedural Branch Correlation
1: int sound_ioctl(uint cmd, ulong arg) {
2:
3: if (_SIOC_DIR(cmd) != _SIOC_NONE &&
4: _SIOC_DIR(cmd) != 0)
5:
6: if(_SIOC_DIR(cmd)&_SIOC_WRITE)
7: if (!access_ok(arg))
8: return -EFAULT;
9:
10: ...
11: return sound_mixer_ioctl(cmd, arg);
12: }
13: int sound_mixer_ioctl(uint cmd, void *arg) 14: { 15: ... 16: return aci_mixer_ioctl(cmd, arg); 17: }18: 19: 20: int aci_mixer_ioctl(uint cmd, void *arg) 21: {22: switch(cmd) 23: case SOUND_MIXER_WRITE_IGAIN: 24: ...*arg...; 25: ... 26: }
1. *argchecked under condition_SIOC_DIR(cmd) != _SIOC_NONE && _SIOC_DIR(cmd) != 0 && _SIOC_DIR(cmd)&_SIOC_WRITE
2. cmd == SOUND_MIXER_WRITE_IGAIN implies_SIOC_DIR(cmd) != _SIOC_NONE && _SIOC_DIR(cmd) != 0 && _SIOC_DIR(cmd)&_SIOC_WRITE
1
2
![Page 72: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/72.jpg)
False Alarm:Function Pointers
1: struct { char *name; ...} map[] = ...,
2: {[NFSCTL_GETFD] = {.name = ".getfd", ...},
3: [NFSCTL_GETFS] = {.name = ".getfs", ...},};
4:
5: long sys_nfsservctl (int cmd, ..., void *res) {
6: ...
7: struct file *file = do_open(map[cmd].name);
8: ...
9: int err = file->f_op->read(file, res, ...);
10: ...
11: }
![Page 73: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/73.jpg)
False Alarm:Function Pointers
1: int notifier_call_chain(struct notifier_block **nl, ulong val, void *v)
2: {
3: int ret = NOTIFY_DONE;
4: struct notifier_block *nb;
5:
6: nb = *nl;
7:
8: while (nb) {
9: ret = nb->notifier_call(nb, val, v);
10: ...
11: nb = nb->next;
12: }
13:
14: return ret;
15: }
![Page 74: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/74.jpg)
Related Work
• MECA, by Yang, Kremenek, Xie, Engler
– bug finder, path-insensitive, Linux, automatic
• Sparse, by Torvalds
– bug finder, path-insensitive, Linux, 10,000 annotations
• CQual, by Johnson, Wagner
– verifier, path-insensitive, Linux, automatic, 300 KLOC
• ESP, by Dor, Adams, Das, Yang
– verifier, path-sensitive, Windows, automatic, 1 MLOC
![Page 75: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/75.jpg)
Future Work
• Eliminate the time outs on procedures
• Handle inline assembly statements
• Reduce number of false alarms
![Page 76: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/76.jpg)
Conclusions
• Nearly verifying important security property
• Scaling to largest open source program
• Reporting low number of false alarms
![Page 77: Verifying the Safety of User Pointer Dereferences](https://reader035.vdocuments.mx/reader035/viewer/2022062408/568144de550346895db1aaaf/html5/thumbnails/77.jpg)
Questions