bugfix: protect field access with lock to avoid possible data race (#5211)

This commit is contained in:
Stone-afk
2023-05-18 21:22:41 +08:00
committed by Ming Deng
parent f61065d674
commit 4e481606f7
12 changed files with 81 additions and 98 deletions

View File

@@ -20,15 +20,16 @@
//
// Usage:
// import(
// _ "github.com/beego/beego/v2/server/web/session/couchbase"
// "github.com/beego/beego/v2/server/web/session"
//
// _ "github.com/beego/beego/v2/server/web/session/couchbase"
// "github.com/beego/beego/v2/server/web/session"
//
// )
//
// func init() {
// globalSessions, _ = session.NewManager("couchbase", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"http://host:port/, Pool, Bucket"}``)
// go globalSessions.GC()
// }
//
package couchbase
import (
@@ -105,8 +106,10 @@ func (cs *SessionStore) SessionID(context.Context) string {
// SessionRelease Write couchbase session with Gob string
func (cs *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
defer cs.b.Close()
bo, err := session.EncodeGob(cs.values)
cs.lock.RLock()
values := cs.values
cs.lock.RUnlock()
bo, err := session.EncodeGob(values)
if err != nil {
return
}

View File

@@ -69,7 +69,10 @@ func (ls *SessionStore) SessionID(context.Context) string {
// SessionRelease save session values to ledis
func (ls *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
b, err := session.EncodeGob(ls.values)
ls.lock.RLock()
values := ls.values
ls.lock.RUnlock()
b, err := session.EncodeGob(values)
if err != nil {
return
}

View File

@@ -20,15 +20,16 @@
//
// Usage:
// import(
// _ "github.com/beego/beego/v2/server/web/session/memcache"
// "github.com/beego/beego/v2/server/web/session"
//
// _ "github.com/beego/beego/v2/server/web/session/memcache"
// "github.com/beego/beego/v2/server/web/session"
//
// )
//
// func init() {
// globalSessions, _ = session.NewManager("memcache", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:11211"}``)
// go globalSessions.GC()
// }
//
package memcache
import (
@@ -96,7 +97,10 @@ func (rs *SessionStore) SessionID(context.Context) string {
// SessionRelease save session values to memcache
func (rs *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
b, err := session.EncodeGob(rs.values)
rs.lock.RLock()
values := rs.values
rs.lock.RUnlock()
b, err := session.EncodeGob(values)
if err != nil {
return
}

View File

@@ -19,6 +19,7 @@
// go install github.com/go-sql-driver/mysql
//
// mysql session support need create table as sql:
//
// CREATE TABLE `session` (
// `session_key` char(64) NOT NULL,
// `session_data` blob,
@@ -28,15 +29,16 @@
//
// Usage:
// import(
// _ "github.com/beego/beego/v2/server/web/session/mysql"
// "github.com/beego/beego/v2/server/web/session"
//
// _ "github.com/beego/beego/v2/server/web/session/mysql"
// "github.com/beego/beego/v2/server/web/session"
//
// )
//
// func init() {
// globalSessions, _ = session.NewManager("mysql", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]"}``)
// go globalSessions.GC()
// }
//
package mysql
import (
@@ -109,7 +111,10 @@ func (st *SessionStore) SessionID(context.Context) string {
// must call this method to save values to database.
func (st *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
defer st.c.Close()
b, err := session.EncodeGob(st.values)
st.lock.RLock()
values := st.values
st.lock.RUnlock()
b, err := session.EncodeGob(values)
if err != nil {
return
}

View File

@@ -18,7 +18,6 @@
//
// go install github.com/lib/pq
//
//
// needs this table in your database:
//
// CREATE TABLE session (
@@ -35,18 +34,18 @@
// SessionSavePath = "user=a password=b dbname=c sslmode=disable"
// SessionName = session
//
//
// Usage:
// import(
// _ "github.com/beego/beego/v2/server/web/session/postgresql"
// "github.com/beego/beego/v2/server/web/session"
//
// _ "github.com/beego/beego/v2/server/web/session/postgresql"
// "github.com/beego/beego/v2/server/web/session"
//
// )
//
// func init() {
// globalSessions, _ = session.NewManager("postgresql", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"user=pqgotest dbname=pqgotest sslmode=verify-full"}``)
// go globalSessions.GC()
// }
//
package postgres
import (
@@ -115,7 +114,10 @@ func (st *SessionStore) SessionID(context.Context) string {
// must call this method to save values to database.
func (st *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
defer st.c.Close()
b, err := session.EncodeGob(st.values)
st.lock.RLock()
values := st.values
st.lock.RUnlock()
b, err := session.EncodeGob(values)
if err != nil {
return
}

View File

@@ -20,15 +20,16 @@
//
// Usage:
// import(
// _ "github.com/beego/beego/v2/server/web/session/redis"
// "github.com/beego/beego/v2/server/web/session"
//
// _ "github.com/beego/beego/v2/server/web/session/redis"
// "github.com/beego/beego/v2/server/web/session"
//
// )
//
// func init() {
// globalSessions, _ = session.NewManager("redis", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:7070"}``)
// go globalSessions.GC()
// }
//
// func init() {
// globalSessions, _ = session.NewManager("redis", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:7070"}``)
// go globalSessions.GC()
// }
package redis
import (
@@ -100,7 +101,10 @@ func (rs *SessionStore) SessionID(context.Context) string {
// SessionRelease save session values to redis
func (rs *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
b, err := session.EncodeGob(rs.values)
rs.lock.RLock()
values := rs.values
rs.lock.RUnlock()
b, err := session.EncodeGob(values)
if err != nil {
return
}

View File

@@ -20,15 +20,16 @@
//
// Usage:
// import(
// _ "github.com/beego/beego/v2/server/web/session/redis_cluster"
// "github.com/beego/beego/v2/server/web/session"
//
// _ "github.com/beego/beego/v2/server/web/session/redis_cluster"
// "github.com/beego/beego/v2/server/web/session"
//
// )
//
// func init() {
// globalSessions, _ = session.NewManager("redis_cluster", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:7070;127.0.0.1:7071"}``)
// go globalSessions.GC()
// }
//
package redis_cluster
import (
@@ -100,7 +101,10 @@ func (rs *SessionStore) SessionID(context.Context) string {
// SessionRelease save session values to redis_cluster
func (rs *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
b, err := session.EncodeGob(rs.values)
rs.lock.RLock()
values := rs.values
rs.lock.RUnlock()
b, err := session.EncodeGob(values)
if err != nil {
return
}

View File

@@ -20,8 +20,10 @@
//
// Usage:
// import(
// _ "github.com/beego/beego/v2/server/web/session/redis_sentinel"
// "github.com/beego/beego/v2/server/web/session"
//
// _ "github.com/beego/beego/v2/server/web/session/redis_sentinel"
// "github.com/beego/beego/v2/server/web/session"
//
// )
//
// func init() {
@@ -101,7 +103,10 @@ func (rs *SessionStore) SessionID(context.Context) string {
// SessionRelease save session values to redis_sentinel
func (rs *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
b, err := session.EncodeGob(rs.values)
rs.lock.RLock()
values := rs.values
rs.lock.RUnlock()
b, err := session.EncodeGob(values)
if err != nil {
return
}

View File

@@ -75,9 +75,11 @@ func (st *CookieSessionStore) SessionID(context.Context) string {
// SessionRelease Write cookie session to http response cookie
func (st *CookieSessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
st.lock.Lock()
encodedCookie, err := encodeCookie(cookiepder.block, cookiepder.config.SecurityKey, cookiepder.config.SecurityName, st.values)
st.lock.Unlock()
st.lock.RLock()
values := st.values
st.lock.RUnlock()
encodedCookie, err := encodeCookie(
cookiepder.block, cookiepder.config.SecurityKey, cookiepder.config.SecurityName, values)
if err == nil {
cookie := &http.Cookie{
Name: cookiepder.config.CookieName,
@@ -110,11 +112,12 @@ type CookieProvider struct {
// SessionInit Init cookie session provider with max lifetime and config json.
// maxlifetime is ignored.
// json config:
// securityKey - hash string
// blockKey - gob encode hash string. it's saved as aes crypto.
// securityName - recognized name in encoded cookie string
// cookieName - cookie name
// maxage - cookie max life time.
//
// securityKey - hash string
// blockKey - gob encode hash string. it's saved as aes crypto.
// securityName - recognized name in encoded cookie string
// cookieName - cookie name
// maxage - cookie max life time.
func (pder *CookieProvider) SessionInit(ctx context.Context, maxlifetime int64, config string) error {
pder.config = &cookieConfig{}
err := json.Unmarshal([]byte(config), pder.config)

View File

@@ -205,7 +205,10 @@ func (s *SessionStore) SessionID(context.Context) string {
// SessionRelease Store the keyvalues into ssdb
func (s *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
b, err := session.EncodeGob(s.values)
s.lock.RLock()
values := s.values
s.lock.RUnlock()
b, err := session.EncodeGob(values)
if err != nil {
return
}