@@ -309,6 +309,8 @@ static void append_kcore_note(char *notes, size_t *i, const char *name,
309
309
310
310
static ssize_t read_kcore_iter (struct kiocb * iocb , struct iov_iter * iter )
311
311
{
312
+ struct file * file = iocb -> ki_filp ;
313
+ char * buf = file -> private_data ;
312
314
loff_t * fpos = & iocb -> ki_pos ;
313
315
size_t phdrs_offset , notes_offset , data_offset ;
314
316
size_t page_offline_frozen = 1 ;
@@ -555,10 +557,21 @@ static ssize_t read_kcore_iter(struct kiocb *iocb, struct iov_iter *iter)
555
557
case KCORE_VMEMMAP :
556
558
case KCORE_TEXT :
557
559
/*
558
- * We use _copy_to_iter() to bypass usermode hardening
559
- * which would otherwise prevent this operation.
560
+ * Sadly we must use a bounce buffer here to be able to
561
+ * make use of copy_from_kernel_nofault(), as these
562
+ * memory regions might not always be mapped on all
563
+ * architectures.
560
564
*/
561
- if (_copy_to_iter ((char * )start , tsz , iter ) != tsz ) {
565
+ if (copy_from_kernel_nofault (buf , (void * )start , tsz )) {
566
+ if (iov_iter_zero (tsz , iter ) != tsz ) {
567
+ ret = - EFAULT ;
568
+ goto out ;
569
+ }
570
+ /*
571
+ * We know the bounce buffer is safe to copy from, so
572
+ * use _copy_to_iter() directly.
573
+ */
574
+ } else if (_copy_to_iter (buf , tsz , iter ) != tsz ) {
562
575
ret = - EFAULT ;
563
576
goto out ;
564
577
}
@@ -595,6 +608,10 @@ static int open_kcore(struct inode *inode, struct file *filp)
595
608
if (ret )
596
609
return ret ;
597
610
611
+ filp -> private_data = kmalloc (PAGE_SIZE , GFP_KERNEL );
612
+ if (!filp -> private_data )
613
+ return - ENOMEM ;
614
+
598
615
if (kcore_need_update )
599
616
kcore_update_ram ();
600
617
if (i_size_read (inode ) != proc_root_kcore -> size ) {
@@ -605,9 +622,16 @@ static int open_kcore(struct inode *inode, struct file *filp)
605
622
return 0 ;
606
623
}
607
624
625
+ static int release_kcore (struct inode * inode , struct file * file )
626
+ {
627
+ kfree (file -> private_data );
628
+ return 0 ;
629
+ }
630
+
608
631
static const struct proc_ops kcore_proc_ops = {
609
632
.proc_read_iter = read_kcore_iter ,
610
633
.proc_open = open_kcore ,
634
+ .proc_release = release_kcore ,
611
635
.proc_lseek = default_llseek ,
612
636
};
613
637
0 commit comments