From fdae90dd11b6f1230f66d530f2d213599f58c760 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Tue, 28 Apr 2015 14:56:55 +0530 Subject: [PATCH] Bug #20181776 :- ACCESS CONTROL DOESN'T MATCH MOST SPECIFIC HOST WHEN IT CONTAINS WILDCARD Description :- Incorrect access privileges are provided to a user due to wrong sorting of users when wildcard characters is present in the hostname. Analysis :- Function "get_sorts()" is used to sort the strings of user name, hostname, database name. It is used to arrange the users in the access privilege matching order. When a user connects, it checks in the sorted user access privilege list and finds a corresponding matching entry for the user. Algorithm used in "get_sort()" sorts the strings inappropriately. As a result, when a user connects to the server, it is mapped to incorrect user access privileges. Algorithm used in "get_sort()" counts the number of characters before the first occurence of any one of the wildcard characters (single-wildcard character '_' or multi-wildcard character '%') and sorts in that order. As a result of inconnect sorting it treats hostname "%" and "%.mysql.com" as equally-specific values and therefore the order is indeterminate. Fix:- The "get_sort()" algorithm has been modified to treat "%" seperately. Now "get_sort()" returns a number which, if sorted in descending order, puts strings in the following order:- * strings with no wildcards * strings containg wildcards and non-wildcard characters * single muilt-wildcard character('%') * empty string. --- sql/sql_acl.cc | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 05a31b85d00..b061a8bc2cf 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -801,7 +801,8 @@ static ulong get_access(TABLE *form, uint fieldnr, uint *next_field) /* Return a number which, if sorted 'desc', puts strings in this order: no wildcards - wildcards + strings containg wildcards and non-wildcard characters + single muilt-wildcard character('%') empty string */ @@ -818,7 +819,16 @@ static ulong get_sort(uint count,...) { char *start, *str= va_arg(args,char*); uint chars= 0; - uint wild_pos= 0; /* first wildcard position */ + uint wild_pos= 0; + + /* + wild_pos + 0 if string is empty + 1 if string is a single muilt-wildcard + character('%') + first wildcard position + 1 if string containg wildcards and + non-wildcard characters + */ if ((start= str)) { @@ -829,6 +839,8 @@ static ulong get_sort(uint count,...) else if (*str == wild_many || *str == wild_one) { wild_pos= (uint) (str - start) + 1; + if (!(wild_pos == 1 && *str == wild_many && *(++str) == '\0')) + wild_pos++; break; } chars= 128; // Marker that chars existed