|
@@ -512,23 +512,15 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
|
|
return -EFAULT;
|
|
return -EFAULT;
|
|
} else {
|
|
} else {
|
|
if (kern_addr_valid(start)) {
|
|
if (kern_addr_valid(start)) {
|
|
- unsigned long n;
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* Using bounce buffer to bypass the
|
|
* Using bounce buffer to bypass the
|
|
* hardened user copy kernel text checks.
|
|
* hardened user copy kernel text checks.
|
|
*/
|
|
*/
|
|
- memcpy(buf, (char *) start, tsz);
|
|
|
|
- n = copy_to_user(buffer, buf, tsz);
|
|
|
|
- /*
|
|
|
|
- * We cannot distinguish between fault on source
|
|
|
|
- * and fault on destination. When this happens
|
|
|
|
- * we clear too and hope it will trigger the
|
|
|
|
- * EFAULT again.
|
|
|
|
- */
|
|
|
|
- if (n) {
|
|
|
|
- if (clear_user(buffer + tsz - n,
|
|
|
|
- n))
|
|
|
|
|
|
+ if (probe_kernel_read(buf, (void *) start, tsz)) {
|
|
|
|
+ if (clear_user(buffer, tsz))
|
|
|
|
+ return -EFAULT;
|
|
|
|
+ } else {
|
|
|
|
+ if (copy_to_user(buffer, buf, tsz))
|
|
return -EFAULT;
|
|
return -EFAULT;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|