[LTP] [PATCH 1/2] [mtest06] Fix race condition with signal handling
Jan Stancek
jstancek@redhat.com
Tue Dec 12 10:53:49 CET 2017
----- Original Message -----
> Hi!
> > > I would also like to mention that we need to use locking at least when
> > > the address computation and actual access to it is happening:
> > >
> > > read thread write thread
> > > <compute and load address based on active mapping>
> > > unmap()
> > > <access address thinking it should be mapped>
> > > <unexpected SIGSEGV>
> > >
> > > There should be no issues with leaving out locking for the other parts
> > > of code, but I found no feasible way to get around this one.
> >
> > The idea me and Veronika were dicussing off-list was using just
> > pthread_mutex_trylock() without actual blocking to avoid race above.
> >
> > >
> > > I'd be happy to hear any feedback or different ideas how to tackle both
> > > issues if anybody has them.
> >
> > I don't see problem using 2 pages.
> > I'd drop '-s' parameter until there's need for it.
>
> Agreed.
>
> > I'd try some minimal locking and measure how many iterations
> > are we able to do now vs. before.
>
> Sounds reasonable.
>
> I guess that it's impossible to make it 100% correct without any
> locking, so we should make it as lightweight as possible, maybe some
> spinlocks atomic operations and sched_yield().
>
> I was thinking of doing pthread_kill() to the reading thread with some
> other signal that would flip a flag in the signal handler before we
> unmap and after we map the memory, so we will use that signal as a some
> kind of barrier. But this may be tricky to get working and quite
> possibly will not work at all.
>
> > ---
> > Thinking loud about alternatives:
> >
> > Signal handler could be replaced with write() to some temporary
> > file, which would use the ptr to mapped/unmapped area. If it's
> > not mapped we get EFAULT. This would also eliminate setjmp()/longjmp().
>
> I wonder if we should actually test both, but yes handling EFAULT would
> make this much easier than asynchronous signal delivery. On the other
> hand the signal handler code is much more complex so there is probably
> bigger room for triggering bugs.
>
> > If we stop looking at mapped status and only consider mapped data,
> > then this would turn into checking written pattern:
> > 1) create file A with some pattern
> > 2) thread1 maps/unmaps file into memory at X
> > 3) thread2 writes to file B, from memory X, this will either work or fail
> > with EFAULT
> > 4) report PASS if all blocks in file B have same pattern as blocks in file
> > A
>
> And thread2 retries on EFAULT with the same address again, right? This
> sounds interesting enough to be implemented as a test.
OK, I'll put it on my TODO list (as mtest08).
>
> > To address "read between mmap/munmap must succeed", there would probably
> > also
> > need to be a write performed by thread1 to file C.
>
> But that runs synchronously between the mmap() and unmap() right? That
> kind of misses the point of the original test, however I wonder how
It does. Likely better to have two tests, mtest06 with some light
locking, and mtest08 doing the EFAULT checks.
Regards,
Jan
More information about the ltp
mailing list