Bug #1579 Uninitialized data in host access control
Submitted: 16 Oct 2003 14:29 Modified: 11 Dec 2003 6:49
Reporter: Curtis Smith Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S2 (Serious)
Version:4.0.15a OS:Solaris (Solaris 8)
Assigned to: Michael Widenius CPU Architecture:Any

[16 Oct 2003 14:29] Curtis Smith
Description:
In our implemention of the MySQL database access control, we set the database 
to use a host of NULL so that the list of hosts in the host table will control access 
to the database. But beause of uninitialized data, the host table rejects access. 
 
I did not see this behavior in MySQL 4.0.12 probably because of the data assigned 
to the acl_db variable "just happened" to be zero. In MySQL 4.0.15a, some of the 
data in acl_db ended up non-zero. And it may be hard to reproduce on different 
architectures. 
 

How to repeat:
Create a database with db set, user set and host unset (blank or NULL value). Set 
appropriate host table to allow access, including something as simple as a host of 
"%". The reproduction will be depending on if the acl_db variable was allocated 
where ip or ip_mask became garbage. Try testing from a host where access 
should be allowed. 
 
The code where the error occurs is in "sql_acl.cc" at the first "if" statement failing 
to find ip_mask being zero. 
 
static bool compare_hostname(const acl_host_and_ip *host, const char 
*hostname, const char *ip) 
{ 
  long tmp; 
  if (host->ip_mask && ip && calc_ip(ip,&tmp,'\0')) 
  { 
    return (tmp & host->ip_mask) == host->ip; 
  } 
  return (!host->hostname || 
          (hostname && !wild_case_compare(hostname,host->hostname)) || 
          (ip && !wild_compare(ip,host->hostname))); 
} 

Suggested fix:
Add a line at the top to initialize ip and ip_mask just in case hostname comes in 
as a NULL pointer. The code where the error should be fixed is in "sql_acl.cc": 
 
static void update_hostname(acl_host_and_ip *host, const char *hostname) 
{ 
  host->ip=host->ip_mask=0;                     // Initialize (this is new code) 
  host->hostname=(char*) hostname;              // This will not be modified! 
  if (hostname && 
      (!(hostname=calc_ip(hostname,&host->ip,'/')) || 
       !(hostname=calc_ip(hostname+1,&host->ip_mask,'\0')))) 
  { 
    host->ip=host->ip_mask=0;                   // Not a masked ip 
  } 
}
[11 Dec 2003 5:31] MySQL Verification Team
This works fine if host column in db table is empty string or blank.

As documented in our manual, it is not supposed to be NULL.
[11 Dec 2003 6:49] Michael Widenius
Thank you for your bug report. This issue has been committed to our
source repository of that product and will be incorporated into the
next release.

If necessary, you can access the source repository and build the latest
available version, including the bugfix, yourself. More information 
about accessing the source trees is available at
    http://www.mysql.com/doc/en/Installing_source_tree.html

Additional info:

I applied the following patch instead of the suggested one as this is shorter and more efficient

===== sql_acl.cc 1.119 vs edited =====
1205c1205
<   if (hostname &&
---
>   if (!hostname ||

The fix will be in 4.0.17
(The reson for fixing this is that the update_host_name() function can take NULL pointers and should thus work correctly with these even if MySQL doesn't normally have hostnames with NULL)

Regards,
Monty