본문 바로가기

[Debugging] Tips

[리눅스커널] 리눅스 커널 브링업 패치 [1] (4.14v)

diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index f702f2b..299427d 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c

 

@@ -435,6 +435,45 @@ int call_undef_hook(struct pt_regs *regs, unsigned int instr)
  return fn ? fn(regs, instr) : 1;
 }
 
+void trace_exe_filename(void)
+{
+ struct file *exe_file;
+ char *pathbuf, *fname;
+
+ printk("[+][trace][%s][%s,%d] caller: %pS  \n",
+ current->comm, __func__,__LINE__,  (void *)__builtin_return_address(0));
+
+ exe_file = get_mm_exe_file(current->mm);
+
+ if (!exe_file)
+ {
+ printk("[-] path unknown: %s \n", current->comm);
+ return;
+ }
+
+ pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY);
+
+ if (!pathbuf) {
+ printk("[-] memory starved: %s \n", current->comm);
+ goto put_exe_file;
+ }
+
+ fname = d_path(&exe_file->f_path, pathbuf, PATH_MAX);
+
+ if (IS_ERR(fname)) {
+ printk("[-] path error: %s \n", current->comm);
+ goto free_buf;
+ }
+
+ printk("[+][%s]: exe_file: %s \n", current->comm, fname);
+
+free_buf:
+ kfree(pathbuf);
+put_exe_file:
+ fput(exe_file);
+ return;
+}
+
 asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
 {
  unsigned int instr;
@@ -476,6 +515,12 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
  return;
 
 die_sig:
+ printk("%s (%d): undefined instruction: pc=%p\n",
+ current->comm, task_pid_nr(current), pc);
+ __show_regs(regs);
+ dump_instr(KERN_INFO, regs);
+ trace_exe_filename();
+
 #ifdef CONFIG_DEBUG_USER
  if (user_debug & UDBG_UNDEFINED) {
  pr_info("%s (%d): undefined instruction: pc=%p\n",
@@ -553,6 +598,10 @@ static int bad_syscall(int n, struct pt_regs *regs)
  }
 #endif
 
+ pr_err("[%d] %s: obsolete system call %08x.\n",
+ task_pid_nr(current), current->comm, n);
+ dump_instr(KERN_ERR, regs);
+
  info.si_signo = SIGILL;
  info.si_errno = 0;
  info.si_code  = ILL_ILLTRP;
@@ -682,6 +731,17 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
  }
  }
 #endif
+
+ pr_err("[%d] %s: arm syscall %d\n",
+        task_pid_nr(current), current->comm, no);
+ dump_instr("", regs);
+ if (user_mode(regs)) {
+ __show_regs(regs);
+ c_backtrace(frame_pointer(regs), processor_mode(regs));
+ }
+
+ trace_exe_filename();
+
  info.si_signo = SIGILL;
  info.si_errno = 0;
  info.si_code  = ILL_ILLTRP;
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 49b1b80..be205c9 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -167,6 +167,11 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
  if (addr > TASK_SIZE)
  harden_branch_predictor();
 
+ printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n",
+        tsk->comm, sig, addr, fsr);
+ show_pte(tsk->mm, addr);
+ show_regs(regs);
+
 #ifdef CONFIG_DEBUG_USER
  if (((user_debug & UDBG_SEGV) && (sig == SIGSEGV)) ||
      ((user_debug & UDBG_BUS)  && (sig == SIGBUS))) {
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 4cacc33d..41ed6f1 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -414,6 +414,7 @@ void arm64_notify_segfault(struct pt_regs *regs, unsigned long addr)
 
 asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
 {
+ void __user *pc = (void __user *)instruction_pointer(regs);
  /* check for AArch32 breakpoint instructions */
  if (!aarch32_break_handler(regs))
  return;
@@ -421,6 +422,11 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
  if (call_undef_hook(regs) == 0)
  return;
 
+ printk("+[F:%s, L:%d] caller(%pS)\n", __func__, __LINE__, (void *)__builtin_return_address(0));
+ printk("+%s[%d]: undef at 0x%08lx",
+ current->comm, task_pid_nr(current), (unsigned long)pc);
+ __show_regs(regs);
+
  force_signal_inject(SIGILL, ILL_ILLOPC, regs, 0);
 }
 
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 465b90d..a4c53f0 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -303,6 +303,13 @@ static void __do_user_fault(struct task_struct *tsk, unsigned long addr,
  const struct fault_info *inf;
  unsigned int lsb = 0;
 
+ printk("+[F:%s, L:%d] caller(%pS)\n", __func__, __LINE__, (void *)__builtin_return_address(0));
+ printk("+%s[%d]: faults:(%d) at 0x%08lx, esr 0x%03x",
+ tsk->comm, task_pid_nr(tsk), sig,
+ addr, esr);
+
+ __show_regs(regs);
+
  if (unhandled_signal(tsk, sig) && show_unhandled_signals_ratelimited()) {
  inf = esr_to_fault_info(esr);
  pr_info("%s[%d]: unhandled %s (%d) at 0x%08lx, esr 0x%03x",
diff --git a/fs/exec.c b/fs/exec.c
index 0936b5a..ddfced9 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1666,6 +1666,34 @@ int search_binary_handler(struct linux_binprm *bprm)
 }
 EXPORT_SYMBOL(search_binary_handler);
 
+#define PROCESS_ARG_BUFF_SIZE 128
+
+void trace_process_exec_profile(const char *fname)
+{
+ char process_arg_buf[PROCESS_ARG_BUFF_SIZE] = {0,};
+ int len = 0;
+
+ len = get_cmdline(current, process_arg_buf, PROCESS_ARG_BUFF_SIZE -1);
+
+ if(len == 0) {
+ printk("[-] Error: len: %d \n", len);
+ return;
+ }
+
+ if(!fname) {
+ printk("[-] Error: fname null \n");
+ return;
+ }
+
+ if (len > PROCESS_ARG_BUFF_SIZE)
+ len = PROCESS_ARG_BUFF_SIZE;
+
+ process_arg_buf[len] = '\0';
+
+    pr_info("[exec:%s-%d] exec_file: %s, arg: [%s] \n",
+ current->comm, current->pid, fname, process_arg_buf);
+}
+
 static int exec_binprm(struct linux_binprm *bprm)
 {
  pid_t old_pid, old_vpid;
@@ -1683,6 +1711,8 @@ static int exec_binprm(struct linux_binprm *bprm)
  trace_sched_process_exec(current, old_pid, bprm);
  ptrace_event(PTRACE_EVENT_EXEC, old_vpid);
  proc_exec_connector(current);
+
+ trace_process_exec_profile(bprm->filename);
  }
 
  return ret;
diff --git a/fs/open.c b/fs/open.c
index 28a3956..f0bd689 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -1047,6 +1047,27 @@ struct file *filp_clone_open(struct file *oldfile)
 }
 EXPORT_SYMBOL(filp_clone_open);
 
+static void _trace_do_sys_open(struct file *filp, int flags, int mode, long fd)
+{
+       char *buf;
+       char *fname;
+
+       buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!buf)
+               return;
+
+       fname = d_path(&filp->f_path, buf, PAGE_SIZE);
+
+       if (IS_ERR(fname))
+               goto out;
+
+       printk("%s: open(\"%s\", %d, %d) fd = %ld, inode = %ld\n",
+                            current->comm, fname, flags, mode, fd, filp->f_inode->i_ino);
+
+out:
+       kfree(buf);
+}
+
 long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
 {
  struct open_flags op;
@@ -1069,6 +1090,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
  } else {
  fsnotify_open(f);
  fd_install(fd, f);
+ _trace_do_sys_open(f, flags, mode, fd);
  }
  }
  putname(tmp);
diff --git a/kernel/signal.c b/kernel/signal.c
index 619c616..b8d168a 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1133,6 +1133,8 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
  complete_signal(sig, t, group);
 ret:
  trace_signal_generate(sig, info, t, group, result);
+ printk("[+][sig_gen][%s] sig = %d, target = %s \n",
+ current->comm, sig, t->comm);
  return ret;
 }
 
@@ -1628,6 +1630,8 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
  result = TRACE_SIGNAL_DELIVERED;
 out:
  trace_signal_generate(sig, &q->info, t, group, result);
+ printk("[++][sig_gen][%s] sig = %d, target = %s \n",
+ current->comm, sig, t->comm);
  unlock_task_sighand(t, &flags);
 ret:
  return ret;
@@ -2312,6 +2316,9 @@ int get_signal(struct ksignal *ksig)
  /* Trace actually delivered signals. */
  trace_signal_deliver(signr, &ksig->info, ka);
 
+ printk("[+][signal_deliver][%s] sig = %d, \n",
+ current->comm, signr);
+
  if (ka->sa.sa_handler == SIG_IGN) /* Do nothing.  */
  continue;
  if (ka->sa.sa_handler != SIG_DFL) {