|
@@ -6,6 +6,7 @@
|
|
|
#include <linux/config.h>
|
|
|
#include <linux/compiler.h>
|
|
|
#include "linux/sched.h"
|
|
|
+#include "linux/mm.h"
|
|
|
#include "asm/elf.h"
|
|
|
#include "asm/ptrace.h"
|
|
|
#include "asm/uaccess.h"
|
|
@@ -26,9 +27,17 @@ int is_syscall(unsigned long addr)
|
|
|
|
|
|
n = copy_from_user(&instr, (void __user *) addr, sizeof(instr));
|
|
|
if(n){
|
|
|
- printk("is_syscall : failed to read instruction from 0x%lx\n",
|
|
|
- addr);
|
|
|
- return(0);
|
|
|
+ /* access_process_vm() grants access to vsyscall and stub,
|
|
|
+ * while copy_from_user doesn't. Maybe access_process_vm is
|
|
|
+ * slow, but that doesn't matter, since it will be called only
|
|
|
+ * in case of singlestepping, if copy_from_user failed.
|
|
|
+ */
|
|
|
+ n = access_process_vm(current, addr, &instr, sizeof(instr), 0);
|
|
|
+ if(n != sizeof(instr)) {
|
|
|
+ printk("is_syscall : failed to read instruction from "
|
|
|
+ "0x%lx\n", addr);
|
|
|
+ return(1);
|
|
|
+ }
|
|
|
}
|
|
|
/* int 0x80 or sysenter */
|
|
|
return((instr == 0x80cd) || (instr == 0x340f));
|