Enforcing Kernel Security Invariants with Data Flow Integrity
Chengyu Song, ByoungyoungLee, Kangjie Lu, William Harris, Taesoo Kim, Wenke Lee Institute for Information Security & Privacy Georgia Tech
Enforcing Kernel Security Invariants with Data Flow Integrity - - PowerPoint PPT Presentation
Enforcing Kernel Security Invariants with Data Flow Integrity Chengyu Song , ByoungyoungLee, Kangjie Lu, William Harris, Taesoo Kim, Wenke Lee Institute for Information Security & Privacy Georgia Tech Kernel Memory Corruption Vulnerability
Chengyu Song, ByoungyoungLee, Kangjie Lu, William Harris, Taesoo Kim, Wenke Lee Institute for Information Security & Privacy Georgia Tech
(e.g., app sandbox)
2 / 24
3 / 24
Control-flow hijacking Bypass the check Data-oriented attacks Manipulate the check
1 static int acl_permission_check 2
(struct inode *inode, int mask)
3 { 4
unsigned int mode = inode->i_mode;
5 6
if (likely(uid_eq(current_fsuid(), inode->i_uid)))
7
mode >>= 6;
8
else if (in_group_p(inode->i_gid))
9
mode >>= 3;
10 11
if ((mask & ~mode &
12
(MAY_READ | MAY_WRITE | MAY_EXEC)) == 0)
13
return 0;
14
return -EACCES;
15 }
Code Injection Attack Disable the check
4 / 24
5 / 24
enforce access control invariants [NTIS AD-758 206]
6 / 24
for security checks (when they fail)
automatically infer security checks
long as there is no semantic errors)
7 / 24
Step 1: collect return values
1 static int acl_permission_check 2
(struct inode *inode, int mask)
3 { 4
unsigned int mode = inode->i_mode;
5 6
if (likely(uid_eq(current_fsuid(), inode->i_uid)))
7
mode >>= 6;
8
else if (in_group_p(inode->i_gid))
9
mode >>= 3;
10 11
if ((mask & ~mode &
12
(MAY_READ | MAY_WRITE | MAY_EXEC)) == 0)
13
return 0;
14
return -EACCES;
15 }
8 / 24
Step 2: collect conditional branches
1 static int acl_permission_check 2
(struct inode *inode, int mask)
3 { 4
unsigned int mode = inode->i_mode;
5 6
if (likely(uid_eq(current_fsuid(), inode->i_uid)))
7
mode >>= 6;
8
else if (in_group_p(inode->i_gid))
9
mode >>= 3;
10 11
if ((mask & ~mode &
12
(MAY_READ | MAY_WRITE | MAY_EXEC)) == 0)
13
return 0;
14
return -EACCES;
15 }
9 / 24
Step 2: collect conditional branches
if (condition1 || condition2) return 0; else return -EACCESS;
10 / 24
Step 2: collect conditional branches
if (condition) return -EINVAL; if (uid_eq) mode >> 6; else mode >> 3;
11 / 24
Step 3: collect dependencies
1 static int acl_permission_check 2
(struct inode *inode, int mask)
3 { 4
unsigned int mode = inode->i_mode;
5 6
if (likely(uid_eq(current_fsuid(), inode->i_uid)))
7
mode >>= 6;
8
else if (in_group_p(inode->i_gid))
9
mode >>= 3;
10 11
if ((mask & ~mode &
12
(MAY_READ | MAY_WRITE | MAY_EXEC)) == 0)
13
return 0;
14
return -EACCES;
15 }
12 / 24
13 / 24
graph (similar to control-flow integrity)
14 / 24
Write Integrity Test [S&P’08]
15 / 24
domain (ARM32), virtual address space, virtualization, TrustZone, etc.
sensitive data
16 / 24
address, register spills
17 / 24
18 / 24
19 / 24
163 115 93 50 40 37 40 119 60 42 37 30 31 36 20 40 60 80 100 120 140 160 180 net fs drivers kernel security include
Fields Structs 20 / 24
21 / 24
22 / 24
kernel
great way to build principled and practical security solution
23 / 24
24 / 24
Q & A