Skip to content

Commit

Permalink
util: change super to process privilege when reading statements_summa…
Browse files Browse the repository at this point in the history
  • Loading branch information
djshow832 authored Aug 23, 2021
1 parent 4cc2423 commit 48e12ae
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 47 deletions.
8 changes: 2 additions & 6 deletions executor/infoschema_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -2102,11 +2102,6 @@ func (e *stmtSummaryTableRetriever) retrieve(ctx context.Context, sctx sessionct
return nil, nil
}
e.retrieved = true
user := sctx.GetSessionVars().User
isSuper := false
if pm := privilege.GetPrivilegeManager(sctx); pm != nil {
isSuper = pm.RequestVerificationWithUser("", "", "", mysql.SuperPriv, user)
}

var err error
var instanceAddr string
Expand All @@ -2118,7 +2113,8 @@ func (e *stmtSummaryTableRetriever) retrieve(ctx context.Context, sctx sessionct
return nil, err
}
}
reader := stmtsummary.NewStmtSummaryReader(user, isSuper, e.columns, instanceAddr)
user := sctx.GetSessionVars().User
reader := stmtsummary.NewStmtSummaryReader(user, hasPriv(sctx, mysql.ProcessPriv), e.columns, instanceAddr)
var rows [][]types.Datum
switch e.table.Name.O {
case infoschema.TableStatementsSummary,
Expand Down
60 changes: 35 additions & 25 deletions infoschema/tables_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1149,51 +1149,61 @@ func (s *testTableSuite) TestStmtSummaryTable(c *C) {
from information_schema.statements_summary`,
).Check(testkit.Rows())

// Create a new session to test
tk = s.newTestKitWithRoot(c)

tk.MustExec("set global tidb_enable_stmt_summary = on")
tk.MustExec("set global tidb_stmt_summary_history_size = 24")
}

func (s *testTableSuite) TestStmtSummaryTablePriv(c *C) {
tk := s.newTestKitWithRoot(c)

tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int, b varchar(10), key k(a))")
defer tk.MustExec("drop table if exists t")

// Disable refreshing summary.
tk.MustExec("set global tidb_stmt_summary_refresh_interval = 999999999")
tk.MustQuery("select @@global.tidb_stmt_summary_refresh_interval").Check(testkit.Rows("999999999"))
// Clear all statements.
tk.MustExec("set global tidb_enable_stmt_summary = 0")
tk.MustExec("set global tidb_enable_stmt_summary = 1")

// Create a new user to test statements summary table privilege
tk.MustExec("drop user if exists 'test_user'@'localhost'")
tk.MustExec("create user 'test_user'@'localhost'")
tk.MustExec("grant select on *.* to 'test_user'@'localhost'")
tk.Se.Auth(&auth.UserIdentity{
Username: "root",
Hostname: "%",
AuthUsername: "root",
AuthHostname: "%",
}, nil, nil)
defer tk.MustExec("drop user if exists 'test_user'@'localhost'")
tk.MustExec("grant select on test.t to 'test_user'@'localhost'")
tk.MustExec("select * from t where a=1")
result := tk.MustQuery("select * from information_schema.statements_summary where digest_text like 'select * from `t`%'")
// Super user can query all records.
c.Assert(len(result.Rows()), Equals, 1)
result = tk.MustQuery("select * from information_schema.statements_summary_history where digest_text like 'select * from `t`%'")
c.Assert(len(result.Rows()), Equals, 1)
tk.Se.Auth(&auth.UserIdentity{

tk1 := testkit.NewTestKitWithInit(c, s.store)
tk1.Se.Auth(&auth.UserIdentity{
Username: "test_user",
Hostname: "localhost",
AuthUsername: "test_user",
AuthHostname: "localhost",
}, nil, nil)
result = tk.MustQuery("select * from information_schema.statements_summary where digest_text like 'select * from `t`%'")

result = tk1.MustQuery("select * from information_schema.statements_summary where digest_text like 'select * from `t`%'")
// Ordinary users can not see others' records
c.Assert(len(result.Rows()), Equals, 0)
result = tk.MustQuery("select * from information_schema.statements_summary_history where digest_text like 'select * from `t`%'")
result = tk1.MustQuery("select * from information_schema.statements_summary_history where digest_text like 'select * from `t`%'")
c.Assert(len(result.Rows()), Equals, 0)
tk.MustExec("select * from t where a=1")
result = tk.MustQuery("select * from information_schema.statements_summary where digest_text like 'select * from `t`%'")
tk1.MustExec("select * from t where b=1")
result = tk1.MustQuery("select * from information_schema.statements_summary where digest_text like 'select * from `t`%'")
// Ordinary users can see his own records
c.Assert(len(result.Rows()), Equals, 1)
tk.MustExec("select * from t where a=1")
result = tk.MustQuery("select * from information_schema.statements_summary_history where digest_text like 'select * from `t`%'")
result = tk1.MustQuery("select * from information_schema.statements_summary_history where digest_text like 'select * from `t`%'")
c.Assert(len(result.Rows()), Equals, 1)
// use root user to set variables back
tk.Se.Auth(&auth.UserIdentity{
Username: "root",
Hostname: "%",
AuthUsername: "root",
AuthHostname: "%",
}, nil, nil)

tk.MustExec("grant process on *.* to 'test_user'@'localhost'")
result = tk1.MustQuery("select * from information_schema.statements_summary where digest_text like 'select * from `t`%'")
// Users with 'PROCESS' privileges can query all records.
c.Assert(len(result.Rows()), Equals, 2)
result = tk1.MustQuery("select * from information_schema.statements_summary_history where digest_text like 'select * from `t`%'")
c.Assert(len(result.Rows()), Equals, 2)
}

func (s *testTableSuite) TestIssue18845(c *C) {
Expand Down
21 changes: 11 additions & 10 deletions util/stmtsummary/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,23 @@ import (

// stmtSummaryReader uses to read the statement summaries data and convert to []datum row.
type stmtSummaryReader struct {
user *auth.UserIdentity
isSuper bool
user *auth.UserIdentity
// If the user has the 'PROCESS' privilege, he can read all the statements.
hasProcessPriv bool
columns []*model.ColumnInfo
instanceAddr string
ssMap *stmtSummaryByDigestMap
columnValueFactories []columnValueFactory
}

// NewStmtSummaryReader return a new statement summaries reader.
func NewStmtSummaryReader(user *auth.UserIdentity, isSuper bool, cols []*model.ColumnInfo, instanceAddr string) *stmtSummaryReader {
func NewStmtSummaryReader(user *auth.UserIdentity, hasProcessPriv bool, cols []*model.ColumnInfo, instanceAddr string) *stmtSummaryReader {
reader := &stmtSummaryReader{
user: user,
isSuper: isSuper,
columns: cols,
instanceAddr: instanceAddr,
ssMap: StmtSummaryByDigestMap,
user: user,
hasProcessPriv: hasProcessPriv,
columns: cols,
instanceAddr: instanceAddr,
ssMap: StmtSummaryByDigestMap,
}
// initialize column value factories.
reader.columnValueFactories = make([]columnValueFactory, len(reader.columns))
Expand Down Expand Up @@ -120,7 +121,7 @@ func (ssr *stmtSummaryReader) getStmtByDigestRow(ssbd *stmtSummaryByDigest, begi
// `ssElement` is lazy expired, so expired elements could also be read.
// `beginTime` won't change since `ssElement` is created, so locking is not needed here.
isAuthed := true
if ssr.user != nil && !ssr.isSuper {
if ssr.user != nil && !ssr.hasProcessPriv && ssElement != nil {
_, isAuthed = ssElement.authUsers[ssr.user.Username]
}
if ssElement == nil || ssElement.beginTime < beginTimeForCurInterval || !isAuthed {
Expand All @@ -146,7 +147,7 @@ func (ssr *stmtSummaryReader) getStmtByDigestHistoryRow(ssbd *stmtSummaryByDiges
rows := make([][]types.Datum, 0, len(ssElements))
for _, ssElement := range ssElements {
isAuthed := true
if ssr.user != nil && !ssr.isSuper {
if ssr.user != nil && !ssr.hasProcessPriv {
_, isAuthed = ssElement.authUsers[ssr.user.Username]
}
if isAuthed {
Expand Down
12 changes: 6 additions & 6 deletions util/stmtsummary/statement_summary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1418,26 +1418,26 @@ func TestAccessPrivilege(t *testing.T) {

reader := newStmtSummaryReaderForTest(ssMap)
reader.user = user
reader.isSuper = false
reader.hasProcessPriv = false
datums := reader.GetStmtSummaryCurrentRows()
require.Len(t, datums, loops)
reader.user = badUser
reader.isSuper = false
reader.hasProcessPriv = false
datums = reader.GetStmtSummaryCurrentRows()
require.Len(t, datums, 0)
reader.isSuper = true
reader.hasProcessPriv = true
datums = reader.GetStmtSummaryCurrentRows()
require.Len(t, datums, loops)

reader.user = user
reader.isSuper = false
reader.hasProcessPriv = false
datums = reader.GetStmtSummaryHistoryRows()
require.Len(t, datums, loops)
reader.user = badUser
reader.isSuper = false
reader.hasProcessPriv = false
datums = reader.GetStmtSummaryHistoryRows()
require.Len(t, datums, 0)
reader.isSuper = true
reader.hasProcessPriv = true
datums = reader.GetStmtSummaryHistoryRows()
require.Len(t, datums, loops)
}

0 comments on commit 48e12ae

Please sign in to comment.