Skip to content

Commit 8d21c8b

Browse files
authored
Merge pull request #8423 from 4B5F5F4B/main
[CPP][Linux Kernel]Add ql to detect CVE-2017-5123
2 parents e5ac492 + 9358b82 commit 8d21c8b

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* @name Linux kernel no check before unsafe_put_user vulnerability detection
3+
* @description unsafe_put_user which is used to write data to user-mode
4+
* memory is widely used in Linux kernel codebase, but if
5+
* there is no security check for user-mode pointer used as
6+
* parameter of unsafe_put_user, attacker can exploit the issue
7+
* to obtain root privilege. CVE-2017-5123 is quite a good
8+
* example for your information.
9+
* @kind problem
10+
* @id cpp/linux-kernel-no-check-before-unsafe-put-user
11+
* @problem.severity warning
12+
* @security-severity 7.5
13+
* @tags security
14+
* external/cwe/cwe-020
15+
*/
16+
17+
import cpp
18+
import semmle.code.cpp.dataflow.DataFlow
19+
20+
class WriteAccessCheckMacro extends Macro {
21+
VariableAccess va;
22+
23+
WriteAccessCheckMacro() {
24+
this.getName() = ["user_write_access_begin", "user_access_begin"] and
25+
va.getEnclosingElement() = this.getAnInvocation().getAnExpandedElement()
26+
}
27+
28+
VariableAccess getArgument() { result = va }
29+
}
30+
31+
class UnSafePutUserMacro extends Macro {
32+
PointerDereferenceExpr writeUserPtr;
33+
34+
UnSafePutUserMacro() {
35+
this.getName() = "unsafe_put_user" and
36+
writeUserPtr.getEnclosingElement() = this.getAnInvocation().getAnExpandedElement()
37+
}
38+
39+
Expr getUserModePtr() {
40+
result = writeUserPtr.getOperand().(AddressOfExpr).getOperand().(FieldAccess).getQualifier()
41+
}
42+
}
43+
44+
class ExploitableUserModePtrParam extends Parameter {
45+
ExploitableUserModePtrParam() {
46+
not exists(WriteAccessCheckMacro writeAccessCheck |
47+
DataFlow::localFlow(DataFlow::parameterNode(this),
48+
DataFlow::exprNode(writeAccessCheck.getArgument()))
49+
)
50+
}
51+
}
52+
53+
from ExploitableUserModePtrParam p, UnSafePutUserMacro unsafePutUser
54+
where
55+
DataFlow::localFlow(DataFlow::parameterNode(p), DataFlow::exprNode(unsafePutUser.getUserModePtr()))
56+
select p, "unsafe_put_user write user-mode pointer $@ without check.", p, p.toString()

0 commit comments

Comments
 (0)