Bug #9244 Provide better support for chroot=...
Submitted: 17 Mar 2005 8:17 Modified: 5 Dec 2007 18:55
Reporter: Jürgen Kreileder Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: General Severity:S4 (Feature request)
Version:4.1.10a OS:Linux (Debian Linux)
Assigned to: CPU Architecture:Any

[17 Mar 2005 8:17] Jürgen Kreileder
Description:
I'm currently chrooting mysqld via 'chroot=/srv/mysql' in my.cnf.  This works fine, but only if I copy some libraries into the chroot:

    pushd $CHROOT_DIR > /dev/null
    # for reading etc/passwd and etc/hosts
    cp /lib/libnss_compat.so.2 lib
    cp /lib/libnss_files.so.2 lib

    # needed only when compiled with --with-mysqld-ldflags=-all-static
    cp /lib/libc.so.6 lib
    cp /lib/ld* lib

(Full chrooting setup available on http://blog.blackdown.de/2005/03/04/chrooting-mysql-on-debian/ )

It would be nice if chrooting worked without copying any libraries into the chroot.  Both Apache (via mod_chroot or mod_security) and bind9 manage to change the user in the chroot without having any libraries and /etc/passwd in the chroot.

It shouldn't be hard to implement this for mysqld.cc too, just do all user lookup stuff (ie. getpwuid(3), getpwnam(3), ...) before calling chroot(2) (currently it's the other way round).
src/mysqld.cc is a huge file and I probably don't know enough about the code flow, so this change should be implemented by someone more competent.

How to repeat:
* Setup a chroot with just the databases in it
* Start mysqld with chroot=...
=> mysqld can't change the user, because there's no etc/passwd and no /lib/libnss_files.so.2 (needed for lookups in etc/passwd) in the chroot

Suggested fix:
Call getpwnam(3) and friends before chroot(2).
[17 Mar 2005 8:18] Jürgen Kreileder
Changed category to MySQL Server
[28 May 2005 23:02] sean finney
hi,

just to add a little debian-specific information on this, it was originally reported as bug #299265 in the debian BTS.  since then, we've had a second bug reported (#310605), which i think has much of the same desire.

both of these bugs are tagged as upstream and forwarded, referencing this bug report.  i'll go ahead and subscribe to this bug so if/when it's closed i'll know to update the debian changelog and BTS.
[28 May 2005 23:07] sean finney
here's the text from the second bug report:

On Tue, May 24, 2005 at 08:56:45AM -0700, Stephen Gildea wrote:
> Package: mysql-server
> Version: 4.0.24-5
>
> I have some suggestions to make it easier to use mysqld's "chroot"
> feature.  As with the setuid call, the chroot call must be carefully
> positioned in the server's initialization sequence.  The current
> placement of the chroot call makes it hard to use.
>
> By moving some of the file-accessing initialization before the chroot,
> fewer system files need to be copied into the chroot area, making set-up
> easier and more portable.  Also, the external behavior of mysqld would
> be more like the behavior without chroot.
>
> Three initialization operations that could be moved before the chroot:
>
> 1.  Determining the numeric UID and GID to use for our process.  The
>     user/group name to number translation is complicated and opens many
>     system files.  Library calls such as initgroups(), getpwnam(),
>     and getpwuid() may load shared libraries and files in /etc such as
>     /etc/passwd, /etc/group, and /etc/nsswitch.conf.
>
>     Once we have the numbers, the setuid and setgid calls themselves
>     should not be moved, of course, as they must happen after binding
>     the TCP listening socket.
>
>     Because the initgroups function both determines the numeric groups
>     to use and also sets them, it should be replaced with getgrouplist
>     (before the chroot) and setgroups (after the chroot).
>
> 2.  Writing the .pid file.  It is simplest to leave this where it is and
>     have agreement on its location between the daemon, the config files,
>     and the scripts.
>
> 3.  Opening the Unix socket.  Again, it is most convenient to not change
>     the location of this socket in the file system.  This is probably
>     the most important change to make.
>
>     Note that the opening of the TCP/IP listener socket can continue to
>     happen after the chroot.
>
> Note that all these changes are separable, and doing any of them would
> make chroot easier to use even if not all of the changes were done.
>
> It looks to me like the affected code is in sql/mysqld.cc.
> These comments apply to MySQL 4.0.24 and 4.1.11.
>
>  < Stephen
[10 Jul 2005 6:28] Aleksey Kishkin
Hi! just checked against mysql 4.1.12-standard (static binaries, from dev.mysql.com) and mysql in chroot environment worked without any additional libraries (i mean without /lib/libnss_compat.so.2  and /lib/libnss_files.so.2). Could you please to check if mysql from dev.mysql.com wotks properly on your computer?
[10 Jul 2005 10:39] Jürgen Kreileder
Yes, 4.1.12-standard works without resolver libraries in the chroot but it still needs passwd in the chroot.

The problem still exists, though. There are no source changes that could fix it.  4.1.12-standard just seems to work around it by linking the resolver libraries statically (which should not be done even for otherwise statically linked binaries according to the glibc developers).

Dynamically linked builds and statically linked builds that use the dynamic resolver libraries still fail when the resolver libraries are not available in the chroot.
As said in the original report: All passwd and host lookups should be done before chrooting in sql/mysqld.cc.