Re: ipc: BUG: sem_unlock unlocks non-locked lock
From: Manfred Spraul
Date:  Sun Dec 18 2016 - 13:33:05 EST
On 12/18/2016 05:29 PM, Davidlohr Bueso wrote:
On Sun, 18 Dec 2016, Bueso wrote:
On Fri, 16 Dec 2016, Dmitry Vyukov wrote:
[ BUG: bad unlock balance detected! ]
4.9.0+ #89 Not tainted
Thanks for the report, I can reproduce the issue as of (which I 
obviously
should have tested with lockdep):
370b262c896 (ipc/sem: avoid idr tree lookup for interrupted semop)
I need to think more about it this evening, but I believe the issue 
to be
the potentially bogus locknum in the unlock path, as we are calling 
sem_lock
without updating the variable. I'll send a patch after more testing. 
This
fixes it for me:
diff --git a/ipc/sem.c b/ipc/sem.c
index e08b94851922..fba6139e7208 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -1977,7 +1977,7 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct 
sembuf __user *, tsops,
        }
        rcu_read_lock();
-        sem_lock(sma, sops, nsops);
+            sem_lock(sma, sops, nsops);
*sigh*, that would be:
             locknum = sem_lock(sma, sops, nsops);
Yes, I can confirm that this fixes the issue.
Reproducing is simple:
- task A: single semop semop(), sleeps
- task B: multi semop semop(), sleeps
- task A woken up by signal/timeout
I'll send a patch.
--
    Manfred