2.6.31 - sequence of chroot calls makes filesystem unmountable

From: Richard W.M. Jones
Date: Mon Jun 22 2009 - 15:46:59 EST


I discovered an odd bug in 2.6.31 (from Fedora Rawhide which is mostly
tracking git). A sequence of chroot() and open() syscalls executed as
root can make a filesystem unmountable.

Test program below, along with a wrapper script.

The filesystem stays unmountable even after the program & script exit.
'lsof' and 'fuser' don't show anything holding the filesystem open.

Some sample output is here:
https://bugzilla.redhat.com/show_bug.cgi?id=507066#c10

Rich.

Save as /tmp/test.c
Compile: gcc -Wall -o /tmp/test /tmp/test.c
----------------------------------------------------------------------
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

int
main (int argc, char *argv[])
{
int fd, r;

if (chdir ("/") == -1) {
perror ("chdir");
exit (1);
}

if (chroot ("/tmp/mnt") == -1) {
perror ("chroot#1");
exit (1);
}
fd = open ("/hello", O_WRONLY|O_CREAT|O_NOCTTY, 0666);
if (fd == -1) {
perror ("open");
exit (1);
}
if (chroot (".") == -1) {
perror ("chroot#2");
exit (1);
}
if (close (fd) == -1) {
perror ("close");
exit (1);
}

r = system ("umount /tmp/mnt");
if (r == -1 || WEXITSTATUS(r) != 0) {
fprintf (stderr, "umount failed\n");
exit (1);
}

exit (0);
}
----------------------------------------------------------------------


Wrapper script (/tmp/test.sh)
----------------------------------------------------------------------
#!/bin/sh -

set -e

dd if=/dev/zero of=/tmp/fs bs=1024k count=10
/sbin/mkfs.ext2 -F /tmp/fs

rm -rf /tmp/mnt
mkdir /tmp/mnt

mount -o loop /tmp/fs /tmp/mnt

/tmp/test

echo Finished test successfully.
----------------------------------------------------------------------

--
Richard Jones, Emerging Technologies, Red Hat http://et.redhat.com/~rjones
virt-p2v converts physical machines to virtual machines. Boot with a
live CD or over the network (PXE) and turn machines into Xen guests.
http://et.redhat.com/~rjones/virt-p2v
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/