fix incorrect arch register use for kprobe func with more parameters
authorYonghong Song <yhs@fb.com>
Fri, 19 Feb 2021 17:13:30 +0000 (09:13 -0800)
committeryonghong-song <ys114321@gmail.com>
Fri, 19 Feb 2021 18:15:51 +0000 (10:15 -0800)
Commit 12107c6936c6 ("use correct arch register for the
4th param of x86_64 syscalls") tries to use proper syscall
specific registers on x86_64 as its 4th param for syscall
is different from non-syscall. Unfortunately, the
implementation also uses syscall arch. register
for non-syscall kernel functions, which is incorrect.

This patch fixed the issue by using syscall arch
registers only for syscalls.

Reported-by: zhenwei pi <pizhenwei@bytedance.com>
Fixes: 12107c6936c6 ("use correct arch register for the 4th param of x86_64 syscalls")
Signed-off-by: Yonghong Song <yhs@fb.com>
src/cc/frontends/clang/b_frontend_action.cc

index c106c4a6b6618134fbfb02fdde5730da783d537b..da9b8ed9c0fd11e7eb3eb87b4945ab30f2f94f5f 100644 (file)
@@ -766,17 +766,20 @@ void BTypeVisitor::genParamIndirectAssign(FunctionDecl *D, string& preamble,
 }
 
 void BTypeVisitor::rewriteFuncParam(FunctionDecl *D) {
-  const char **calling_conv_regs = get_call_conv(true);
-
   string preamble = "{\n";
   if (D->param_size() > 1) {
+    bool is_syscall = false;
+    if (strncmp(D->getName().str().c_str(), "syscall__", 9) == 0 ||
+        strncmp(D->getName().str().c_str(), "kprobe____x64_sys_", 18) == 0)
+      is_syscall = true;
+    const char **calling_conv_regs = get_call_conv(is_syscall);
+
     // If function prefix is "syscall__" or "kprobe____x64_sys_",
     // the function will attach to a kprobe syscall function.
     // Guard parameter assiggnment with CONFIG_ARCH_HAS_SYSCALL_WRAPPER.
     // For __x64_sys_* syscalls, this is always true, but we guard
     // it in case of "syscall__" for other architectures.
-    if (strncmp(D->getName().str().c_str(), "syscall__", 9) == 0 ||
-        strncmp(D->getName().str().c_str(), "kprobe____x64_sys_", 18) == 0) {
+    if (is_syscall) {
       preamble += "#if defined(CONFIG_ARCH_HAS_SYSCALL_WRAPPER) && !defined(__s390x__)\n";
       genParamIndirectAssign(D, preamble, calling_conv_regs);
       preamble += "\n#else\n";