Skip to content

Commit a9dea9b

Browse files
author
Daniel Blanchard
committed
Bug#35507223 MySQL Server crashes when executing query
ISSUE ===== The expression ~NO_ACCESS was being used to provide an "all access" ACL bitmask. This usage was successful when an ACL bitmask was a 32 bit value, but can cause problems now an ACL bitmask is a 64 bit value (on Linux, not on Windows) as ~NO_ACCESS produces a value with the high order 32 bits set. SOLUTION ======== Make the type of all ACL bitmask variables explicitly 32 bits, by changing the relevant bitmask variable types from ulong to uint32_t. Change-Id: I7abe9ac400490de1d855a23ff5ced1c9124f1453
1 parent 54f13f8 commit a9dea9b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+724
-599
lines changed

mysql-test/r/bug35507223.result

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
CREATE TABLE v0(c1 INT);
2+
CREATE TABLE IF NOT EXISTS v2 ( CHECK ( c1 IN ( SELECT DISTINCT * FROM ( v0 a3 ) CROSS JOIN ( v0 ) ON c1 WHERE c1 ) ) ) TABLE v0 ;
3+
ERROR 23000: Column 'c1' in field list is ambiguous
4+
DROP TABLE v0;

mysql-test/t/bug35507223.test

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CREATE TABLE v0(c1 INT);
2+
# Expect an error
3+
# ERROR: 1052 (23000): Column 'c1' in field list is ambiguous
4+
--error ER_NON_UNIQ_ERROR
5+
CREATE TABLE IF NOT EXISTS v2 ( CHECK ( c1 IN ( SELECT DISTINCT * FROM ( v0 a3 ) CROSS JOIN ( v0 ) ON c1 WHERE c1 ) ) ) TABLE v0 ;
6+
DROP TABLE v0;

sql/auth/acl_table_user.cc

+17-14
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ static std::map<const User_attribute_type, const std::string>
133133

