Commit fe557319 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Linus Torvalds

maccess: rename probe_kernel_{read,write} to copy_{from,to}_kernel_nofault

Better describe what these functions do.
Suggested-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent b3a9e3b9
...@@ -84,7 +84,8 @@ static int ftrace_modify_code(unsigned long pc, unsigned long old, ...@@ -84,7 +84,8 @@ static int ftrace_modify_code(unsigned long pc, unsigned long old,
old = __opcode_to_mem_arm(old); old = __opcode_to_mem_arm(old);
if (validate) { if (validate) {
if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE)) if (copy_from_kernel_nofault(&replaced, (void *)pc,
MCOUNT_INSN_SIZE))
return -EFAULT; return -EFAULT;
if (replaced != old) if (replaced != old)
......
...@@ -236,7 +236,7 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) ...@@ -236,7 +236,7 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
/* patch_text() only supports int-sized breakpoints */ /* patch_text() only supports int-sized breakpoints */
BUILD_BUG_ON(sizeof(int) != BREAK_INSTR_SIZE); BUILD_BUG_ON(sizeof(int) != BREAK_INSTR_SIZE);
err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr, err = copy_from_kernel_nofault(bpt->saved_instr, (char *)bpt->bpt_addr,
BREAK_INSTR_SIZE); BREAK_INSTR_SIZE);
if (err) if (err)
return err; return err;
......
...@@ -135,7 +135,7 @@ int __kprobes aarch64_insn_read(void *addr, u32 *insnp) ...@@ -135,7 +135,7 @@ int __kprobes aarch64_insn_read(void *addr, u32 *insnp)
int ret; int ret;
__le32 val; __le32 val;
ret = probe_kernel_read(&val, addr, AARCH64_INSN_SIZE); ret = copy_from_kernel_nofault(&val, addr, AARCH64_INSN_SIZE);
if (!ret) if (!ret)
*insnp = le32_to_cpu(val); *insnp = le32_to_cpu(val);
...@@ -151,7 +151,7 @@ static int __kprobes __aarch64_insn_write(void *addr, __le32 insn) ...@@ -151,7 +151,7 @@ static int __kprobes __aarch64_insn_write(void *addr, __le32 insn)
raw_spin_lock_irqsave(&patch_lock, flags); raw_spin_lock_irqsave(&patch_lock, flags);
waddr = patch_map(addr, FIX_TEXT_POKE0); waddr = patch_map(addr, FIX_TEXT_POKE0);
ret = probe_kernel_write(waddr, &insn, AARCH64_INSN_SIZE); ret = copy_to_kernel_nofault(waddr, &insn, AARCH64_INSN_SIZE);
patch_unmap(FIX_TEXT_POKE0); patch_unmap(FIX_TEXT_POKE0);
raw_spin_unlock_irqrestore(&patch_lock, flags); raw_spin_unlock_irqrestore(&patch_lock, flags);
......
...@@ -72,7 +72,8 @@ static int ftrace_check_current_nop(unsigned long hook) ...@@ -72,7 +72,8 @@ static int ftrace_check_current_nop(unsigned long hook)
uint16_t olds[7]; uint16_t olds[7];
unsigned long hook_pos = hook - 2; unsigned long hook_pos = hook - 2;
if (probe_kernel_read((void *)olds, (void *)hook_pos, sizeof(nops))) if (copy_from_kernel_nofault((void *)olds, (void *)hook_pos,
sizeof(nops)))
return -EFAULT; return -EFAULT;
if (memcmp((void *)nops, (void *)olds, sizeof(nops))) { if (memcmp((void *)nops, (void *)olds, sizeof(nops))) {
...@@ -97,7 +98,7 @@ static int ftrace_modify_code(unsigned long hook, unsigned long target, ...@@ -97,7 +98,7 @@ static int ftrace_modify_code(unsigned long hook, unsigned long target,
make_jbsr(target, hook, call, nolr); make_jbsr(target, hook, call, nolr);
ret = probe_kernel_write((void *)hook_pos, enable ? call : nops, ret = copy_to_kernel_nofault((void *)hook_pos, enable ? call : nops,
sizeof(nops)); sizeof(nops));
if (ret) if (ret)
return -EPERM; return -EPERM;
......
...@@ -108,7 +108,7 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, ...@@ -108,7 +108,7 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code,
goto skip_check; goto skip_check;
/* read the text we want to modify */ /* read the text we want to modify */
if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE)) if (copy_from_kernel_nofault(replaced, (void *)ip, MCOUNT_INSN_SIZE))
return -EFAULT; return -EFAULT;
/* Make sure it is what we expect it to be */ /* Make sure it is what we expect it to be */
...@@ -117,7 +117,7 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, ...@@ -117,7 +117,7 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code,
skip_check: skip_check:
/* replace the text with the new text */ /* replace the text with the new text */
if (probe_kernel_write(((void *)ip), new_code, MCOUNT_INSN_SIZE)) if (copy_to_kernel_nofault(((void *)ip), new_code, MCOUNT_INSN_SIZE))
return -EPERM; return -EPERM;
flush_icache_range(ip, ip + MCOUNT_INSN_SIZE); flush_icache_range(ip, ip + MCOUNT_INSN_SIZE);
...@@ -129,7 +129,7 @@ static int ftrace_make_nop_check(struct dyn_ftrace *rec, unsigned long addr) ...@@ -129,7 +129,7 @@ static int ftrace_make_nop_check(struct dyn_ftrace *rec, unsigned long addr)
unsigned char __attribute__((aligned(8))) replaced[MCOUNT_INSN_SIZE]; unsigned char __attribute__((aligned(8))) replaced[MCOUNT_INSN_SIZE];
unsigned long ip = rec->ip; unsigned long ip = rec->ip;
if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE)) if (copy_from_kernel_nofault(replaced, (void *)ip, MCOUNT_INSN_SIZE))
return -EFAULT; return -EFAULT;
if (rec->flags & FTRACE_FL_CONVERTED) { if (rec->flags & FTRACE_FL_CONVERTED) {
struct ftrace_call_insn *call_insn, *tmp_call; struct ftrace_call_insn *call_insn, *tmp_call;
......
...@@ -86,9 +86,9 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) ...@@ -86,9 +86,9 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
goto out; goto out;
} }
if ((probe_kernel_read(&prev_insn, p->addr - 1, if (copy_from_kernel_nofault(&prev_insn, p->addr - 1,
sizeof(mips_instruction)) == 0) && sizeof(mips_instruction)) == 0 &&
insn_has_delayslot(prev_insn)) { insn_has_delayslot(prev_insn)) {
pr_notice("Kprobes for branch delayslot are not supported\n"); pr_notice("Kprobes for branch delayslot are not supported\n");
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
......
...@@ -131,13 +131,14 @@ static int __ftrace_modify_code(unsigned long pc, unsigned long *old_insn, ...@@ -131,13 +131,14 @@ static int __ftrace_modify_code(unsigned long pc, unsigned long *old_insn,
unsigned long orig_insn[3]; unsigned long orig_insn[3];
if (validate) { if (validate) {
if (probe_kernel_read(orig_insn, (void *)pc, MCOUNT_INSN_SIZE)) if (copy_from_kernel_nofault(orig_insn, (void *)pc,
MCOUNT_INSN_SIZE))
return -EFAULT; return -EFAULT;
if (memcmp(orig_insn, old_insn, MCOUNT_INSN_SIZE)) if (memcmp(orig_insn, old_insn, MCOUNT_INSN_SIZE))
return -EINVAL; return -EINVAL;
} }
if (probe_kernel_write((void *)pc, new_insn, MCOUNT_INSN_SIZE)) if (copy_to_kernel_nofault((void *)pc, new_insn, MCOUNT_INSN_SIZE))
return -EPERM; return -EPERM;
return 0; return 0;
......
...@@ -172,7 +172,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) ...@@ -172,7 +172,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
ip = (void *)(rec->ip + 4 - size); ip = (void *)(rec->ip + 4 - size);
ret = probe_kernel_read(insn, ip, size); ret = copy_from_kernel_nofault(insn, ip, size);
if (ret) if (ret)
return ret; return ret;
......
...@@ -154,8 +154,8 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip) ...@@ -154,8 +154,8 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip)
int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
{ {
int ret = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr, int ret = copy_from_kernel_nofault(bpt->saved_instr,
BREAK_INSTR_SIZE); (char *)bpt->bpt_addr, BREAK_INSTR_SIZE);
if (ret) if (ret)
return ret; return ret;
......
...@@ -57,7 +57,7 @@ void * memcpy(void * dst,const void *src, size_t count) ...@@ -57,7 +57,7 @@ void * memcpy(void * dst,const void *src, size_t count)
EXPORT_SYMBOL(raw_copy_in_user); EXPORT_SYMBOL(raw_copy_in_user);
EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memcpy);
bool probe_kernel_read_allowed(const void *unsafe_src, size_t size) bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
{ {
if ((unsigned long)unsafe_src < PAGE_SIZE) if ((unsigned long)unsafe_src < PAGE_SIZE)
return false; return false;
......
...@@ -756,7 +756,8 @@ int module_trampoline_target(struct module *mod, unsigned long addr, ...@@ -756,7 +756,8 @@ int module_trampoline_target(struct module *mod, unsigned long addr,
stub = (struct ppc64_stub_entry *)addr; stub = (struct ppc64_stub_entry *)addr;
if (probe_kernel_read(&magic, &stub->magic, sizeof(magic))) { if (copy_from_kernel_nofault(&magic, &stub->magic,
sizeof(magic))) {
pr_err("%s: fault reading magic for stub %lx for %s\n", __func__, addr, mod->name); pr_err("%s: fault reading magic for stub %lx for %s\n", __func__, addr, mod->name);
return -EFAULT; return -EFAULT;
} }
...@@ -766,7 +767,8 @@ int module_trampoline_target(struct module *mod, unsigned long addr, ...@@ -766,7 +767,8 @@ int module_trampoline_target(struct module *mod, unsigned long addr,
return -EFAULT; return -EFAULT;
} }
if (probe_kernel_read(&funcdata, &stub->funcdata, sizeof(funcdata))) { if (copy_from_kernel_nofault(&funcdata, &stub->funcdata,
sizeof(funcdata))) {
pr_err("%s: fault reading funcdata for stub %lx for %s\n", __func__, addr, mod->name); pr_err("%s: fault reading funcdata for stub %lx for %s\n", __func__, addr, mod->name);
return -EFAULT; return -EFAULT;
} }
......
...@@ -226,7 +226,7 @@ __ftrace_make_nop(struct module *mod, ...@@ -226,7 +226,7 @@ __ftrace_make_nop(struct module *mod,
unsigned long ip = rec->ip; unsigned long ip = rec->ip;
unsigned long tramp; unsigned long tramp;
if (probe_kernel_read(&op, (void *)ip, MCOUNT_INSN_SIZE)) if (copy_from_kernel_nofault(&op, (void *)ip, MCOUNT_INSN_SIZE))
return -EFAULT; return -EFAULT;
/* Make sure that that this is still a 24bit jump */ /* Make sure that that this is still a 24bit jump */
...@@ -249,7 +249,7 @@ __ftrace_make_nop(struct module *mod, ...@@ -249,7 +249,7 @@ __ftrace_make_nop(struct module *mod,
pr_devel("ip:%lx jumps to %lx", ip, tramp); pr_devel("ip:%lx jumps to %lx", ip, tramp);
/* Find where the trampoline jumps to */ /* Find where the trampoline jumps to */
if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) { if (copy_from_kernel_nofault(jmp, (void *)tramp, sizeof(jmp))) {
pr_err("Failed to read %lx\n", tramp); pr_err("Failed to read %lx\n", tramp);
return -EFAULT; return -EFAULT;
} }
......
...@@ -33,11 +33,11 @@ int probe_kernel_read_inst(struct ppc_inst *inst, ...@@ -33,11 +33,11 @@ int probe_kernel_read_inst(struct ppc_inst *inst,
unsigned int val, suffix; unsigned int val, suffix;
int err; int err;
err = probe_kernel_read(&val, src, sizeof(val)); err = copy_from_kernel_nofault(&val, src, sizeof(val));
if (err) if (err)
return err; return err;
if (get_op(val) == OP_PREFIX) { if (get_op(val) == OP_PREFIX) {
err = probe_kernel_read(&suffix, (void *)src + 4, 4); err = copy_from_kernel_nofault(&suffix, (void *)src + 4, 4);
*inst = ppc_inst_prefix(val, suffix); *inst = ppc_inst_prefix(val, suffix);
} else { } else {
*inst = ppc_inst(val); *inst = ppc_inst(val);
...@@ -64,7 +64,7 @@ int probe_kernel_read_inst(struct ppc_inst *inst, ...@@ -64,7 +64,7 @@ int probe_kernel_read_inst(struct ppc_inst *inst,
unsigned int val; unsigned int val;
int err; int err;
err = probe_kernel_read(&val, src, sizeof(val)); err = copy_from_kernel_nofault(&val, src, sizeof(val));
if (!err) if (!err)
*inst = ppc_inst(val); *inst = ppc_inst(val);
......
...@@ -418,7 +418,8 @@ static __u64 power_pmu_bhrb_to(u64 addr) ...@@ -418,7 +418,8 @@ static __u64 power_pmu_bhrb_to(u64 addr)
__u64 target; __u64 target;
if (is_kernel_addr(addr)) { if (is_kernel_addr(addr)) {
if (probe_kernel_read(&instr, (void *)addr, sizeof(instr))) if (copy_from_kernel_nofault(&instr, (void *)addr,
sizeof(instr)))
return 0; return 0;
return branch_target((struct ppc_inst *)&instr); return branch_target((struct ppc_inst *)&instr);
......
...@@ -38,7 +38,8 @@ static int ftrace_check_current_call(unsigned long hook_pos, ...@@ -38,7 +38,8 @@ static int ftrace_check_current_call(unsigned long hook_pos,
* Read the text we want to modify; * Read the text we want to modify;
* return must be -EFAULT on read error * return must be -EFAULT on read error
*/ */
if (probe_kernel_read(replaced, (void *)hook_pos, MCOUNT_INSN_SIZE)) if (copy_from_kernel_nofault(replaced, (void *)hook_pos,
MCOUNT_INSN_SIZE))
return -EFAULT; return -EFAULT;
/* /*
......
...@@ -153,7 +153,7 @@ int do_single_step(struct pt_regs *regs) ...@@ -153,7 +153,7 @@ int do_single_step(struct pt_regs *regs)
stepped_address = addr; stepped_address = addr;
/* Replace the op code with the break instruction */ /* Replace the op code with the break instruction */
error = probe_kernel_write((void *)stepped_address, error = copy_to_kernel_nofault((void *)stepped_address,
arch_kgdb_ops.gdb_bpt_instr, arch_kgdb_ops.gdb_bpt_instr,
BREAK_INSTR_SIZE); BREAK_INSTR_SIZE);
/* Flush and return */ /* Flush and return */
...@@ -173,7 +173,7 @@ int do_single_step(struct pt_regs *regs) ...@@ -173,7 +173,7 @@ int do_single_step(struct pt_regs *regs)
static void undo_single_step(struct pt_regs *regs) static void undo_single_step(struct pt_regs *regs)
{ {
if (stepped_opcode != 0) { if (stepped_opcode != 0) {
probe_kernel_write((void *)stepped_address, copy_to_kernel_nofault((void *)stepped_address,
(void *)&stepped_opcode, BREAK_INSTR_SIZE); (void *)&stepped_opcode, BREAK_INSTR_SIZE);
flush_icache_range(stepped_address, flush_icache_range(stepped_address,
stepped_address + BREAK_INSTR_SIZE); stepped_address + BREAK_INSTR_SIZE);
......
...@@ -63,7 +63,7 @@ static int patch_insn_write(void *addr, const void *insn, size_t len) ...@@ -63,7 +63,7 @@ static int patch_insn_write(void *addr, const void *insn, size_t len)
waddr = patch_map(addr, FIX_TEXT_POKE0); waddr = patch_map(addr, FIX_TEXT_POKE0);
ret = probe_kernel_write(waddr, insn, len); ret = copy_to_kernel_nofault(waddr, insn, len);
patch_unmap(FIX_TEXT_POKE0); patch_unmap(FIX_TEXT_POKE0);
...@@ -76,7 +76,7 @@ NOKPROBE_SYMBOL(patch_insn_write); ...@@ -76,7 +76,7 @@ NOKPROBE_SYMBOL(patch_insn_write);
#else #else
static int patch_insn_write(void *addr, const void *insn, size_t len) static int patch_insn_write(void *addr, const void *insn, size_t len)
{ {
return probe_kernel_write(addr, insn, len); return copy_to_kernel_nofault(addr, insn, len);
} }
NOKPROBE_SYMBOL(patch_insn_write); NOKPROBE_SYMBOL(patch_insn_write);
#endif /* CONFIG_MMU */ #endif /* CONFIG_MMU */
......
...@@ -83,7 +83,7 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, ...@@ -83,7 +83,7 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
{ {
struct ftrace_insn orig, new, old; struct ftrace_insn orig, new, old;
if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old))) if (copy_from_kernel_nofault(&old, (void *) rec->ip, sizeof(old)))
return -EFAULT; return -EFAULT;
if (addr == MCOUNT_ADDR) { if (addr == MCOUNT_ADDR) {
/* Initial code replacement */ /* Initial code replacement */
...@@ -105,7 +105,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) ...@@ -105,7 +105,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
{ {
struct ftrace_insn orig, new, old; struct ftrace_insn orig, new, old;
if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old))) if (copy_from_kernel_nofault(&old, (void *) rec->ip, sizeof(old)))
return -EFAULT; return -EFAULT;
/* Replace nop with an ftrace call. */ /* Replace nop with an ftrace call. */
ftrace_generate_nop_insn(&orig); ftrace_generate_nop_insn(&orig);
......
...@@ -119,7 +119,7 @@ static void ftrace_mod_code(void) ...@@ -119,7 +119,7 @@ static void ftrace_mod_code(void)
* But if one were to fail, then they all should, and if one were * But if one were to fail, then they all should, and if one were
* to succeed, then they all should. * to succeed, then they all should.
*/ */
mod_code_status = probe_kernel_write(mod_code_ip, mod_code_newcode, mod_code_status = copy_to_kernel_nofault(mod_code_ip, mod_code_newcode,
MCOUNT_INSN_SIZE); MCOUNT_INSN_SIZE);
/* if we fail, then kill any new writers */ /* if we fail, then kill any new writers */
...@@ -203,7 +203,7 @@ static int ftrace_modify_code(unsigned long ip, unsigned char *old_code, ...@@ -203,7 +203,7 @@ static int ftrace_modify_code(unsigned long ip, unsigned char *old_code,
*/ */
/* read the text we want to modify */ /* read the text we want to modify */
if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE)) if (copy_from_kernel_nofault(replaced, (void *)ip, MCOUNT_INSN_SIZE))
return -EFAULT; return -EFAULT;
/* Make sure it is what we expect it to be */ /* Make sure it is what we expect it to be */
...@@ -268,7 +268,7 @@ static int ftrace_mod(unsigned long ip, unsigned long old_addr, ...@@ -268,7 +268,7 @@ static int ftrace_mod(unsigned long ip, unsigned long old_addr,
{ {
unsigned char code[MCOUNT_INSN_SIZE]; unsigned char code[MCOUNT_INSN_SIZE];
if (probe_kernel_read(code, (void *)ip, MCOUNT_INSN_SIZE)) if (copy_from_kernel_nofault(code, (void *)ip, MCOUNT_INSN_SIZE))
return -EFAULT; return -EFAULT;
if (old_addr != __raw_readl((unsigned long *)code)) if (old_addr != __raw_readl((unsigned long *)code))
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <os.h> #include <os.h>
bool probe_kernel_read_allowed(const void *src, size_t size) bool copy_from_kernel_nofault_allowed(const void *src, size_t size)
{ {
void *psrc = (void *)rounddown((unsigned long)src, PAGE_SIZE); void *psrc = (void *)rounddown((unsigned long)src, PAGE_SIZE);
......
...@@ -278,7 +278,7 @@ static inline unsigned long *regs_get_kernel_stack_nth_addr(struct pt_regs *regs ...@@ -278,7 +278,7 @@ static inline unsigned long *regs_get_kernel_stack_nth_addr(struct pt_regs *regs
} }
/* To avoid include hell, we can't include uaccess.h */ /* To avoid include hell, we can't include uaccess.h */
extern long probe_kernel_read(void *dst, const void *src, size_t size); extern long copy_from_kernel_nofault(void *dst, const void *src, size_t size);
/** /**
* regs_get_kernel_stack_nth() - get Nth entry of the stack * regs_get_kernel_stack_nth() - get Nth entry of the stack
...@@ -298,7 +298,7 @@ static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, ...@@ -298,7 +298,7 @@ static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
addr = regs_get_kernel_stack_nth_addr(regs, n); addr = regs_get_kernel_stack_nth_addr(regs, n);
if (addr) { if (addr) {
ret = probe_kernel_read(&val, addr, sizeof(val)); ret = copy_from_kernel_nofault(&val, addr, sizeof(val));
if (!ret) if (!ret)
return val; return val;
} }
......
...@@ -106,7 +106,7 @@ void show_opcodes(struct pt_regs *regs, const char *loglvl) ...@@ -106,7 +106,7 @@ void show_opcodes(struct pt_regs *regs, const char *loglvl)
bad_ip = user_mode(regs) && bad_ip = user_mode(regs) &&
__chk_range_not_ok(prologue, OPCODE_BUFSIZE, TASK_SIZE_MAX); __chk_range_not_ok(prologue, OPCODE_BUFSIZE, TASK_SIZE_MAX);
if (bad_ip || probe_kernel_read(opcodes, (u8 *)prologue, if (bad_ip || copy_from_kernel_nofault(opcodes, (u8 *)prologue,
OPCODE_BUFSIZE)) { OPCODE_BUFSIZE)) {
printk("%sCode: Bad RIP value.\n", loglvl); printk("%sCode: Bad RIP value.\n", loglvl);
} else { } else {
......
...@@ -86,7 +86,7 @@ static int ftrace_verify_code(unsigned long ip, const char *old_code) ...@@ -86,7 +86,7 @@ static int ftrace_verify_code(unsigned long ip, const char *old_code)
* sure what we read is what we expected it to be before modifying it. * sure what we read is what we expected it to be before modifying it.
*/ */
/* read the text we want to modify */ /* read the text we want to modify */
if (probe_kernel_read(cur_code, (void *)ip, MCOUNT_INSN_SIZE)) { if (copy_from_kernel_nofault(cur_code, (void *)ip, MCOUNT_INSN_SIZE)) {
WARN_ON(1); WARN_ON(1);
return -EFAULT; return -EFAULT;
} }
...@@ -355,7 +355,7 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) ...@@ -355,7 +355,7 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size)
npages = DIV_ROUND_UP(*tramp_size, PAGE_SIZE); npages = DIV_ROUND_UP(*tramp_size, PAGE_SIZE);
/* Copy ftrace_caller onto the trampoline memory */ /* Copy ftrace_caller onto the trampoline memory */
ret = probe_kernel_read(trampoline, (void *)start_offset, size); ret = copy_from_kernel_nofault(trampoline, (void *)start_offset, size);
if (WARN_ON(ret < 0)) if (WARN_ON(ret < 0))
goto fail; goto fail;
...@@ -363,13 +363,13 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) ...@@ -363,13 +363,13 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size)
/* The trampoline ends with ret(q) */ /* The trampoline ends with ret(q) */
retq = (unsigned long)ftrace_stub; retq = (unsigned long)ftrace_stub;
ret = probe_kernel_read(ip, (void *)retq, RET_SIZE); ret = copy_from_kernel_nofault(ip, (void *)retq, RET_SIZE);
if (WARN_ON(ret < 0)) if (WARN_ON(ret < 0))
goto fail; goto fail;
if (ops->flags & FTRACE_OPS_FL_SAVE_REGS) { if (ops->flags & FTRACE_OPS_FL_SAVE_REGS) {
ip = trampoline + (ftrace_regs_caller_ret - ftrace_regs_caller); ip = trampoline + (ftrace_regs_caller_ret - ftrace_regs_caller);
ret = probe_kernel_read(ip, (void *)retq, RET_SIZE); ret = copy_from_kernel_nofault(ip, (void *)retq, RET_SIZE);
if (WARN_ON(ret < 0)) if (WARN_ON(ret < 0))
goto fail; goto fail;
} }
...@@ -506,7 +506,7 @@ static void *addr_from_call(void *ptr) ...@@ -506,7 +506,7 @@ static void *addr_from_call(void *ptr)
union text_poke_insn call; union text_poke_insn call;
int ret; int ret;
ret = probe_kernel_read(&call, ptr, CALL_INSN_SIZE); ret = copy_from_kernel_nofault(&call, ptr, CALL_INSN_SIZE);
if (WARN_ON_ONCE(ret < 0)) if (WARN_ON_ONCE(ret < 0))
return NULL; return NULL;
......
...@@ -732,11 +732,11 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) ...@@ -732,11 +732,11 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
int err; int err;
bpt->type = BP_BREAKPOINT; bpt->type = BP_BREAKPOINT;
err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr, err = copy_from_kernel_nofault(bpt->saved_instr, (char *)bpt->bpt_addr,
BREAK_INSTR_SIZE); BREAK_INSTR_SIZE);
if (err) if (err)
return err; return err;
err = probe_kernel_write((char *)bpt->bpt_addr, err = copy_to_kernel_nofault((char *)bpt->bpt_addr,
arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE); arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE);
if (!err) if (!err)
return err; return err;
...@@ -768,7 +768,7 @@ int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) ...@@ -768,7 +768,7 @@ int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
return 0; return 0;
knl_write: knl_write:
return probe_kernel_write((char *)bpt->bpt_addr, return copy_to_kernel_nofault((char *)bpt->bpt_addr,
(char *)bpt->saved_instr, BREAK_INSTR_SIZE); (char *)bpt->saved_instr, BREAK_INSTR_SIZE);
} }
......
...@@ -243,7 +243,7 @@ __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr) ...@@ -243,7 +243,7 @@ __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr)
* Fortunately, we know that the original code is the ideal 5-byte * Fortunately, we know that the original code is the ideal 5-byte
* long NOP. * long NOP.
*/ */
if (probe_kernel_read(buf, (void *)addr, if (copy_from_kernel_nofault(buf, (void *)addr,
MAX_INSN_SIZE * sizeof(kprobe_opcode_t))) MAX_INSN_SIZE * sizeof(kprobe_opcode_t)))
return 0UL; return 0UL;
...@@ -346,7 +346,8 @@ int __copy_instruction(u8 *dest, u8 *src, u8 *real, struct insn *insn) ...@@ -346,7 +346,8 @@ int __copy_instruction(u8 *dest, u8 *src, u8 *real, struct insn *insn)
return 0; return 0;
/* This can access kernel text if given address is not recovered */ /* This can access kernel text if given address is not recovered */
if (probe_kernel_read(dest, (void *)recovered_insn, MAX_INSN_SIZE)) if (copy_from_kernel_nofault(dest, (void *)recovered_insn,
MAX_INSN_SIZE))
return 0; return 0;
kernel_insn_init(insn, dest, MAX_INSN_SIZE); kernel_insn_init(insn, dest, MAX_INSN_SIZE);
......
...@@ -56,7 +56,7 @@ unsigned long __recover_optprobed_insn(kprobe_opcode_t *buf, unsigned long addr) ...@@ -56,7 +56,7 @@ unsigned long __recover_optprobed_insn(kprobe_opcode_t *buf, unsigned long addr)
* overwritten by jump destination address. In this case, original * overwritten by jump destination address. In this case, original
* bytes must be recovered from op->optinsn.copied_insn buffer. * bytes must be recovered from op->optinsn.copied_insn buffer.
*/ */
if (probe_kernel_read(buf, (void *)addr, if (copy_from_kernel_nofault(buf, (void *)addr,
MAX_INSN_SIZE * sizeof(kprobe_opcode_t))) MAX_INSN_SIZE * sizeof(kprobe_opcode_t)))
return 0UL; return 0UL;
......
...@@ -488,7 +488,8 @@ static enum kernel_gp_hint get_kernel_gp_address(struct pt_regs *regs, ...@@ -488,7 +488,8 @@ static enum kernel_gp_hint get_kernel_gp_address(struct pt_regs *regs,
u8 insn_buf[MAX_INSN_SIZE]; u8 insn_buf[MAX_INSN_SIZE];
struct insn insn; struct insn insn;
if (probe_kernel_read(insn_buf, (void *)regs->ip, MAX_INSN_SIZE)) if (copy_from_kernel_nofault(insn_buf, (void *)regs->ip,
MAX_INSN_SIZE))
return GP_NO_HINT; return GP_NO_HINT;
kernel_insn_init(&insn, insn_buf, MAX_INSN_SIZE); kernel_insn_init(&insn, insn_buf, MAX_INSN_SIZE);
......
...@@ -442,7 +442,7 @@ static void show_ldttss(const struct desc_ptr *gdt, const char *name, u16 index) ...@@ -442,7 +442,7 @@ static void show_ldttss(const struct desc_ptr *gdt, const char *name, u16 index)
return; return;
} }
if (probe_kernel_read(&desc, (void *)(gdt->address + offset), if (copy_from_kernel_nofault(&desc, (void *)(gdt->address + offset),
sizeof(struct ldttss_desc))) { sizeof(struct ldttss_desc))) {
pr_alert("%s: 0x%hx -- GDT entry is not readable\n", pr_alert("%s: 0x%hx -- GDT entry is not readable\n",
name, index); name, index);
......
...@@ -737,7 +737,7 @@ static void __init test_wp_bit(void) ...@@ -737,7 +737,7 @@ static void __init test_wp_bit(void)
__set_fixmap(FIX_WP_TEST, __pa_symbol(empty_zero_page), PAGE_KERNEL_RO); __set_fixmap(FIX_WP_TEST, __pa_symbol(empty_zero_page), PAGE_KERNEL_RO);
if (probe_kernel_write((char *)fix_to_virt(FIX_WP_TEST), &z, 1)) { if (copy_to_kernel_nofault((char *)fix_to_virt(FIX_WP_TEST), &z, 1)) {
clear_fixmap(FIX_WP_TEST); clear_fixmap(FIX_WP_TEST);
printk(KERN_CONT "Ok.\n"); printk(KERN_CONT "Ok.\n");
return; return;
......
...@@ -9,7 +9,7 @@ static __always_inline u64 canonical_address(u64 vaddr, u8 vaddr_bits) ...@@ -9,7 +9,7 @@ static __always_inline u64 canonical_address(u64 vaddr, u8 vaddr_bits)
return ((s64)vaddr << (64 - vaddr_bits)) >> (64 - vaddr_bits); return ((s64)vaddr << (64 - vaddr_bits)) >> (64 - vaddr_bits);
} }
bool probe_kernel_read_allowed(const void *unsafe_src, size_t size) bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
{ {
unsigned long vaddr = (unsigned long)unsafe_src; unsigned long vaddr = (unsigned long)unsafe_src;
...@@ -22,7 +22,7 @@ bool probe_kernel_read_allowed(const void *unsafe_src, size_t size) ...@@ -22,7 +22,7 @@ bool probe_kernel_read_allowed(const void *unsafe_src, size_t size)
canonical_address(vaddr, boot_cpu_data.x86_virt_bits) == vaddr; canonical_address(vaddr, boot_cpu_data.x86_virt_bits) == vaddr;
} }
#else #else
bool probe_kernel_read_allowed(const void *unsafe_src, size_t size) bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
{ {
return (unsigned long)unsafe_src >= TASK_SIZE_MAX; return (unsigned long)unsafe_src >= TASK_SIZE_MAX;
} }
......
...@@ -386,7 +386,7 @@ static void set_aliased_prot(void *v, pgprot_t prot) ...@@ -386,7 +386,7 @@ static void set_aliased_prot(void *v, pgprot_t prot)
preempt_disable(); preempt_disable();
probe_kernel_read(&dummy, v, 1); copy_from_kernel_nofault(&dummy, v, 1);
if (HYPERVISOR_update_va_mapping((unsigned long)v, pte, 0)) if (HYPERVISOR_update_va_mapping((unsigned long)v, pte, 0))
BUG(); BUG();
......
...@@ -171,7 +171,7 @@ static ssize_t read_mem(struct file *file, char __user *buf, ...@@ -171,7 +171,7 @@ static ssize_t read_mem(struct file *file, char __user *buf,
if (!ptr) if (!ptr)
goto failed; goto failed;
probe = probe_kernel_read(bounce, ptr, sz); probe = copy_from_kernel_nofault(bounce, ptr, sz);
unxlate_dev_mem_ptr(p, ptr); unxlate_dev_mem_ptr(p, ptr);
if (probe) if (probe)
goto failed; goto failed;
......
...@@ -135,7 +135,8 @@ int __init dio_find(int deviceid) ...@@ -135,7 +135,8 @@ int __init dio_find(int deviceid)
else else
va = ioremap(pa, PAGE_SIZE); va = ioremap(pa, PAGE_SIZE);
if (probe_kernel_read(&i, (unsigned char *)va + DIO_IDOFF, 1)) { if (copy_from_kernel_nofault(&i,
(unsigned char *)va + DIO_IDOFF, 1)) {
if (scode >= DIOII_SCBASE) if (scode >= DIOII_SCBASE)
iounmap(va); iounmap(va);
continue; /* no board present at that select code */ continue; /* no board present at that select code */
...@@ -208,7 +209,8 @@ static int __init dio_init(void) ...@@ -208,7 +209,8 @@ static int __init dio_init(void)
else else
va = ioremap(pa, PAGE_SIZE); va = ioremap(pa, PAGE_SIZE);
if (probe_kernel_read(&i, (unsigned char *)va + DIO_IDOFF, 1)) { if (copy_from_kernel_nofault(&i,
(unsigned char *)va + DIO_IDOFF, 1)) {
if (scode >= DIOII_SCBASE) if (scode >= DIOII_SCBASE)
iounmap(va); iounmap(va);
continue; /* no board present at that select code */ continue; /* no board present at that select code */
......
...@@ -1021,7 +1021,7 @@ static int __init hp_sdc_register(void) ...@@ -1021,7 +1021,7 @@ static int __init hp_sdc_register(void)
hp_sdc.base_io = (unsigned long) 0xf0428000; hp_sdc.base_io = (unsigned long) 0xf0428000;
hp_sdc.data_io = (unsigned long) hp_sdc.base_io + 1; hp_sdc.data_io = (unsigned long) hp_sdc.base_io + 1;
hp_sdc.status_io = (unsigned long) hp_sdc.base_io + 3; hp_sdc.status_io = (unsigned long) hp_sdc.base_io + 3;
if (!probe_kernel_read(&i, (unsigned char *)hp_sdc.data_io, 1)) if (!copy_from_kernel_nofault(&i, (unsigned char *)hp_sdc.data_io, 1))
hp_sdc.dev = (void *)1; hp_sdc.dev = (void *)1;
hp_sdc.dev_err = hp_sdc_init(); hp_sdc.dev_err = hp_sdc_init();
#endif #endif
......
...@@ -828,7 +828,7 @@ static void run_plant_and_detach_test(int is_early) ...@@ -828,7 +828,7 @@ static void run_plant_and_detach_test(int is_early)
char before[BREAK_INSTR_SIZE]; char before[BREAK_INSTR_SIZE];
char after[BREAK_INSTR_SIZE]; char after[BREAK_INSTR_SIZE];
probe_kernel_read(before, (char *)kgdbts_break_test, copy_from_kernel_nofault(before, (char *)kgdbts_break_test,
BREAK_INSTR_SIZE); BREAK_INSTR_SIZE);
init_simple_test(); init_simple_test();
ts.tst = plant_and_detach_test; ts.tst = plant_and_detach_test;
...@@ -836,8 +836,8 @@ static void run_plant_and_detach_test(int is_early) ...@@ -836,8 +836,8 @@ static void run_plant_and_detach_test(int is_early)
/* Activate test with initial breakpoint */ /* Activate test with initial breakpoint */
if (!is_early) if (!is_early)
kgdb_breakpoint(); kgdb_breakpoint();
probe_kernel_read(after, (char *)kgdbts_break_test, copy_from_kernel_nofault(after, (char *)kgdbts_break_test,
BREAK_INSTR_SIZE); BREAK_INSTR_SIZE);
if (memcmp(before, after, BREAK_INSTR_SIZE)) { if (memcmp(before, after, BREAK_INSTR_SIZE)) {
printk(KERN_CRIT "kgdbts: ERROR kgdb corrupted memory\n"); printk(KERN_CRIT "kgdbts: ERROR kgdb corrupted memory\n");
panic("kgdb memory corruption"); panic("kgdb memory corruption");
......
...@@ -402,7 +402,7 @@ int __init hpfb_init(void) ...@@ -402,7 +402,7 @@ int __init hpfb_init(void)
if (err) if (err)
return err; return err;
err = probe_kernel_read(&i, (unsigned char *)INTFBVADDR + DIO_IDOFF, 1); err = copy_from_kernel_nofault(&i, (unsigned char *)INTFBVADDR + DIO_IDOFF, 1);
if (!err && (i == DIO_ID_FBUFFER) && topcat_sid_ok(sid = DIO_SECID(INTFBVADDR))) { if (!err && (i == DIO_ID_FBUFFER) && topcat_sid_ok(sid = DIO_SECID(INTFBVADDR))) {
if (!request_mem_region(INTFBPADDR, DIO_DEVSIZE, "Internal Topcat")) if (!request_mem_region(INTFBPADDR, DIO_DEVSIZE, "Internal Topcat"))
......
...@@ -512,7 +512,8 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) ...@@ -512,7 +512,8 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
* Using bounce buffer to bypass the * Using bounce buffer to bypass the
* hardened user copy kernel text checks. * hardened user copy kernel text checks.
*/ */
if (probe_kernel_read(buf, (void *) start, tsz)) { if (copy_from_kernel_nofault(buf, (void *)start,
tsz)) {
if (clear_user(buffer, tsz)) { if (clear_user(buffer, tsz)) {
ret = -EFAULT; ret = -EFAULT;
goto out; goto out;
......
...@@ -301,13 +301,14 @@ copy_struct_from_user(void *dst, size_t ksize, const void __user *src, ...@@ -301,13 +301,14 @@ copy_struct_from_user(void *dst, size_t ksize, const void __user *src,
return 0; return 0;
} }
bool probe_kernel_read_allowed(const void *unsafe_src, size_t size); bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size);
extern long probe_kernel_read(void *dst, const void *src, size_t size); long copy_from_kernel_nofault(void *dst, const void *src, size_t size);
extern long probe_user_read(void *dst, const void __user *src, size_t size); long notrace copy_to_kernel_nofault(void *dst, const void *src, size_t size);
extern long notrace probe_kernel_write(void *dst, const void *src, size_t size); extern long probe_user_read(void *dst, const void __user *src, size_t size);
extern long notrace probe_user_write(void __user *dst, const void *src, size_t size); extern long notrace probe_user_write(void __user *dst, const void *src,
size_t size);
long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr,
long count); long count);
...@@ -324,7 +325,7 @@ long strnlen_user_nofault(const void __user *unsafe_addr, long count); ...@@ -324,7 +325,7 @@ long strnlen_user_nofault(const void __user *unsafe_addr, long count);
* Returns 0 on success, or -EFAULT. * Returns 0 on success, or -EFAULT.
*/ */
#define probe_kernel_address(addr, retval) \ #define probe_kernel_address(addr, retval) \
probe_kernel_read(&retval, addr, sizeof(retval)) copy_from_kernel_nofault(&retval, addr, sizeof(retval))
#ifndef user_access_begin #ifndef user_access_begin
#define user_access_begin(ptr,len) access_ok(ptr, len) #define user_access_begin(ptr,len) access_ok(ptr, len)
......
...@@ -169,18 +169,18 @@ int __weak kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) ...@@ -169,18 +169,18 @@ int __weak kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
{ {
int err; int err;
err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr, err = copy_from_kernel_nofault(bpt->saved_instr, (char *)bpt->bpt_addr,
BREAK_INSTR_SIZE); BREAK_INSTR_SIZE);
if (err) if (err)
return err; return err;
err = probe_kernel_write((char *)bpt->bpt_addr, err = copy_to_kernel_nofault((char *)bpt->bpt_addr,
arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE); arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE);
return err; return err;
} }
int __weak kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) int __weak kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
{ {
return probe_kernel_write((char *)bpt->bpt_addr, return copy_to_kernel_nofault((char *)bpt->bpt_addr,
(char *)bpt->saved_instr, BREAK_INSTR_SIZE); (char *)bpt->saved_instr, BREAK_INSTR_SIZE);
} }
......
...@@ -247,7 +247,7 @@ char *kgdb_mem2hex(char *mem, char *buf, int count) ...@@ -247,7 +247,7 @@ char *kgdb_mem2hex(char *mem, char *buf, int count)
*/ */
tmp = buf + count; tmp = buf + count;
err = probe_kernel_read(tmp, mem, count); err = copy_from_kernel_nofault(tmp, mem, count);
if (err) if (err)
return NULL; return NULL;
while (count > 0) { while (count > 0) {
...@@ -283,7 +283,7 @@ int kgdb_hex2mem(char *buf, char *mem, int count) ...@@ -283,7 +283,7 @@ int kgdb_hex2mem(char *buf, char *mem, int count)
*tmp_raw |= hex_to_bin(*tmp_hex--) << 4; *tmp_raw |= hex_to_bin(*tmp_hex--) << 4;
} }
return probe_kernel_write(mem, tmp_raw, count); return copy_to_kernel_nofault(mem, tmp_raw, count);
} }
/* /*
...@@ -335,7 +335,7 @@ static int kgdb_ebin2mem(char *buf, char *mem, int count) ...@@ -335,7 +335,7 @@ static int kgdb_ebin2mem(char *buf, char *mem, int count)
size++; size++;
} }
return probe_kernel_write(mem, c, size); return copy_to_kernel_nofault(mem, c, size);
} }
#if DBG_MAX_REG_NUM > 0 #if DBG_MAX_REG_NUM > 0
......
...@@ -2326,7 +2326,8 @@ void kdb_ps1(const struct task_struct *p) ...@@ -2326,7 +2326,8 @@ void kdb_ps1(const struct task_struct *p)
int cpu; int cpu;
unsigned long tmp; unsigned long tmp;
if (!p || probe_kernel_read(&tmp, (char *)p, sizeof(unsigned long))) if (!p ||
copy_from_kernel_nofault(&tmp, (char *)p, sizeof(unsigned long)))
return; return;
cpu = kdb_process_cpu(p); cpu = kdb_process_cpu(p);
......
...@@ -325,7 +325,7 @@ char *kdb_strdup(const char *str, gfp_t type) ...@@ -325,7 +325,7 @@ char *kdb_strdup(const char *str, gfp_t type)
*/ */
int kdb_getarea_size(void *res, unsigned long addr, size_t size) int kdb_getarea_size(void *res, unsigned long addr, size_t size)
{ {
int ret = probe_kernel_read((char *)res, (char *)addr, size); int ret = copy_from_kernel_nofault((char *)res, (char *)addr, size);
if (ret) { if (ret) {
if (!KDB_STATE(SUPPRESS)) { if (!KDB_STATE(SUPPRESS)) {
kdb_printf("kdb_getarea: Bad address 0x%lx\n", addr); kdb_printf("kdb_getarea: Bad address 0x%lx\n", addr);
...@@ -350,7 +350,7 @@ int kdb_getarea_size(void *res, unsigned long addr, size_t size) ...@@ -350,7 +350,7 @@ int kdb_getarea_size(void *res, unsigned long addr, size_t size)
*/ */
int kdb_putarea_size(unsigned long addr, void *res, size_t size) int kdb_putarea_size(unsigned long addr, void *res, size_t size)
{ {
int ret = probe_kernel_read((char *)addr, (char *)res, size); int ret = copy_from_kernel_nofault((char *)addr, (char *)res, size);
if (ret) { if (ret) {
if (!KDB_STATE(SUPPRESS)) { if (!KDB_STATE(SUPPRESS)) {
kdb_printf("kdb_putarea: Bad address 0x%lx\n", addr); kdb_printf("kdb_putarea: Bad address 0x%lx\n", addr);
...@@ -624,7 +624,8 @@ char kdb_task_state_char (const struct task_struct *p) ...@@ -624,7 +624,8 @@ char kdb_task_state_char (const struct task_struct *p)
char state; char state;
unsigned long tmp; unsigned long tmp;
if (!p || probe_kernel_read(&tmp, (char *)p, sizeof(unsigned long))) if (!p ||
copy_from_kernel_nofault(&tmp, (char *)p, sizeof(unsigned long)))
return 'E'; return 'E';
cpu = kdb_process_cpu(p); cpu = kdb_process_cpu(p);
......
...@@ -201,7 +201,7 @@ void *kthread_probe_data(struct task_struct *task) ...@@ -201,7 +201,7 @@ void *kthread_probe_data(struct task_struct *task)
struct kthread *kthread = to_kthread(task); struct kthread *kthread = to_kthread(task);
void *data = NULL; void *data = NULL;
probe_kernel_read(&data, &kthread->data, sizeof(data)); copy_from_kernel_nofault(&data, &kthread->data, sizeof(data));
return data; return data;
} }
......
...@@ -196,7 +196,7 @@ bpf_probe_read_kernel_common(void *dst, u32 size, const void *unsafe_ptr) ...@@ -196,7 +196,7 @@ bpf_probe_read_kernel_common(void *dst, u32 size, const void *unsafe_ptr)
if (unlikely(ret < 0)) if (unlikely(ret < 0))
goto fail; goto fail;
ret = probe_kernel_read(dst, unsafe_ptr, size); ret = copy_from_kernel_nofault(dst, unsafe_ptr, size);
if (unlikely(ret < 0)) if (unlikely(ret < 0))
goto fail; goto fail;
return ret; return ret;
...@@ -661,7 +661,7 @@ BPF_CALL_5(bpf_seq_printf, struct seq_file *, m, char *, fmt, u32, fmt_size, ...@@ -661,7 +661,7 @@ BPF_CALL_5(bpf_seq_printf, struct seq_file *, m, char *, fmt, u32, fmt_size,
copy_size = (fmt[i + 2] == '4') ? 4 : 16; copy_size = (fmt[i + 2] == '4') ? 4 : 16;
err = probe_kernel_read(bufs->buf[memcpy_cnt], err = copy_from_kernel_nofault(bufs->buf[memcpy_cnt],
(void *) (long) args[fmt_cnt], (void *) (long) args[fmt_cnt],
copy_size); copy_size);
if (err < 0) if (err < 0)
......
...@@ -1222,7 +1222,7 @@ fetch_store_strlen(unsigned long addr) ...@@ -1222,7 +1222,7 @@ fetch_store_strlen(unsigned long addr)
#endif #endif
do { do {
ret = probe_kernel_read(&c, (u8 *)addr + len, 1); ret = copy_from_kernel_nofault(&c, (u8 *)addr + len, 1);
len++; len++;
} while (c && ret == 0 && len < MAX_STRING_SIZE); } while (c && ret == 0 && len < MAX_STRING_SIZE);
...@@ -1300,7 +1300,7 @@ probe_mem_read(void *dest, void *src, size_t size) ...@@ -1300,7 +1300,7 @@ probe_mem_read(void *dest, void *src, size_t size)
if ((unsigned long)src < TASK_SIZE) if ((unsigned long)src < TASK_SIZE)
return probe_mem_read_user(dest, src, size); return probe_mem_read_user(dest, src, size);
#endif #endif
return probe_kernel_read(dest, src, size); return copy_from_kernel_nofault(dest, src, size);
} }
/* Note that we don't verify it, since the code does not come from user space */ /* Note that we don't verify it, since the code does not come from user space */
......
...@@ -4638,11 +4638,11 @@ void print_worker_info(const char *log_lvl, struct task_struct *task) ...@@ -4638,11 +4638,11 @@ void print_worker_info(const char *log_lvl, struct task_struct *task)
* Carefully copy the associated workqueue's workfn, name and desc. * Carefully copy the associated workqueue's workfn, name and desc.
* Keep the original last '\0' in case the original is garbage. * Keep the original last '\0' in case the original is garbage.
*/ */
probe_kernel_read(&fn, &worker->current_func, sizeof(fn)); copy_from_kernel_nofault(&fn, &worker->current_func, sizeof(fn));
probe_kernel_read(&pwq, &worker->current_pwq, sizeof(pwq)); copy_from_kernel_nofault(&pwq, &worker->current_pwq, sizeof(pwq));
probe_kernel_read(&wq, &pwq->wq, sizeof(wq)); copy_from_kernel_nofault(&wq, &pwq->wq, sizeof(wq));
probe_kernel_read(name, wq->name, sizeof(name) - 1); copy_from_kernel_nofault(name, wq->name, sizeof(name) - 1);
probe_kernel_read(desc, worker->desc, sizeof(desc) - 1); copy_from_kernel_nofault(desc, worker->desc, sizeof(desc) - 1);
if (fn || name[0] || desc[0]) { if (fn || name[0] || desc[0]) {
printk("%sWorkqueue: %s %ps", log_lvl, name, fn); printk("%sWorkqueue: %s %ps", log_lvl, name, fn);
......
...@@ -120,9 +120,9 @@ void __dump_page(struct page *page, const char *reason) ...@@ -120,9 +120,9 @@ void __dump_page(struct page *page, const char *reason)
* mapping can be invalid pointer and we don't want to crash * mapping can be invalid pointer and we don't want to crash
* accessing it, so probe everything depending on it carefully * accessing it, so probe everything depending on it carefully
*/ */
if (probe_kernel_read(&host, &mapping->host, if (copy_from_kernel_nofault(&host, &mapping->host,
sizeof(struct inode *)) || sizeof(struct inode *)) ||
probe_kernel_read(&a_ops, &mapping->a_ops, copy_from_kernel_nofault(&a_ops, &mapping->a_ops,
sizeof(struct address_space_operations *))) { sizeof(struct address_space_operations *))) {
pr_warn("failed to read mapping->host or a_ops, mapping not a valid kernel address?\n"); pr_warn("failed to read mapping->host or a_ops, mapping not a valid kernel address?\n");
goto out_mapping; goto out_mapping;
...@@ -133,7 +133,7 @@ void __dump_page(struct page *page, const char *reason) ...@@ -133,7 +133,7 @@ void __dump_page(struct page *page, const char *reason)
goto out_mapping; goto out_mapping;
} }
if (probe_kernel_read(&dentry_first, if (copy_from_kernel_nofault(&dentry_first,
&host->i_dentry.first, sizeof(struct hlist_node *))) { &host->i_dentry.first, sizeof(struct hlist_node *))) {
pr_warn("mapping->a_ops:%ps with invalid mapping->host inode address %px\n", pr_warn("mapping->a_ops:%ps with invalid mapping->host inode address %px\n",
a_ops, host); a_ops, host);
...@@ -146,7 +146,7 @@ void __dump_page(struct page *page, const char *reason) ...@@ -146,7 +146,7 @@ void __dump_page(struct page *page, const char *reason)
} }
dentry_ptr = container_of(dentry_first, struct dentry, d_u.d_alias); dentry_ptr = container_of(dentry_first, struct dentry, d_u.d_alias);
if (probe_kernel_read(&dentry, dentry_ptr, if (copy_from_kernel_nofault(&dentry, dentry_ptr,
sizeof(struct dentry))) { sizeof(struct dentry))) {
pr_warn("mapping->aops:%ps with invalid mapping->host->i_dentry.first %px\n", pr_warn("mapping->aops:%ps with invalid mapping->host->i_dentry.first %px\n",
a_ops, dentry_ptr); a_ops, dentry_ptr);
......
...@@ -6,14 +6,15 @@ ...@@ -6,14 +6,15 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
bool __weak probe_kernel_read_allowed(const void *unsafe_src, size_t size) bool __weak copy_from_kernel_nofault_allowed(const void *unsafe_src,
size_t size)
{ {
return true; return true;
} }
#ifdef HAVE_GET_KERNEL_NOFAULT #ifdef HAVE_GET_KERNEL_NOFAULT
#define probe_kernel_read_loop(dst, src, len, type, err_label) \ #define copy_from_kernel_nofault_loop(dst, src, len, type, err_label) \
while (len >= sizeof(type)) { \ while (len >= sizeof(type)) { \
__get_kernel_nofault(dst, src, type, err_label); \ __get_kernel_nofault(dst, src, type, err_label); \
dst += sizeof(type); \ dst += sizeof(type); \
...@@ -21,25 +22,25 @@ bool __weak probe_kernel_read_allowed(const void *unsafe_src, size_t size) ...@@ -21,25 +22,25 @@ bool __weak probe_kernel_read_allowed(const void *unsafe_src, size_t size)
len -= sizeof(type); \ len -= sizeof(type); \
} }
long probe_kernel_read(void *dst, const void *src, size_t size) long copy_from_kernel_nofault(void *dst, const void *src, size_t size)
{ {
if (!probe_kernel_read_allowed(src, size)) if (!copy_from_kernel_nofault_allowed(src, size))
return -ERANGE; return -ERANGE;
pagefault_disable(); pagefault_disable();
probe_kernel_read_loop(dst, src, size, u64, Efault); copy_from_kernel_nofault_loop(dst, src, size, u64, Efault);
probe_kernel_read_loop(dst, src, size, u32, Efault); copy_from_kernel_nofault_loop(dst, src, size, u32, Efault);
probe_kernel_read_loop(dst, src, size, u16, Efault); copy_from_kernel_nofault_loop(dst, src, size, u16, Efault);
probe_kernel_read_loop(dst, src, size, u8, Efault); copy_from_kernel_nofault_loop(dst, src, size, u8, Efault);
pagefault_enable(); pagefault_enable();
return 0; return 0;
Efault: Efault:
pagefault_enable(); pagefault_enable();
return -EFAULT; return -EFAULT;
} }
EXPORT_SYMBOL_GPL(probe_kernel_read); EXPORT_SYMBOL_GPL(copy_from_kernel_nofault);
#define probe_kernel_write_loop(dst, src, len, type, err_label) \ #define copy_to_kernel_nofault_loop(dst, src, len, type, err_label) \
while (len >= sizeof(type)) { \ while (len >= sizeof(type)) { \
__put_kernel_nofault(dst, src, type, err_label); \ __put_kernel_nofault(dst, src, type, err_label); \
dst += sizeof(type); \ dst += sizeof(type); \
...@@ -47,13 +48,13 @@ EXPORT_SYMBOL_GPL(probe_kernel_read); ...@@ -47,13 +48,13 @@ EXPORT_SYMBOL_GPL(probe_kernel_read);
len -= sizeof(type); \ len -= sizeof(type); \
} }
long probe_kernel_write(void *dst, const void *src, size_t size) long copy_to_kernel_nofault(void *dst, const void *src, size_t size)
{ {
pagefault_disable(); pagefault_disable();
probe_kernel_write_loop(dst, src, size, u64, Efault); copy_to_kernel_nofault_loop(dst, src, size, u64, Efault);
probe_kernel_write_loop(dst, src, size, u32, Efault); copy_to_kernel_nofault_loop(dst, src, size, u32, Efault);
probe_kernel_write_loop(dst, src, size, u16, Efault); copy_to_kernel_nofault_loop(dst, src, size, u16, Efault);
probe_kernel_write_loop(dst, src, size, u8, Efault); copy_to_kernel_nofault_loop(dst, src, size, u8, Efault);
pagefault_enable(); pagefault_enable();
return 0; return 0;
Efault: Efault:
...@@ -67,7 +68,7 @@ long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count) ...@@ -67,7 +68,7 @@ long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count)
if (unlikely(count <= 0)) if (unlikely(count <= 0))
return 0; return 0;
if (!probe_kernel_read_allowed(unsafe_addr, count)) if (!copy_from_kernel_nofault_allowed(unsafe_addr, count))
return -ERANGE; return -ERANGE;
pagefault_disable(); pagefault_disable();
...@@ -87,7 +88,7 @@ long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count) ...@@ -87,7 +88,7 @@ long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count)
} }
#else /* HAVE_GET_KERNEL_NOFAULT */ #else /* HAVE_GET_KERNEL_NOFAULT */
/** /**
* probe_kernel_read(): safely attempt to read from kernel-space * copy_from_kernel_nofault(): safely attempt to read from kernel-space
* @dst: pointer to the buffer that shall take the data * @dst: pointer to the buffer that shall take the data
* @src: address to read from * @src: address to read from
* @size: size of the data chunk * @size: size of the data chunk
...@@ -98,15 +99,15 @@ long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count) ...@@ -98,15 +99,15 @@ long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count)
* *
* We ensure that the copy_from_user is executed in atomic context so that * We ensure that the copy_from_user is executed in atomic context so that
* do_page_fault() doesn't attempt to take mmap_lock. This makes * do_page_fault() doesn't attempt to take mmap_lock. This makes
* probe_kernel_read() suitable for use within regions where the caller * copy_from_kernel_nofault() suitable for use within regions where the caller
* already holds mmap_lock, or other locks which nest inside mmap_lock. * already holds mmap_lock, or other locks which nest inside mmap_lock.
*/ */
long probe_kernel_read(void *dst, const void *src, size_t size) long copy_from_kernel_nofault(void *dst, const void *src, size_t size)
{ {
long ret; long ret;
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
if (!probe_kernel_read_allowed(src, size)) if (!copy_from_kernel_nofault_allowed(src, size))
return -ERANGE; return -ERANGE;
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
...@@ -120,10 +121,10 @@ long probe_kernel_read(void *dst, const void *src, size_t size) ...@@ -120,10 +121,10 @@ long probe_kernel_read(void *dst, const void *src, size_t size)
return -EFAULT; return -EFAULT;
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(probe_kernel_read); EXPORT_SYMBOL_GPL(copy_from_kernel_nofault);
/** /**
* probe_kernel_write(): safely attempt to write to a location * copy_to_kernel_nofault(): safely attempt to write to a location
* @dst: address to write to * @dst: address to write to
* @src: pointer to the data that shall be written * @src: pointer to the data that shall be written
* @size: size of the data chunk * @size: size of the data chunk
...@@ -131,7 +132,7 @@ EXPORT_SYMBOL_GPL(probe_kernel_read); ...@@ -131,7 +132,7 @@ EXPORT_SYMBOL_GPL(probe_kernel_read);
* Safely write to address @dst from the buffer at @src. If a kernel fault * Safely write to address @dst from the buffer at @src. If a kernel fault
* happens, handle that and return -EFAULT. * happens, handle that and return -EFAULT.
*/ */
long probe_kernel_write(void *dst, const void *src, size_t size) long copy_to_kernel_nofault(void *dst, const void *src, size_t size)
{ {
long ret; long ret;
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
...@@ -174,7 +175,7 @@ long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count) ...@@ -174,7 +175,7 @@ long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count)
if (unlikely(count <= 0)) if (unlikely(count <= 0))
return 0; return 0;
if (!probe_kernel_read_allowed(unsafe_addr, count)) if (!copy_from_kernel_nofault_allowed(unsafe_addr, count))
return -ERANGE; return -ERANGE;
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
......
...@@ -25,7 +25,7 @@ void rodata_test(void) ...@@ -25,7 +25,7 @@ void rodata_test(void)
} }
/* test 2: write to the variable; this should fault */ /* test 2: write to the variable; this should fault */
if (!probe_kernel_write((void *)&rodata_test_data, if (!copy_to_kernel_nofault((void *)&rodata_test_data,
(void *)&zero, sizeof(zero))) { (void *)&zero, sizeof(zero))) {
pr_err("test data was not read only\n"); pr_err("test data was not read only\n");
return; return;
......
...@@ -292,7 +292,7 @@ static inline void *get_freepointer_safe(struct kmem_cache *s, void *object) ...@@ -292,7 +292,7 @@ static inline void *get_freepointer_safe(struct kmem_cache *s, void *object)
return get_freepointer(s, object); return get_freepointer(s, object);
freepointer_addr = (unsigned long)object + s->offset; freepointer_addr = (unsigned long)object + s->offset;
probe_kernel_read(&p, (void **)freepointer_addr, sizeof(p)); copy_from_kernel_nofault(&p, (void **)freepointer_addr, sizeof(p));
return freelist_ptr(s, p, freepointer_addr); return freelist_ptr(s, p, freepointer_addr);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment