Skip to content

Commit 5b12981

Browse files
committed
Merge tag 'x86_urgent_for_v6.2_rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Borislav Petkov: - Two fixes to correct how kprobes handles INT3 now that they're added by other functionality like the rethunks and not only kgdb - Remove __init section markings of two functions which are referenced by a function in the .text section * tag 'x86_urgent_for_v6.2_rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/kprobes: Fix optprobe optimization check with CONFIG_RETHUNK x86/kprobes: Fix kprobes instruction boudary check with CONFIG_RETHUNK x86/calldepth: Fix incorrect init section references
2 parents 95d248d + 63dc632 commit 5b12981

File tree

3 files changed

+17
-25
lines changed

3 files changed

+17
-25
lines changed

arch/x86/kernel/callthunks.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ static bool is_coretext(const struct core_text *ct, void *addr)
119119
return within_module_coretext(addr);
120120
}
121121

122-
static __init_or_module bool skip_addr(void *dest)
122+
static bool skip_addr(void *dest)
123123
{
124124
if (dest == error_entry)
125125
return true;
@@ -181,7 +181,7 @@ static const u8 nops[] = {
181181
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
182182
};
183183

184-
static __init_or_module void *patch_dest(void *dest, bool direct)
184+
static void *patch_dest(void *dest, bool direct)
185185
{
186186
unsigned int tsize = SKL_TMPL_SIZE;
187187
u8 *pad = dest - tsize;

arch/x86/kernel/kprobes/core.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <linux/extable.h>
3838
#include <linux/kdebug.h>
3939
#include <linux/kallsyms.h>
40+
#include <linux/kgdb.h>
4041
#include <linux/ftrace.h>
4142
#include <linux/kasan.h>
4243
#include <linux/moduleloader.h>
@@ -281,12 +282,15 @@ static int can_probe(unsigned long paddr)
281282
if (ret < 0)
282283
return 0;
283284

285+
#ifdef CONFIG_KGDB
284286
/*
285-
* Another debugging subsystem might insert this breakpoint.
286-
* In that case, we can't recover it.
287+
* If there is a dynamically installed kgdb sw breakpoint,
288+
* this function should not be probed.
287289
*/
288-
if (insn.opcode.bytes[0] == INT3_INSN_OPCODE)
290+
if (insn.opcode.bytes[0] == INT3_INSN_OPCODE &&
291+
kgdb_has_hit_break(addr))
289292
return 0;
293+
#endif
290294
addr += insn.length;
291295
}
292296

arch/x86/kernel/kprobes/opt.c

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/extable.h>
1616
#include <linux/kdebug.h>
1717
#include <linux/kallsyms.h>
18+
#include <linux/kgdb.h>
1819
#include <linux/ftrace.h>
1920
#include <linux/objtool.h>
2021
#include <linux/pgtable.h>
@@ -279,19 +280,6 @@ static int insn_is_indirect_jump(struct insn *insn)
279280
return ret;
280281
}
281282

282-
static bool is_padding_int3(unsigned long addr, unsigned long eaddr)
283-
{
284-
unsigned char ops;
285-
286-
for (; addr < eaddr; addr++) {
287-
if (get_kernel_nofault(ops, (void *)addr) < 0 ||
288-
ops != INT3_INSN_OPCODE)
289-
return false;
290-
}
291-
292-
return true;
293-
}
294-
295283
/* Decode whole function to ensure any instructions don't jump into target */
296284
static int can_optimize(unsigned long paddr)
297285
{
@@ -334,15 +322,15 @@ static int can_optimize(unsigned long paddr)
334322
ret = insn_decode_kernel(&insn, (void *)recovered_insn);
335323
if (ret < 0)
336324
return 0;
337-
325+
#ifdef CONFIG_KGDB
338326
/*
339-
* In the case of detecting unknown breakpoint, this could be
340-
* a padding INT3 between functions. Let's check that all the
341-
* rest of the bytes are also INT3.
327+
* If there is a dynamically installed kgdb sw breakpoint,
328+
* this function should not be probed.
342329
*/
343-
if (insn.opcode.bytes[0] == INT3_INSN_OPCODE)
344-
return is_padding_int3(addr, paddr - offset + size) ? 1 : 0;
345-
330+
if (insn.opcode.bytes[0] == INT3_INSN_OPCODE &&
331+
kgdb_has_hit_break(addr))
332+
return 0;
333+
#endif
346334
/* Recover address */
347335
insn.kaddr = (void *)addr;
348336
insn.next_byte = (void *)(addr + insn.length);

0 commit comments

Comments
 (0)