134134
Acl_user_attributes::Acl_user_attributes(MEM_ROOT *mem_root,
135135
bool read_restrictions,
136-
Auth_id &auth_id, ulong global_privs)
136+
Auth_id &auth_id,
137+
Access_bitmask global_privs)
137138
: m_mem_root(mem_root),
138139
m_read_restrictions(read_restrictions),
139140
m_auth_id(auth_id),
@@ -149,7 +150,7 @@ Acl_user_attributes::Acl_user_attributes(MEM_ROOT *mem_root,
149150
Auth_id &auth_id,
150151
Restrictions *restrictions,
151152
I_multi_factor_auth *mfa)
152-
: Acl_user_attributes(mem_root, read_restrictions, auth_id, ~NO_ACCESS) {
153+
: Acl_user_attributes(mem_root, read_restrictions, auth_id, ALL_ACCESS) {
153154
if (restrictions) m_restrictions = *restrictions;
154155
m_mfa = mfa;
155156
}
@@ -176,16 +177,16 @@ bool Acl_user_attributes::consume_user_attributes_json(Json_dom_ptr json) {
176177
}
177178

178179
void Acl_user_attributes::report_and_remove_invalid_db_restrictions(
179-
DB_restrictions &db_restrictions, ulong mask, enum loglevel level,
180+
DB_restrictions &db_restrictions, Access_bitmask mask, enum loglevel level,
180181
ulonglong errcode) {
181182
if (!db_restrictions.is_empty()) {
182183
for (auto &itr : db_restrictions()) {
183-
ulong privs = itr.second;
184+
Access_bitmask privs = itr.second;
184185
if (privs != (privs & mask)) {
185186
std::string invalid_privs;
186187
std::string separator(", ");
187188
bool second = false;
188-
ulong filtered_privs = privs & ~mask;
189+
Access_bitmask filtered_privs = privs & ~mask;
189190
if (filtered_privs)
190191
db_restrictions.remove(itr.first.c_str(), filtered_privs);
191192
while (filtered_privs != 0) {
@@ -461,8 +462,9 @@ Acl_table_user_writer_status::Acl_table_user_writer_status()
461462
methods
462463
*/
463464
Acl_table_user_writer::Acl_table_user_writer(
464-
THD *thd, TABLE *table, LEX_USER *combo, ulong rights, bool revoke_grant,
465-
bool can_create_user, Pod_user_what_to_update what_to_update,
465+
THD *thd, TABLE *table, LEX_USER *combo, Access_bitmask rights,
466+
bool revoke_grant, bool can_create_user,
467+
Pod_user_what_to_update what_to_update,
466468
Restrictions *restrictions = nullptr, I_multi_factor_auth *mfa = nullptr)
467469
: Acl_table(thd, table, acl_table::Acl_table_operation::OP_INSERT),
468470
m_has_user_application_user_metadata(false),
@@ -858,7 +860,7 @@ bool Acl_table_user_writer::update_privileges(
858860
/* Update table columns with new privileges */
859861
const char what = m_revoke_grant ? 'N' : 'Y';
860862
Field **tmp_field;
861-
ulong priv;
863+
Access_bitmask priv;
862864
for (tmp_field = m_table->field + 2, priv = SELECT_ACL;
863865
*tmp_field && (*tmp_field)->real_type() == MYSQL_TYPE_ENUM &&
864866
((Field_enum *)(*tmp_field))->typelib->count == 2;
@@ -885,8 +887,8 @@ bool Acl_table_user_writer::update_privileges(
885887
}
886888

887889
return_value.updated_rights = get_user_privileges();
888-
DBUG_PRINT("info",
889-
("Privileges on disk are now %lu", return_value.updated_rights));
890+
DBUG_PRINT("info", ("Privileges on disk are now %" PRIu32,
891+
return_value.updated_rights));
890892
DBUG_PRINT("info", ("table fields: %d", m_table->s->fields));
891893

892894
return false;
@@ -1300,10 +1302,10 @@ bool Acl_table_user_writer::write_user_attributes_column(
13001302
13011303
@returns Bitmask representing global privileges granted to given account
13021304
*/
1303-
ulong Acl_table_user_writer::get_user_privileges() {
1305+
Access_bitmask Acl_table_user_writer::get_user_privileges() {
13041306
uint next_field;
13051307
char *priv_str;
1306-
ulong rights =
1308+
Access_bitmask rights =
13071309
get_access(m_table, m_table_schema->select_priv_idx(), &next_field);
13081310
if (m_table->s->fields > m_table_schema->drop_role_priv_idx()) {
13091311
priv_str =
@@ -2125,8 +2127,9 @@ Password_lock::Password_lock(Password_lock &&other) {
21252127
processing subsequent user specified in the ACL statement.
21262128
*/
21272129

2128-
int replace_user_table(THD *thd, TABLE *table, LEX_USER *combo, ulong rights,
2129-
bool revoke_grant, bool can_create_user,
2130+
int replace_user_table(THD *thd, TABLE *table, LEX_USER *combo,
2131+
Access_bitmask rights, bool revoke_grant,
2132+
bool can_create_user,
21302133
acl_table::Pod_user_what_to_update &what_to_update,
21312134
Restrictions *restrictions /*= nullptr*/,
21322135
I_multi_factor_auth *mfa /*= nullptr*/) {

sql/auth/acl_table_user.h

+12-10
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class Acl_user_attributes {
9191
Default constructor.
9292
*/
9393
Acl_user_attributes(MEM_ROOT *mem_root, bool read_restrictions,
94-
Auth_id &auth_id, ulong global_privs);
94+
Auth_id &auth_id, Access_bitmask global_privs);
9595

9696
Acl_user_attributes(MEM_ROOT *mem_root, bool read_restrictions,
9797
Auth_id &auth_id, Restrictions *m_restrictions,
@@ -178,8 +178,8 @@ class Acl_user_attributes {
178178

179179
private:
180180
void report_and_remove_invalid_db_restrictions(
181-
DB_restrictions &db_restrictions, ulong mask, enum loglevel level,
182-
ulonglong errcode);
181+
DB_restrictions &db_restrictions, Access_bitmask mask,
182+
enum loglevel level, ulonglong errcode);
183183
bool deserialize_password_lock(const Json_object &json_object);
184184
bool deserialize_multi_factor(const Json_object &json_object);
185185

@@ -195,7 +195,7 @@ class Acl_user_attributes {
195195
/** Restrictions_list on certain databases for user */
196196
Restrictions m_restrictions;
197197
/** Global static privileges */
198-
ulong m_global_privs;
198+
Access_bitmask m_global_privs;
199199
/** password locking */
200200
Password_lock m_password_lock;
201201
/** multi factor auth info */
@@ -215,7 +215,8 @@ using acl_table_user_writer_status =
215215
class Acl_table_user_writer_status {
216216
public:
217217
Acl_table_user_writer_status();
218-
Acl_table_user_writer_status(bool skip, ulong rights, Table_op_error_code err,
218+
Acl_table_user_writer_status(bool skip, Access_bitmask rights,
219+
Table_op_error_code err,
219220
my_timeval pwd_timestamp, std::string cred,
220221
Password_lock &password_lock,
221222
I_multi_factor_auth *multi_factor)
@@ -229,7 +230,7 @@ class Acl_table_user_writer_status {
229230
multi_factor(multi_factor) {}
230231

231232
bool skip_cache_update;
232-
ulong updated_rights;
233+
Access_bitmask updated_rights;
233234
Table_op_error_code error;
234235
my_timeval password_change_timestamp;
235236
std::string second_cred;
@@ -240,8 +241,9 @@ class Acl_table_user_writer_status {
240241

241242
class Acl_table_user_writer : public Acl_table {
242243
public:
243-
Acl_table_user_writer(THD *thd, TABLE *table, LEX_USER *combo, ulong rights,
244-
bool revoke_grant, bool can_create_user,
244+
Acl_table_user_writer(THD *thd, TABLE *table, LEX_USER *combo,
245+
Access_bitmask rights, bool revoke_grant,
246+
bool can_create_user,
245247
Pod_user_what_to_update what_to_update,
246248
Restrictions *restrictions, I_multi_factor_auth *mfa);
247249
~Acl_table_user_writer() override;
@@ -265,15 +267,15 @@ class Acl_table_user_writer : public Acl_table {
265267

266268
void replace_user_application_user_metadata(
267269
std::function<bool(TABLE *table)> const &update);
268-
ulong get_user_privileges();
270+
Access_bitmask get_user_privileges();
269271
std::string get_current_credentials();
270272

271273
private:
272274
bool update_user_application_user_metadata();
273275
bool write_user_attributes_column(const Acl_user_attributes &user_attributes);
274276
bool m_has_user_application_user_metadata;
275277
LEX_USER *m_combo;
276-
ulong m_rights;
278+
Access_bitmask m_rights;
277279
bool m_revoke_grant;
278280
bool m_can_create_user;
279281
Pod_user_what_to_update m_what_to_update;

sql/auth/auth_acls.h

+36-32
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,26 @@
2323
#ifndef AUTH_ACLS_INCLUDED
2424
#define AUTH_ACLS_INCLUDED
2525

26+
#include <cstdint>
2627
#include <string>
2728
#include <unordered_map>
2829
#include <vector>
2930

3031
/* Total Number of ACLs present in mysql.user */
3132
#define NUM_ACLS 31
3233

33-
#define SELECT_ACL (1L << 0)
34-
#define INSERT_ACL (1L << 1)
35-
#define UPDATE_ACL (1L << 2)
36-
#define DELETE_ACL (1L << 3)
37-
#define CREATE_ACL (1L << 4)
38-
#define DROP_ACL (1L << 5)
39-
#define RELOAD_ACL (1L << 6)
40-
#define SHUTDOWN_ACL (1L << 7)
41-
#define PROCESS_ACL (1L << 8)
42-
#define FILE_ACL (1L << 9)
34+
typedef uint32_t Access_bitmask;
35+
36+
#define SELECT_ACL ((Access_bitmask)1 << 0)
37+
#define INSERT_ACL ((Access_bitmask)1 << 1)
38+
#define UPDATE_ACL ((Access_bitmask)1 << 2)
39+
#define DELETE_ACL ((Access_bitmask)1 << 3)
40+
#define CREATE_ACL ((Access_bitmask)1 << 4)
41+
#define DROP_ACL ((Access_bitmask)1 << 5)
42+
#define RELOAD_ACL ((Access_bitmask)1 << 6)
43+
#define SHUTDOWN_ACL ((Access_bitmask)1 << 7)
44+
#define PROCESS_ACL ((Access_bitmask)1 << 8)
45+
#define FILE_ACL ((Access_bitmask)1 << 9)
4346
/** Set to true by both
4447
GRANT GRANT OPTION ... TO ...
4548
and
@@ -58,27 +61,27 @@ and
5861
5962
@sa @ref LEX::grant_privilege
6063
*/
61-
#define GRANT_ACL (1L << 10)
62-
#define REFERENCES_ACL (1L << 11)
63-
#define INDEX_ACL (1L << 12)
64-
#define ALTER_ACL (1L << 13)
65-
#define SHOW_DB_ACL (1L << 14)
66-
#define SUPER_ACL (1L << 15)
67-
#define CREATE_TMP_ACL (1L << 16)
68-
#define LOCK_TABLES_ACL (1L << 17)
69-
#define EXECUTE_ACL (1L << 18)
70-
#define REPL_SLAVE_ACL (1L << 19)
71-
#define REPL_CLIENT_ACL (1L << 20)
72-
#define CREATE_VIEW_ACL (1L << 21)
73-
#define SHOW_VIEW_ACL (1L << 22)
74-
#define CREATE_PROC_ACL (1L << 23)
75-
#define ALTER_PROC_ACL (1L << 24)
76-
#define CREATE_USER_ACL (1L << 25)
77-
#define EVENT_ACL (1L << 26)
78-
#define TRIGGER_ACL (1L << 27)
79-
#define CREATE_TABLESPACE_ACL (1L << 28)
80-
#define CREATE_ROLE_ACL (1L << 29)
81-
#define DROP_ROLE_ACL (1L << 30)
64+
#define GRANT_ACL ((Access_bitmask)1 << 10)
65+
#define REFERENCES_ACL ((Access_bitmask)1 << 11)
66+
#define INDEX_ACL ((Access_bitmask)1 << 12)
67+
#define ALTER_ACL ((Access_bitmask)1 << 13)
68+
#define SHOW_DB_ACL ((Access_bitmask)1 << 14)
69+
#define SUPER_ACL ((Access_bitmask)1 << 15)
70+
#define CREATE_TMP_ACL ((Access_bitmask)1 << 16)
71+
#define LOCK_TABLES_ACL ((Access_bitmask)1 << 17)
72+
#define EXECUTE_ACL ((Access_bitmask)1 << 18)
73+
#define REPL_SLAVE_ACL ((Access_bitmask)1 << 19)
74+
#define REPL_CLIENT_ACL ((Access_bitmask)1 << 20)
75+
#define CREATE_VIEW_ACL ((Access_bitmask)1 << 21)
76+
#define SHOW_VIEW_ACL ((Access_bitmask)1 << 22)
77+
#define CREATE_PROC_ACL ((Access_bitmask)1 << 23)
78+
#define ALTER_PROC_ACL ((Access_bitmask)1 << 24)
79+
#define CREATE_USER_ACL ((Access_bitmask)1 << 25)
80+
#define EVENT_ACL ((Access_bitmask)1 << 26)
81+
#define TRIGGER_ACL ((Access_bitmask)1 << 27)
82+
#define CREATE_TABLESPACE_ACL ((Access_bitmask)1 << 28)
83+
#define CREATE_ROLE_ACL ((Access_bitmask)1 << 29)
84+
#define DROP_ROLE_ACL ((Access_bitmask)1 << 30)
8285
/*
8386
don't forget to update
8487
1. static struct show_privileges_st sys_privileges[]
@@ -89,7 +92,8 @@ and
8992
6. global_privileges map and vector
9093
*/
9194

92-
#define NO_ACCESS (1L << 31)
95+
#define NO_ACCESS ((Access_bitmask)1 << NUM_ACLS)
96+
#define ALL_ACCESS (NO_ACCESS - 1)
9397

9498
/**
9599
Privileges to perform database related operations.

sql/auth/auth_common.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@ const std::string &Auth_id::host() const { return m_host; }
133133
134134
@returns Name for the privilege represented by LSB
135135
*/
136-
std::string get_one_priv(ulong &revoke_privs) {
136+
std::string get_one_priv(Access_bitmask &revoke_privs) {
137137
std::string priv;
138-
ulong lsb;
138+
Access_bitmask lsb;
139139
if (revoke_privs != 0) {
140140
// find out the least significant bit(lsb)
141141
lsb = revoke_privs & ~(revoke_privs - 1);

0 commit comments

Comments
 (0)