mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
lockdep: fix the TOCTTOU issue
The problem is that it checkes circular dependencies and one then adds the target lock to the graph. Reported-by: syzbot+7687e27a2029723c7fb4@syzkaller.appspotmail.com PiperOrigin-RevId: 512637945
This commit is contained in:
@@ -72,9 +72,23 @@ type goroutineLocks map[*MutexClass]bool
|
||||
|
||||
var routineLocks goroutineLocksAtomicPtrMap
|
||||
|
||||
// maxChainLen is the maximum length of a lock chain.
|
||||
const maxChainLen = 32
|
||||
|
||||
// checkLock checks that class isn't in the ancestors of prevClass.
|
||||
func checkLock(class *MutexClass, prevClass *MutexClass, chain []*MutexClass) {
|
||||
chain = append(chain, prevClass)
|
||||
if len(chain) >= maxChainLen {
|
||||
// It can be a race condition with another thread that added
|
||||
// the lock to the graph but don't complete the validation.
|
||||
var b strings.Builder
|
||||
fmt.Fprintf(&b, "WARNING: The maximum lock depth has been reached: %s", chain[0])
|
||||
for i := 1; i < len(chain); i++ {
|
||||
fmt.Fprintf(&b, "-> %s", chain[i])
|
||||
}
|
||||
log.Warningf("%s", b.String())
|
||||
return
|
||||
}
|
||||
if c := prevClass.ancestors.Load(class); c != nil {
|
||||
var b strings.Builder
|
||||
fmt.Fprintf(&b, "WARNING: circular locking detected: %s -> %s:\n%s\n",
|
||||
@@ -118,10 +132,14 @@ func AddGLock(class *MutexClass, lockNameIndex int) {
|
||||
return
|
||||
}
|
||||
|
||||
if (*currentLocks)[class] {
|
||||
panic(fmt.Sprintf("nested locking: %s:\n%s", class, log.LocalStack(2)))
|
||||
}
|
||||
(*currentLocks)[class] = true
|
||||
// Check dependencies and add locked mutexes to the ancestors list.
|
||||
for prevClass := range *currentLocks {
|
||||
if prevClass == class {
|
||||
panic(fmt.Sprintf("nested locking: %s:\n%s", class, log.LocalStack(2)))
|
||||
continue
|
||||
}
|
||||
checkLock(class, prevClass, nil)
|
||||
|
||||
@@ -130,7 +148,6 @@ func AddGLock(class *MutexClass, lockNameIndex int) {
|
||||
class.ancestors.Store(prevClass, &stacks)
|
||||
}
|
||||
}
|
||||
(*currentLocks)[class] = true
|
||||
}
|
||||
|
||||
// DelGLock deletes a lock from the current goroutine.
|
||||
|
||||
Reference in New Issue
Block a user