@@ -504,9 +504,8 @@ static bool consumer_del(struct uprobe *uprobe, struct uprobe_consumer *uc)
504504 return ret ;
505505}
506506
507- static int
508- __copy_insn (struct address_space * mapping , struct file * filp , char * insn ,
509- unsigned long nbytes , loff_t offset )
507+ static int __copy_insn (struct address_space * mapping , struct file * filp ,
508+ void * insn , int nbytes , loff_t offset )
510509{
511510 struct page * page ;
512511
@@ -528,28 +527,28 @@ __copy_insn(struct address_space *mapping, struct file *filp, char *insn,
528527
529528static int copy_insn (struct uprobe * uprobe , struct file * filp )
530529{
531- struct address_space * mapping ;
532- unsigned long nbytes ;
533- int bytes ;
534-
535- nbytes = PAGE_SIZE - (uprobe -> offset & ~PAGE_MASK );
536- mapping = uprobe -> inode -> i_mapping ;
530+ struct address_space * mapping = uprobe -> inode -> i_mapping ;
531+ loff_t offs = uprobe -> offset ;
532+ void * insn = uprobe -> arch .insn ;
533+ int size = MAX_UINSN_BYTES ;
534+ int len , err = - EIO ;
537535
538- /* Instruction at end of binary; copy only available bytes */
539- if (uprobe -> offset + MAX_UINSN_BYTES > uprobe -> inode -> i_size )
540- bytes = uprobe -> inode -> i_size - uprobe -> offset ;
541- else
542- bytes = MAX_UINSN_BYTES ;
536+ /* Copy only available bytes, -EIO if nothing was read */
537+ do {
538+ if (offs >= i_size_read (uprobe -> inode ))
539+ break ;
543540
544- /* Instruction at the page-boundary; copy bytes in second page */
545- if (nbytes < bytes ) {
546- int err = __copy_insn (mapping , filp , uprobe -> arch .insn + nbytes ,
547- bytes - nbytes , uprobe -> offset + nbytes );
541+ len = min_t (int , size , PAGE_SIZE - (offs & ~PAGE_MASK ));
542+ err = __copy_insn (mapping , filp , insn , len , offs );
548543 if (err )
549- return err ;
550- bytes = nbytes ;
551- }
552- return __copy_insn (mapping , filp , uprobe -> arch .insn , bytes , uprobe -> offset );
544+ break ;
545+
546+ insn += len ;
547+ offs += len ;
548+ size -= len ;
549+ } while (size );
550+
551+ return err ;
553552}
554553
555554static int prepare_uprobe (struct uprobe * uprobe , struct file * file ,
@@ -1447,7 +1446,7 @@ void uprobe_copy_process(struct task_struct *t, unsigned long flags)
14471446 if (!work )
14481447 return uprobe_warn (t , "dup xol area" );
14491448
1450- utask -> vaddr = area -> vaddr ;
1449+ t -> utask -> vaddr = area -> vaddr ;
14511450 init_task_work (work , dup_xol_work );
14521451 task_work_add (t , work , true);
14531452}
0 commit comments