提交 690ed1ed 编写于 作者: L Longjun Luo 提交者: Longjun Luo

uprobe: add UPROBE_ALTER_PC flag for uprobe

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I61AXT
CVE: N/A

Within uprobe handlers, the pc register could be
modified. In this situation, there is no need to
do a single stepping. Just like the kprobe, we
skip it.
Signed-off-by: NLongjun Luo <luolongjun@huawei.com>
上级 61f39efb
...@@ -156,6 +156,15 @@ config UPROBES ...@@ -156,6 +156,15 @@ config UPROBES
managed by the kernel and kept transparent to the probed managed by the kernel and kept transparent to the probed
application. ) application. )
config UPROBES_SUPPORT_PC_ALTER
def_bool n
depends on UPROBES
help
Add UPROBE_ALTER_PC flag for uprobe handlers. When handlers
change the pc register, set this flag to let the uprobe
mechanism skip the execuation of the next insturction.
config HAVE_64BIT_ALIGNED_ACCESS config HAVE_64BIT_ALIGNED_ACCESS
def_bool 64BIT && !HAVE_EFFICIENT_UNALIGNED_ACCESS def_bool 64BIT && !HAVE_EFFICIENT_UNALIGNED_ACCESS
help help
......
...@@ -755,6 +755,7 @@ CONFIG_JUMP_LABEL=y ...@@ -755,6 +755,7 @@ CONFIG_JUMP_LABEL=y
CONFIG_OPTPROBES=y CONFIG_OPTPROBES=y
CONFIG_KPROBES_ON_FTRACE=y CONFIG_KPROBES_ON_FTRACE=y
CONFIG_UPROBES=y CONFIG_UPROBES=y
CONFIG_UPROBES_SUPPORT_PC_ALTER=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_KRETPROBES=y CONFIG_KRETPROBES=y
......
...@@ -22,8 +22,14 @@ struct inode; ...@@ -22,8 +22,14 @@ struct inode;
struct notifier_block; struct notifier_block;
struct page; struct page;
#define UPROBE_HANDLER_REMOVE 1 #define UPROBE_HANDLER_REMOVE 1
#define UPROBE_HANDLER_MASK 1
#ifndef CONFIG_UPROBES_SUPPORT_PC_ALTER
#define UPROBE_HANDLER_MASK 1
#else
#define UPROBE_ALTER_PC 0x2
#define UPROBE_HANDLER_MASK 0x3
#endif
#define MAX_URETPROBE_DEPTH 64 #define MAX_URETPROBE_DEPTH 64
......
...@@ -2070,10 +2070,17 @@ static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp) ...@@ -2070,10 +2070,17 @@ static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp)
return uprobe; return uprobe;
} }
#ifdef CONFIG_UPROBES_SUPPORT_PC_ALTER
static bool handler_chain(struct uprobe *uprobe, struct pt_regs *regs)
#else
static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs) static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs)
#endif
{ {
struct uprobe_consumer *uc; struct uprobe_consumer *uc;
int remove = UPROBE_HANDLER_REMOVE; int remove = UPROBE_HANDLER_REMOVE;
#ifdef CONFIG_UPROBES_SUPPORT_PC_ALTER
bool need_skip = false;
#endif
bool need_prep = false; /* prepare return uprobe, when needed */ bool need_prep = false; /* prepare return uprobe, when needed */
down_read(&uprobe->register_rwsem); down_read(&uprobe->register_rwsem);
...@@ -2090,6 +2097,10 @@ static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs) ...@@ -2090,6 +2097,10 @@ static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs)
need_prep = true; need_prep = true;
remove &= rc; remove &= rc;
#ifdef CONFIG_UPROBES_SUPPORT_PC_ALTER
if (rc & UPROBE_ALTER_PC)
need_skip = true;
#endif
} }
if (need_prep && !remove) if (need_prep && !remove)
...@@ -2100,6 +2111,9 @@ static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs) ...@@ -2100,6 +2111,9 @@ static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs)
unapply_uprobe(uprobe, current->mm); unapply_uprobe(uprobe, current->mm);
} }
up_read(&uprobe->register_rwsem); up_read(&uprobe->register_rwsem);
#ifdef CONFIG_UPROBES_SUPPORT_PC_ALTER
return need_skip;
#endif
} }
static void static void
...@@ -2241,7 +2255,12 @@ static void handle_swbp(struct pt_regs *regs) ...@@ -2241,7 +2255,12 @@ static void handle_swbp(struct pt_regs *regs)
if (arch_uprobe_ignore(&uprobe->arch, regs)) if (arch_uprobe_ignore(&uprobe->arch, regs))
goto out; goto out;
#ifdef CONFIG_UPROBES_SUPPORT_PC_ALTER
if (handler_chain(uprobe, regs))
goto out;
#else
handler_chain(uprobe, regs); handler_chain(uprobe, regs);
#endif
if (arch_uprobe_skip_sstep(&uprobe->arch, regs)) if (arch_uprobe_skip_sstep(&uprobe->arch, regs))
goto out; goto out;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册