Applied, thanks! Sergey Bugaev, le mer. 27 mars 2024 19:18:29 +0300, a ecrit: > Depending on the architecture and setup, it may not be possible to > access user memory directly, for example, due to user mode mappings not > being accessible from kernel mode (x86 SMAP, AArch64 PAN). There are > dedicated machine-specific copyin()/copyout() routines that know how to > access user memory from the kernel; use them. > --- > kern/gsync.c | 38 +++++++++++++++++++++++++++++++------- > 1 file changed, 31 insertions(+), 7 deletions(-) > > diff --git a/kern/gsync.c b/kern/gsync.c > index 31b564ca..656e47dd 100644 > --- a/kern/gsync.c > +++ b/kern/gsync.c > @@ -23,6 +23,7 @@ > #include <kern/list.h> > #include <vm/vm_map.h> > #include <vm/vm_kern.h> > +#include <machine/locore.h> > > /* An entry in the global hash table. */ > struct gsync_hbucket > @@ -254,9 +255,28 @@ kern_return_t gsync_wait (task_t task, vm_offset_t addr, > > boolean_t equal; > if (! remote) > - equal = ((unsigned int *)addr)[0] == lo && > - ((flags & GSYNC_QUAD) == 0 || > - ((unsigned int *)addr)[1] == hi); > + { > + unsigned int value; > + > + if (copyin ((const void *) addr, &value, 4)) > + { > + vm_map_unlock_read (task->map); > + kmutex_unlock (&hbp->lock); > + return KERN_INVALID_ADDRESS; > + } > + > + equal = (value == lo); > + if (flags & GSYNC_QUAD) > + { > + if (copyin ((const void *) (addr + 4), &value, 4)) > + { > + vm_map_unlock_read (task->map); > + kmutex_unlock (&hbp->lock); > + return KERN_INVALID_ADDRESS; > + } > + equal = equal && (value == hi); > + } > + } > else > { > vm_offset_t paddr = temp_mapping (&va, addr, VM_PROT_READ); > @@ -388,11 +408,15 @@ kern_return_t gsync_wake (task_t task, > } > > addr = paddr + (addr & (PAGE_SIZE - 1)); > + *(unsigned int *)addr = val; > + vm_map_remove (kernel_map, addr, addr + sizeof (int)); > + } > + else if (copyout (&val, (void *) addr, 4)) > + { > + kmutex_unlock (&hbp->lock); > + vm_map_unlock_read (task->map); > + return KERN_INVALID_ADDRESS; > } > - > - *(unsigned int *)addr = val; > - if (task != current_task ()) > - vm_map_remove (kernel_map, addr, addr + sizeof (int)); > } > > vm_map_unlock_read (task->map); > -- > 2.44.0 > >
-- Samuel --- Pour une évaluation indépendante, transparente et rigoureuse ! Je soutiens la Commission d'Évaluation de l'Inria.