Bug #21723 Should be able to dump core after setuid() under Linux

Submitted: 18 Aug 2006 16:37 Modified: 14 May 2018 13:11
Reporter: Dean Ellis Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Options Severity:S4 (Feature request)
Version:5.0, 5.7.11 OS:Linux (Linux)
Assigned to: CPU Architecture:Any
Tags: bfsm_2007_05_31, Contribution

[18 Aug 2006 16:37] Dean Ellis
Description:
In many cases, binaries can no longer dump core after calling setuid().  Under Linux it is possible to re-enable this with a system call.

How to repeat:
n/a

Suggested fix:
===== mysqld.cc 1.565 vs edited =====
--- 1.565/sql/mysqld.cc 2006-08-18 11:34:13 -05:00
+++ edited/mysqld.cc    2006-08-18 11:32:44 -05:00
@@ -64,6 +64,10 @@
 #define ONE_THREAD
 #endif
 
+#ifdef __linux__
+#include <sys/prctl.h>
+#endif
+
 #ifdef HAVE_purify
 #define IF_PURIFY(A,B) (A)
 #else
@@ -1362,6 +1366,10 @@
     sql_perror("setuid");
     unireg_abort(1);
   }
+#ifdef __linux__
+  /* inform kernel that process is dumpable */
+  prctl(PR_SET_DUMPABLE,1,0,0,0);
+#endif /* __linux__ */
 #endif
 }
[18 Aug 2006 20:38] Domas Mituzas
This seems to be more a bug than feature request - --core-file functionality is broken if dumpable flag is not reset after setuid().
[5 Sep 2006 13:42] Sergei Golubchik
I'd rather use HAVE_SYS_PRCTL_H or HAVE_PRCTL instead of __linux__
[5 Sep 2006 13:54] Dean Ellis
Sure.  Should probably also move this to the OPT_WANT_CORE test or to write_core() or similar (only do it if core-file option was specified).
[7 Sep 2006 9:20] Michal Marek
The patch attached to bug#21361 contains a configure check and calls prctl()
only of --core-file is given: http://bugs.mysql.com/file.php?id=4063
[1 Jun 2007 14:34] Sergei Golubchik
no need for a special configure check, it's enough to add sys/prctl.h to AC_CHECK_HEADERS() rule in configure.in. The code becomes:

+#ifdef HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#endif
...
+#ifdef PR_SET_DUMPABLE
+  if (test_flags & TEST_CORE_ON_SIGNAL)
+  {
+    prctl(PR_SET_DUMPABLE, 1);
+  }
+#endif

otherwise ok
[14 Jun 2007 18:25] 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/28795

ChangeSet@1.2479, 2007-06-14 14:24:59-04:00, cmiller@zippy.cornsilk.net +2 -0
  Bug#21723: Should be able to dump core after setuid() under Linux
  
  In many cases, binaries can no longer dump core after calling setuid().
  
  Where the PR_SET_DUMPABLE macro is set, use the prctl() system call 
  to tell the kernel that it's allowed to dump the core of the server.
[16 Jun 2007 4:50] Bugs System
Pushed into 5.0.44
[16 Jun 2007 4:51] Bugs System
Pushed into 5.1.20-beta
[18 Jun 2007 15:58] Paul DuBois
Noted in 5.0.44, 5.1.20 changelogs.

Linux binaries were unable to dump core after executing a setuid()
call.
[30 Sep 2009 9:34] Yoshinori Matsunobu
Hi!

In 5.1, prctl() is called *before* setuid/setgid() so it doesn't work. Please fix. 

----------
  if ((user_info= check_user(mysqld_user)))
  {
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
    if (locked_in_memory) // getuid() == 0 here
      set_effective_user(user_info);
    else
#endif
      set_user(mysqld_user, user_info);
  }
----------

prctl() is called by check_user(), setuid()/setgid() are by set_user(), but prctl() should be called after set_user().
[10 Mar 2010 11:36] Mark Robson
This affects us on 5.1 as well, it is difficult to get it to dump core (a UDF which calls prctl() appears to be the current proposed solution)
[11 Mar 2010 4:19] John Smith
Unable to get produce a core dump as a user "mysql" running:

Ubuntu 8.04.4 LTS
MySQL 5.1.36

Editing /etc/init.d/mysql   and setting user=root  allows a core dump to be created.

How to repeat:

1) set user=mysql

$ ulimit -c unlimited

[mysqld]
core-file

$/etc/init.d/mysql restart

killall -11 mysqld

[ no dump file produced ]

1) set user=root

$/etc/init.d/mysql restart

killall -11 mysqld

core.9447  [ core dump produced ]

Side notes:
---------

/etc/security/limits.conf was configured both as

* hard core 0 
* soft core 0

and

* hard core unlimited
* soft core unlimited

and 

core-file-size = 0
core-file-size = unlimited

