Create NoCheckBeforeUnsafePutUser.ql

This commit is contained in:
4B5F5F4B
2022-03-26 22:45:03 +08:00
committed by GitHub
parent 64863d493b
commit 7a091f808b

View File

@@ -0,0 +1,56 @@
/**
* @name Linux kernel no check before unsafe_put_user vulnerability detection
* @description unsafe_put_user which is used to write data to user-mode
* memory is widely used in Linux kernel codebase, but if
* there is no security check for user-mode pointer used as
* parameter of unsafe_put_user, attacker can exploit the issue
* to obtain root privilege. CVE-2017-5123 is quite a good
* example for your information.
* @kind problem
* @id cpp/linux-kernel-no-check-before-unsafe-put-user
* @problem.severity warning
* @security-severity 7.5
* @tags security
* external/cwe/cwe-020
*/
import cpp
import semmle.code.cpp.dataflow.DataFlow
class WrtieAccessCheckMacro extends Macro {
VariableAccess va;
WrtieAccessCheckMacro() {
this.getName() = ["user_write_access_begin", "user_access_begin"] and
va.getEnclosingElement() = this.getAnInvocation().getAnExpandedElement()
}
VariableAccess getArgument() { result = va }
}
class UnSafePutUserMacro extends Macro {
PointerDereferenceExpr writeUserPtr;
UnSafePutUserMacro() {
this.getName() = "unsafe_put_user" and
writeUserPtr.getEnclosingElement() = this.getAnInvocation().getAnExpandedElement()
}
Expr getUserModePtr() {
result = writeUserPtr.getOperand().(AddressOfExpr).getOperand().(FieldAccess).getQualifier()
}
}
class ExploitableUserModePtrParam extends Parameter {
ExploitableUserModePtrParam() {
not exists(WrtieAccessCheckMacro writeAccessCheck |
DataFlow::localFlow(DataFlow::parameterNode(this),
DataFlow::exprNode(writeAccessCheck.getArgument()))
)
}
}
from ExploitableUserModePtrParam p, UnSafePutUserMacro unsafePutUser
where
DataFlow::localFlow(DataFlow::parameterNode(p), DataFlow::exprNode(unsafePutUser.getUserModePtr()))
select p, unsafePutUser, "potential wrtie user mode ptr without check."