Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc: use probe_user_read() and probe_user_write()

Instead of opencoding, use probe_user_read() to failessly read
a user location and probe_user_write() for writing to user.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/e041f5eedb23f09ab553be8a91c3de2087147320.1579800517.git.christophe.leroy@c-s.fr

authored by

Christophe Leroy and committed by
Michael Ellerman
def0bfdb 1e353198

+14 -62
+1 -11
arch/powerpc/kernel/process.c
··· 1277 1277 1278 1278 pc = regs->nip - (NR_INSN_TO_PRINT * 3 / 4 * sizeof(int)); 1279 1279 1280 - /* 1281 - * Make sure the NIP points at userspace, not kernel text/data or 1282 - * elsewhere. 1283 - */ 1284 - if (!__access_ok(pc, NR_INSN_TO_PRINT * sizeof(int), USER_DS)) { 1285 - pr_info("%s[%d]: Bad NIP, not dumping instructions.\n", 1286 - current->comm, current->pid); 1287 - return; 1288 - } 1289 - 1290 1280 seq_buf_init(&s, buf, sizeof(buf)); 1291 1281 1292 1282 while (n) { ··· 1287 1297 for (i = 0; i < 8 && n; i++, n--, pc += sizeof(int)) { 1288 1298 int instr; 1289 1299 1290 - if (probe_kernel_address((const void *)pc, instr)) { 1300 + if (probe_user_read(&instr, (void __user *)pc, sizeof(instr))) { 1291 1301 seq_buf_printf(&s, "XXXXXXXX "); 1292 1302 continue; 1293 1303 }
+2 -4
arch/powerpc/kvm/book3s_64_mmu_radix.c
··· 63 63 } 64 64 isync(); 65 65 66 - pagefault_disable(); 67 66 if (is_load) 68 - ret = raw_copy_from_user(to, from, n); 67 + ret = probe_user_read(to, (const void __user *)from, n); 69 68 else 70 - ret = raw_copy_to_user(to, from, n); 71 - pagefault_enable(); 69 + ret = probe_user_write((void __user *)to, from, n); 72 70 73 71 /* switch the pid first to avoid running host with unallocated pid */ 74 72 if (quadrant == 1 && pid != old_pid)
+1 -5
arch/powerpc/mm/fault.c
··· 279 279 if ((flags & FAULT_FLAG_WRITE) && (flags & FAULT_FLAG_USER) && 280 280 access_ok(nip, sizeof(*nip))) { 281 281 unsigned int inst; 282 - int res; 283 282 284 - pagefault_disable(); 285 - res = __get_user_inatomic(inst, nip); 286 - pagefault_enable(); 287 - if (!res) 283 + if (!probe_user_read(&inst, nip, sizeof(inst))) 288 284 return !store_updates_sp(inst); 289 285 *must_retry = true; 290 286 }
+2 -12
arch/powerpc/oprofile/backtrace.c
··· 28 28 unsigned int stack_frame[2]; 29 29 void __user *p = compat_ptr(sp); 30 30 31 - if (!access_ok(p, sizeof(stack_frame))) 32 - return 0; 33 - 34 31 /* 35 32 * The most likely reason for this is that we returned -EFAULT, 36 33 * which means that we've done all that we can do from 37 34 * interrupt context. 38 35 */ 39 - if (__copy_from_user_inatomic(stack_frame, p, sizeof(stack_frame))) 36 + if (probe_user_read(stack_frame, (void __user *)p, sizeof(stack_frame))) 40 37 return 0; 41 38 42 39 if (!is_first) ··· 51 54 { 52 55 unsigned long stack_frame[3]; 53 56 54 - if (!access_ok((void __user *)sp, sizeof(stack_frame))) 55 - return 0; 56 - 57 - if (__copy_from_user_inatomic(stack_frame, (void __user *)sp, 58 - sizeof(stack_frame))) 57 + if (probe_user_read(stack_frame, (void __user *)sp, sizeof(stack_frame))) 59 58 return 0; 60 59 61 60 if (!is_first) ··· 96 103 first_frame = 0; 97 104 } 98 105 } else { 99 - pagefault_disable(); 100 106 #ifdef CONFIG_PPC64 101 107 if (!is_32bit_task()) { 102 108 while (depth--) { ··· 104 112 break; 105 113 first_frame = 0; 106 114 } 107 - pagefault_enable(); 108 115 return; 109 116 } 110 117 #endif ··· 114 123 break; 115 124 first_frame = 0; 116 125 } 117 - pagefault_enable(); 118 126 } 119 127 }
+3 -17
arch/powerpc/perf/callchain.c
··· 155 155 ((unsigned long)ptr & 7)) 156 156 return -EFAULT; 157 157 158 - pagefault_disable(); 159 - if (!__get_user_inatomic(*ret, ptr)) { 160 - pagefault_enable(); 158 + if (!probe_user_read(ret, ptr, sizeof(*ret))) 161 159 return 0; 162 - } 163 - pagefault_enable(); 164 160 165 161 return read_user_stack_slow(ptr, ret, 8); 166 162 } ··· 167 171 ((unsigned long)ptr & 3)) 168 172 return -EFAULT; 169 173 170 - pagefault_disable(); 171 - if (!__get_user_inatomic(*ret, ptr)) { 172 - pagefault_enable(); 174 + if (!probe_user_read(ret, ptr, sizeof(*ret))) 173 175 return 0; 174 - } 175 - pagefault_enable(); 176 176 177 177 return read_user_stack_slow(ptr, ret, 4); 178 178 } ··· 285 293 */ 286 294 static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret) 287 295 { 288 - int rc; 289 - 290 296 if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) || 291 297 ((unsigned long)ptr & 3)) 292 298 return -EFAULT; 293 299 294 - pagefault_disable(); 295 - rc = __get_user_inatomic(*ret, ptr); 296 - pagefault_enable(); 297 - 298 - return rc; 300 + return probe_user_read(ret, ptr, sizeof(*ret)); 299 301 } 300 302 301 303 static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
+1 -7
arch/powerpc/perf/core-book3s.c
··· 415 415 static __u64 power_pmu_bhrb_to(u64 addr) 416 416 { 417 417 unsigned int instr; 418 - int ret; 419 418 __u64 target; 420 419 421 420 if (is_kernel_addr(addr)) { ··· 425 426 } 426 427 427 428 /* Userspace: need copy instruction here then translate it */ 428 - pagefault_disable(); 429 - ret = __get_user_inatomic(instr, (unsigned int __user *)addr); 430 - if (ret) { 431 - pagefault_enable(); 429 + if (probe_user_read(&instr, (unsigned int __user *)addr, sizeof(instr))) 432 430 return 0; 433 - } 434 - pagefault_enable(); 435 431 436 432 target = branch_target(&instr); 437 433 if ((!target) || (instr & BRANCH_ABSOLUTE))
+4 -6
arch/powerpc/sysdev/fsl_pci.c
··· 1065 1065 addr += mfspr(SPRN_MCAR); 1066 1066 1067 1067 if (is_in_pci_mem_space(addr)) { 1068 - if (user_mode(regs)) { 1069 - pagefault_disable(); 1070 - ret = get_user(inst, (__u32 __user *)regs->nip); 1071 - pagefault_enable(); 1072 - } else { 1068 + if (user_mode(regs)) 1069 + ret = probe_user_read(&inst, (void __user *)regs->nip, 1070 + sizeof(inst)); 1071 + else 1073 1072 ret = probe_kernel_address((void *)regs->nip, inst); 1074 - } 1075 1073 1076 1074 if (!ret && mcheck_handle_load(regs, inst)) { 1077 1075 regs->nip += 4;