were all tried in multiple combinations.  I was not able to get user=mysql to produce a dump.
[11 Mar 2010 17:09] John Smith
Confirmed for 5.0.75-0ubuntu10.3-log
[24 May 2016 4:27] Roel Van de Paar
Status: Open ?
[24 May 2016 11:23] Andrii Nikitin
The problem verified with following steps in source build of 5.7.11 on Oracle Linux 7 :
1. Setup core configuration (as root):
mkdir /tmp/corefiles
chmod 777 /tmp/corefiles
echo "/tmp/corefiles/core" > /proc/sys/kernel/core_pattern
echo "1" > /proc/sys/kernel/core_uses_pid

2. Create my.cnf with only two lines:

[mysqld]
core-file

3.
Initialize two datadir - one for current OS user and second for 'mysql' user:

[root sql]# mkdir /data1
[root sql]# mkdir /data2
[root sql]# chmod 777 /data1
[root sql]# chmod 777 /data2

[anikitin sql]$ ./mysqld --defaults-file=../my.cnf --initialize-insecure --basedir=.. --datadir=/data1
[anikitin sql]$ sudo ./mysqld --defaults-file=../my.cnf --initialize-insecure --basedir=.. --datadir=/data2 --user=mysql 

4. 
Start instances and make sure that second one did change user from root:
[anikitin sql]$ ./mysqld --defaults-file=../my.cnf --basedir=.. --datadir=/data1 --socket=/data1/mysql.sock &
[anikitin sql]$ sudo ./mysqld --defaults-file=../my.cnf --basedir=.. --datadir=/data2 --socket=/data2/mysql.sock --user=mysql --port=3307 &

[root sql]# top -cbn1 | grep mysqld
 5046 anikitin  20   0 2448716 175196   6584 S   0.0  1.1   0:00.22 ./mysqld --defaults-file=../my.cnf --basedir=.. --datadir=/data1 --socket=/data1/mysql.sock
 5136 mysql     20   0 2450800 176440   6488 S   0.0  1.1   0:00.20 ./mysqld --defaults-file=../my.cnf --basedir=.. --datadir=/data2 --socket=/data2/mysql.sock --user=mys+

5.
Make sure size of core file is not limited for the processes:
[anikitin sql]$ cat /proc/5406/limits | grep core
Max core file size        unlimited            unlimited            bytes

[anikitin sql]$ cat /proc/5136/limits | grep core
Max core file size        unlimited            unlimited            bytes

6. 
Attempt to kill the processes and observe that only first one did generate core dump:
[root sql]# kill -11 5136
[root sql]# kill -11 5046
[root sql]# ls -la /tmp/corefiles/
total 1091288
drwxrwxrwx.  2 root     root             84 May 24 12:10 .
drwxrwxrwt. 33 root     root           4096 May 24 12:10 ..
-rw-------.  1 anikitin anikitin 1253367808 May 24 12:10 core.5046

Conclusion:
Since core file was generated only for first instance - the bug is not fixed. Putting to 'Verified'.

Bonus:
Retry the same with suid_dumpable=2  - and core file gets generated:
[root sql]# echo 2 > /proc/sys/fs/suid_dumpable

[anikitin sql]$ sudo ./mysqld --defaults-file=../my.cnf --basedir=.. --datadir=/data2 --socket=/data2/mysql.sock --user=mysql --port=3307 &

[root sql]# top -cbn1 | grep mysqld
 6409 mysql     20   0 2450800 171448   6524 S   0.0  1.0   0:00.21 ./mysqld --defaults-file=../my.cnf --basedir=.. --datadir=/data2 --socket=/data2/mysql.+
[root sql]# kill -11 6409
[root@anikitin7 sql]# ls -la /tmp/corefiles/
total 1358016
drwxrwxrwx.  2 root     root            100 May 24 13:04 .
drwxrwxrwt. 34 root     root           4096 May 24 13:04 ..
-rw-------.  1 anikitin anikitin 1253367808 May 24 12:10 core.5046
-rw-------.  1 root     mysql    1253367808 May 24 13:04 core.6409

Final conclusion:
While the bug is formally not fixed - documentation states "There might be additional restrictions or limitations." 
So, considering well known in community workaround with 'suid_dumpable' - I am leaving this as 'Verified' 'Feature request'.
[1 Jun 2016 0:36] Mark Callaghan
FB MySQL has the fix. People I trust claim upstream MySQL is still broken.
https://github.com/facebook/mysql-5.6/commit/ebb204ce3bf20734e3e5a7cfb8006bbf9bebe8cc
[4 Jun 2016 9:59] Andrii Nikitin
Unfortunately I am not allowed to verify the bug if I don't have exact steps which demonstrate that the problem really exists. 
E.g. more details about environment where mentioned workaround doesn't help or explanation why mentioned workaround is a bad practice.
[30 Apr 2018 17:27] Paul DuBois
This bug was fixed in 8.0 by Bug#90642.
[14 May 2018 12:54] Tor Didriksen
Posted by developer:
 
Fixed by patch for:
https://bugs.mysql.com/bug.php?id=90642
[14 May 2018 13:11] Paul DuBois
Posted by developer:
 
Fixed in 8.0.12.

Linux binaries were unable to dump core after executing a setuid()
call.

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.050 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.