Skip to content

Commit d293bb3

Browse files
craig[bot]gtr
andcommitted
107076: sql: add system privileges to error messages in statement stats tables r=gtr a=gtr Part of cockroachdb#87785. This commit implements the `VIEWACTIVITY` and `VIEWACTIVITYREDACTED` system privileges to the `crdb_internal.node_statement_statistics` table to provide fine-grained permissions to view the error message for failed statements. Release note (sql change): the `crdb_interanal.node_statement_statistics` table redact the error message if the user has `VIEWACTIVITYREDACTED`, and do not redact the error message if the user has `VIEWACTIVITY`. If the user has both, `VIEWACTIVITYREDACTED` takes precedence and the last error is redacted. Co-authored-by: gtr <[email protected]>
2 parents 164c8cb + 6a14da4 commit d293bb3

File tree

11 files changed

+202
-32
lines changed

11 files changed

+202
-32
lines changed

pkg/ccl/logictestccl/tests/3node-tenant/generated_test.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/sql/crdb_internal.go

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1516,12 +1516,24 @@ CREATE TABLE crdb_internal.node_statement_statistics (
15161516
latency_seconds_p99 FLOAT
15171517
)`,
15181518
populate: func(ctx context.Context, p *planner, _ catalog.DatabaseDescriptor, addRow func(...tree.Datum) error) error {
1519-
hasViewActivityOrViewActivityRedacted, err := p.HasViewActivityOrViewActivityRedactedRole(ctx)
1520-
if err != nil {
1519+
shouldRedactError := false
1520+
// Check if the user is admin.
1521+
if isAdmin, err := p.HasAdminRole(ctx); err != nil {
15211522
return err
1522-
}
1523-
if !hasViewActivityOrViewActivityRedacted {
1524-
return noViewActivityOrViewActivityRedactedRoleError(p.User())
1523+
} else if !isAdmin {
1524+
// If the user is not admin, check the individual VIEWACTIVITY and VIEWACTIVITYREDACTED
1525+
// privileges.
1526+
if hasViewActivityRedacted, err := p.HasViewActivityRedacted(ctx); err != nil {
1527+
return err
1528+
} else if hasViewActivityRedacted {
1529+
shouldRedactError = true
1530+
} else if hasViewActivity, err := p.HasViewActivity(ctx); err != nil {
1531+
return err
1532+
} else if !hasViewActivity {
1533+
// If the user is not admin and does not have VIEWACTIVITY or VIEWACTIVITYREDACTED,
1534+
// return insufficient privileges error.
1535+
return noViewActivityOrViewActivityRedactedRoleError(p.User())
1536+
}
15251537
}
15261538

15271539
var alloc tree.DatumAlloc
@@ -1530,8 +1542,12 @@ CREATE TABLE crdb_internal.node_statement_statistics (
15301542

15311543
statementVisitor := func(_ context.Context, stats *appstatspb.CollectedStatementStatistics) error {
15321544
errString := tree.DNull
1533-
if stats.Stats.SensitiveInfo.LastErr != "" {
1534-
errString = alloc.NewDString(tree.DString(stats.Stats.SensitiveInfo.LastErr))
1545+
if shouldRedactError {
1546+
errString = alloc.NewDString(tree.DString("<redacted>"))
1547+
} else {
1548+
if stats.Stats.SensitiveInfo.LastErr != "" {
1549+
errString = alloc.NewDString(tree.DString(stats.Stats.SensitiveInfo.LastErr))
1550+
}
15351551
}
15361552

15371553
errCode := tree.DNull

pkg/sql/logictest/testdata/logic_test/statement_statistics_errors

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,16 @@
66
# by CRDB ("$ internal-migration-manager-find-jobs" for example) since they can be flaky. We are
77
# also ordering by "last_error_code" to maintain consistency.
88

9+
user root
10+
911
# Test 1: division by zero. Error code "22012" should be added.
1012
statement error division by zero
1113
SELECT 2/0;
1214

13-
query T
14-
SELECT last_error_code FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
15+
query TT
16+
SELECT last_error_code, last_error FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
1517
----
16-
22012
18+
22012 division by zero
1719

1820
# Test 2: database does not exist. Error code "3D000" should be added.
1921
query TTTTTT colnames,rowsort
@@ -28,34 +30,34 @@ test root NULL NULL {} NULL
2830
statement error pq: database "posgres" does not exist
2931
use posgres
3032

31-
query T
32-
SELECT last_error_code FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
33+
query TT
34+
SELECT last_error_code, last_error FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
3335
----
34-
22012
35-
3D000
36+
22012 division by zero
37+
3D000 database "posgres" does not exist
3638

3739
# Test 3: Nonexistant user. Error code "42704" should be added.
3840
statement error pq: role/user "who" does not exist
3941
ALTER DEFAULT PRIVILEGES GRANT SELECT ON TABLES to who
4042

41-
query T
42-
SELECT last_error_code FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
43+
query TT
44+
SELECT last_error_code, last_error FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
4345
----
44-
22012
45-
3D000
46-
42704
46+
22012 division by zero
47+
3D000 database "posgres" does not exist
48+
42704 role/user "who" does not exist
4749

4850
# Test 4: Insufficient privilege. Error code "42501" should be added.
4951
statement error schema cannot be modified: "crdb_internal"
5052
CREATE TABLE crdb_internal.example (abc INT)
5153

52-
query T
53-
SELECT last_error_code FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
54+
query TT
55+
SELECT last_error_code, last_error FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
5456
----
55-
22012
56-
3D000
57-
42501
58-
42704
57+
22012 division by zero
58+
3D000 database "posgres" does not exist
59+
42501 schema cannot be modified: "crdb_internal"
60+
42704 role/user "who" does not exist
5961

6062
# Test 5: Foreign key violation. Error code "23503" should be added.
6163
statement ok
@@ -67,11 +69,11 @@ INSERT INTO dst(x) VALUES ('example')
6769
statement error foreign key
6870
UPDATE dst SET x = 'xyz'
6971

70-
query T
71-
SELECT last_error_code FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
72+
query TT
73+
SELECT last_error_code, last_error FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
7274
----
73-
22012
74-
23503
75-
3D000
76-
42501
77-
42704
75+
22012 division by zero
76+
23503 update on table "dst" violates foreign key constraint "dst_x_fkey"
77+
3D000 database "posgres" does not exist
78+
42501 schema cannot be modified: "crdb_internal"
79+
42704 role/user "who" does not exist
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Check that error messages and error codes are being surfaced correctly
2+
#
3+
# For these tests, a statement containing an intentional error is made and the
4+
# crdb_internal.node_statement_statistics virtual table is queried to validate that the error code
5+
# is recorded. When querying the node statistics table, we are ignoring statements made internally
6+
# by CRDB ("$ internal-migration-manager-find-jobs" for example) since they can be flaky. We are
7+
# also ordering by "last_error_code" to maintain consistency. Here we are also testing that the
8+
# error message is redacted for the VIEWACTIVITYREDACTED privilege.
9+
10+
11+
# Grant testuser the VIEWACTIVITYREDACTED system privilege.
12+
statement ok
13+
GRANT SYSTEM VIEWACTIVITYREDACTED TO testuser;
14+
15+
query TTB
16+
SHOW SYSTEM GRANTS
17+
----
18+
testuser VIEWACTIVITYREDACTED false
19+
20+
21+
# Switch to testuser
22+
user testuser
23+
24+
# Test 1: division by zero. Error code "22012" should be added.
25+
statement error division by zero
26+
SELECT 2/0;
27+
28+
query TT
29+
SELECT last_error_code, last_error FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
30+
----
31+
22012 <redacted>
32+
33+
# Test 2: database does not exist. Error code "3D000" should be added.
34+
query TTTTTT colnames,rowsort
35+
SHOW DATABASES
36+
----
37+
database_name owner primary_region secondary_region regions survival_goal
38+
defaultdb root NULL NULL {} NULL
39+
postgres root NULL NULL {} NULL
40+
test root NULL NULL {} NULL
41+
42+
statement error pq: database "posgres" does not exist
43+
use posgres
44+
45+
query TT
46+
SELECT last_error_code, last_error FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
47+
----
48+
22012 <redacted>
49+
3D000 <redacted>
50+
51+
# Test 3: Nonexistant user. Error code "42704" should be added.
52+
statement error pq: role/user "who" does not exist
53+
ALTER DEFAULT PRIVILEGES GRANT SELECT ON TABLES to who
54+
55+
query TT
56+
SELECT last_error_code, last_error FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
57+
----
58+
22012 <redacted>
59+
3D000 <redacted>
60+
42704 <redacted>
61+
62+
# Test 4: Give testuser the VIEWACTIVITY system privilege and remove the VIEWACTIVITYREDACTED privilege.
63+
user root
64+
65+
statement ok
66+
GRANT SYSTEM VIEWACTIVITY TO testuser
67+
68+
statement ok
69+
REVOKE SYSTEM VIEWACTIVITYREDACTED FROM testuser
70+
71+
user testuser
72+
73+
# Now the error message should not be redacted.
74+
75+
query TT
76+
SELECT last_error_code, last_error FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
77+
----
78+
22012 division by zero
79+
3D000 database "posgres" does not exist
80+
42704 role/user "who" does not exist
81+
82+
# Test 5: Give tesuser the VIEWACTIVITYREDACTED privilege again. This time, the error message should be redacted,
83+
# as VIEWACTIVITYREDACTED takes precedence over VIEWACTIVITY.
84+
user root
85+
86+
statement ok
87+
GRANT SYSTEM VIEWACTIVITYREDACTED TO testuser
88+
89+
user testuser
90+
91+
query TT
92+
SELECT last_error_code, last_error FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
93+
----
94+
22012 <redacted>
95+
3D000 <redacted>
96+
42704 <redacted>

pkg/sql/logictest/tests/fakedist-disk/generated_test.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/sql/logictest/tests/fakedist-vec-off/generated_test.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/sql/logictest/tests/fakedist/generated_test.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/sql/logictest/tests/local-legacy-schema-changer/generated_test.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/sql/logictest/tests/local-mixed-22.2-23.1/generated_test.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/sql/logictest/tests/local-vec-off/generated_test.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)