infoschema: improve the security vunerability of TABLE_CONSTRAINTS infoschema (#14037)

This commit is contained in:
reafans
2019-12-13 14:26:41 +08:00
committed by wjHuang
parent 78b8865034
commit 71a8ef2bb8
2 changed files with 26 additions and 2 deletions

View File

@ -1706,10 +1706,15 @@ const (
)
// dataForTableConstraints constructs data for table information_schema.constraints.See https://dev.mysql.com/doc/refman/5.7/en/table-constraints-table.html
func dataForTableConstraints(schemas []*model.DBInfo) [][]types.Datum {
func dataForTableConstraints(ctx sessionctx.Context, schemas []*model.DBInfo) [][]types.Datum {
checker := privilege.GetPrivilegeManager(ctx)
var rows [][]types.Datum
for _, schema := range schemas {
for _, tbl := range schema.Tables {
if checker != nil && !checker.RequestVerification(ctx.GetSessionVars().ActiveRoles, schema.Name.L, tbl.Name.L, "", mysql.AllPrivMask) {
continue
}
if tbl.PKIsHandle {
record := types.MakeDatums(
catalogVal, // CONSTRAINT_CATALOG
@ -2346,7 +2351,7 @@ func (it *infoschemaTable) getRows(ctx sessionctx.Context, cols []*table.Column)
case tableSessionVar:
fullRows, err = dataForSessionVar(ctx)
case tableConstraints:
fullRows = dataForTableConstraints(dbs)
fullRows = dataForTableConstraints(ctx, dbs)
case tableFiles:
case tableProfiling:
if v, ok := ctx.GetSessionVars().GetSystemVar("profiling"); ok && variable.TiDBOptOn(v) {

View File

@ -445,6 +445,25 @@ func (s *testTableSuite) TestSomeTables(c *C) {
tk.MustQuery("select * from information_schema.SESSION_VARIABLES where VARIABLE_NAME='tidb_retry_limit';").Check(testkit.Rows("tidb_retry_limit 10"))
tk.MustQuery("select * from information_schema.ENGINES;").Check(testkit.Rows("InnoDB DEFAULT Supports transactions, row-level locking, and foreign keys YES YES YES"))
tk.MustQuery("select * from information_schema.TABLE_CONSTRAINTS where TABLE_NAME='gc_delete_range';").Check(testkit.Rows("def mysql delete_range_index mysql gc_delete_range UNIQUE"))
//test the privilege of new user for information_schema.table_constraints
tk.MustExec("create user constraints_tester")
constraintsTester := testkit.NewTestKit(c, s.store)
constraintsTester.MustExec("use information_schema")
c.Assert(constraintsTester.Se.Auth(&auth.UserIdentity{
Username: "constraints_tester",
Hostname: "127.0.0.1",
}, nil, nil), IsTrue)
constraintsTester.MustQuery("select * from information_schema.TABLE_CONSTRAINTS;").Check([][]interface{}{})
//test the privilege of user with privilege of mysql.gc_delete_range for information_schema.table_constraints
tk.MustExec("CREATE ROLE r_gc_delete_range ;")
tk.MustExec("GRANT ALL PRIVILEGES ON mysql.gc_delete_range TO r_gc_delete_range;")
tk.MustExec("GRANT r_gc_delete_range TO constraints_tester;")
constraintsTester.MustExec("set role r_gc_delete_range")
c.Assert(len(constraintsTester.MustQuery("select * from information_schema.TABLE_CONSTRAINTS where TABLE_NAME='gc_delete_range';").Rows()), Greater, 0)
constraintsTester.MustQuery("select * from information_schema.TABLE_CONSTRAINTS where TABLE_NAME='tables_priv';").Check([][]interface{}{})
tk.MustQuery("select * from information_schema.KEY_COLUMN_USAGE where TABLE_NAME='stats_meta' and COLUMN_NAME='table_id';").Check(
testkit.Rows("def mysql tbl def mysql stats_meta table_id 1 <nil> <nil> <nil> <nil>"))
tk.MustQuery("select * from information_schema.SCHEMATA where schema_name='mysql';").Check(