Uploaded image for project: 'Couchbase Gateway'
  1. Couchbase Gateway
  2. CBG-1998

[3.0.1 backport] Fix race condition caused when getting user roles

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • Critical
    • 3.0.1
    • 2.8.2
    • SyncGateway
    • Security Level: Public
    • None
    • CBG Sprint 95
    • 1

    Description

      A race condition has been discovered in GetRoles() caused by the nil check, and the user.roles write being done at the same time when replicating 2 documents (with channels) with a custom sync function, and using users with explicit channels.

      This needs to be fixed to make sure this function does not race. This can be done by adding a lock on the userImp struct and then using a read lock, and upgrading it when needed.

      WARNING: DATA RACE
      Read at 0x00c00097c0d0 by goroutine 117:
        github.com/couchbase/sync_gateway/auth.(*userImpl).GetRoles()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/auth/user.go:458 +0x5b
        github.com/couchbase/sync_gateway/auth.(*userImpl).InheritedChannels()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/auth/user.go:507 +0x90
        github.com/couchbase/sync_gateway/db.makeUserCtx()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/crud.go:2239 +0x141
        github.com/couchbase/sync_gateway/db.(*Database).getChannelsAndAccess()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/crud.go:2191 +0x330
        github.com/couchbase/sync_gateway/db.(*Database).runSyncFn()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/crud.go:1422 +0x8b
        github.com/couchbase/sync_gateway/db.(*Database).documentUpdateFunc()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/crud.go:1667 +0x425
        github.com/couchbase/sync_gateway/db.(*Database).updateAndReturnDoc.func1()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/crud.go:1767 +0x504
        github.com/couchbaselabs/walrus.(*WalrusBucket).Update.func1()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbaselabs/walrus/crud.go:583 +0x55
        github.com/couchbaselabs/walrus.(*WalrusBucket).WriteUpdate()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbaselabs/walrus/crud.go:560 +0x1dc
        github.com/couchbaselabs/walrus.(*WalrusBucket).Update()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbaselabs/walrus/crud.go:586 +0x84
        github.com/couchbase/sync_gateway/base.(*LeakyBucket).Update()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/base/leaky_bucket.go:160 +0x201
        github.com/couchbase/sync_gateway/base.(*LoggingBucket).Update()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/base/logging_bucket.go:91 +0x1d2
        github.com/couchbase/sync_gateway/db.(*Database).updateAndReturnDoc()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/crud.go:1755 +0xa2a
        github.com/couchbase/sync_gateway/db.(*Database).PutExistingRevWithConflictResolution()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/crud.go:939 +0x528
        github.com/couchbase/sync_gateway/db.(*Database).PutExistingRev()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/crud.go:923 +0x2564
        github.com/couchbase/sync_gateway/db.(*blipHandler).handleRev()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/blip_handler.go:943 +0x1a36
        github.com/couchbase/sync_gateway/db.userBlipHandler.func1()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/blip_handler.go:84 +0x7b
        github.com/couchbase/sync_gateway/db.(*BlipSyncContext).register.func1()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/blip_sync_context.go:169 +0x2fa
        github.com/couchbase/go-blip.(*Context).dispatchRequest()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/go-blip/context.go:228 +0x275
        github.com/couchbase/go-blip.(*receiver).getPendingRequest.func1()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/go-blip/receiver.go:266 +0x75
        github.com/couchbase/go-blip.(*Message).asyncRead.func1()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/go-blip/message.go:371 +0x121
       
      Previous write at 0x00c00097c0d0 by goroutine 115:
        github.com/couchbase/sync_gateway/auth.(*userImpl).GetRoles()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/auth/user.go:471 +0x385
        github.com/couchbase/sync_gateway/auth.(*userImpl).InheritedChannels()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/auth/user.go:507 +0x90
        github.com/couchbase/sync_gateway/db.makeUserCtx()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/crud.go:2239 +0x141
        github.com/couchbase/sync_gateway/db.(*Database).getChannelsAndAccess()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/crud.go:2191 +0x330
        github.com/couchbase/sync_gateway/db.(*Database).runSyncFn()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/crud.go:1422 +0x8b
        github.com/couchbase/sync_gateway/db.(*Database).documentUpdateFunc()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/crud.go:1667 +0x425
        github.com/couchbase/sync_gateway/db.(*Database).updateAndReturnDoc.func1()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/crud.go:1767 +0x504
        github.com/couchbaselabs/walrus.(*WalrusBucket).Update.func1()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbaselabs/walrus/crud.go:583 +0x55
        github.com/couchbaselabs/walrus.(*WalrusBucket).WriteUpdate()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbaselabs/walrus/crud.go:560 +0x1dc
        github.com/couchbaselabs/walrus.(*WalrusBucket).Update()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbaselabs/walrus/crud.go:586 +0x84
        github.com/couchbase/sync_gateway/base.(*LeakyBucket).Update()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/base/leaky_bucket.go:160 +0x201
        github.com/couchbase/sync_gateway/base.(*LoggingBucket).Update()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/base/logging_bucket.go:91 +0x1d2
        github.com/couchbase/sync_gateway/db.(*Database).updateAndReturnDoc()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/crud.go:1755 +0xa2a
        github.com/couchbase/sync_gateway/db.(*Database).PutExistingRevWithConflictResolution()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/crud.go:939 +0x528
        github.com/couchbase/sync_gateway/db.(*Database).PutExistingRev()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/crud.go:923 +0x2564
        github.com/couchbase/sync_gateway/db.(*blipHandler).handleRev()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/blip_handler.go:943 +0x1a36
        github.com/couchbase/sync_gateway/db.userBlipHandler.func1()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/blip_handler.go:84 +0x7b
        github.com/couchbase/sync_gateway/db.(*BlipSyncContext).register.func1()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/sync_gateway/db/blip_sync_context.go:169 +0x2fa
        github.com/couchbase/go-blip.(*Context).dispatchRequest()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/go-blip/context.go:228 +0x275
        github.com/couchbase/go-blip.(*receiver).getPendingRequest.func1()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/go-blip/receiver.go:266 +0x75
        github.com/couchbase/go-blip.(*Message).asyncRead.func1()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/go-blip/message.go:371 +0x121
       
      Goroutine 117 (running) created at:
        github.com/couchbase/go-blip.(*Message).asyncRead()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/go-blip/message.go:357 +0x344
        github.com/couchbase/go-blip.(*receiver).getPendingRequest()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/go-blip/receiver.go:265 +0x545
        github.com/couchbase/go-blip.(*receiver).processFrame()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/go-blip/receiver.go:220 +0x1ab
        github.com/couchbase/go-blip.(*receiver).handleIncomingFrame()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/go-blip/receiver.go:209 +0xca4
        github.com/couchbase/go-blip.(*receiver).parseLoop()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/go-blip/receiver.go:103 +0x1cc
        github.com/couchbase/go-blip.(*receiver).receiveLoop- dwrap- 13()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/go-blip/receiver.go:60 +0x39
       
      Goroutine 115 (running) created at:
        github.com/couchbase/go-blip.(*Message).asyncRead()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/go-blip/message.go:357 +0x344
        github.com/couchbase/go-blip.(*receiver).getPendingRequest()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/go-blip/receiver.go:265 +0x545
        github.com/couchbase/go-blip.(*receiver).processFrame()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/go-blip/receiver.go:220 +0x1ab
        github.com/couchbase/go-blip.(*receiver).handleIncomingFrame()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/go-blip/receiver.go:209 +0xca4
        github.com/couchbase/go-blip.(*receiver).parseLoop()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/go-blip/receiver.go:103 +0x1cc
        github.com/couchbase/go-blip.(*receiver).receiveLoop- dwrap- 13()
            /Users/isaaclambat/dev/sync-gateway/master/godeps/src/github.com/couchbase/go-blip/receiver.go:60 +0x39
      ==================
      

      Attachments

        Issue Links

          Activity

            People

              isaac.lambat Isaac Lambat
              isaac.lambat Isaac Lambat
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                PagerDuty