Public bug reported:

fstype, from klibc-utils, is used in the Ubuntu initrd to determine the
type of the root filesystem before it can be mounted. Unfortunately the
method fstype uses to determine the filesystem type is not all that
rigorous, and can be easily fooled into misidentifying the filesystem
type.

I have seen this cause at least one box to fail at boot, however any
machine with an ext3 root filesystem is vulnerable, it merely depends on
the free inode count.

eg:

# dd if=/dev/zero of=ext3.img bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.267534 seconds, 392 MB/s
# losetup /dev/loop0 ext3.img
# mke2fs -j /dev/loop0
mke2fs 1.38 (30-Jun-2005)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
25688 inodes, 102400 blocks
5120 blocks (5.00%) reserved for the super user
...
# mkdir mnt
# /usr/lib/klibc/bin/fstype ext3.img
FSTYPE=ext3
FSSIZE=102400
# mount -t ext3 /dev/loop0 mnt/
# df -i mnt/
Filesystem            Inodes   IUsed   IFree IUse% Mounted on
/dev/loop0             25688      11   25677    1% /home/michael/fstype/mnt
# cd mnt/
# typeset -i i=0
# while [[ $i -lt 20670 ]]
> do
>       touch file-$i
>       i=$i+1
> done
# df -i mnt/
Filesystem            Inodes   IUsed   IFree IUse% Mounted on
/dev/loop0             25688   20681    5007   81% /home/michael/fstype/mnt
# umount mnt
# /usr/lib/klibc/bin/fstype ext3.img
FSTYPE=minix
FSSIZE=0


The relevant code from fstype is:

static int minix_image(const unsigned char *buf, unsigned long *blocks)
{
        const struct minix_super_block *sb =
                (const struct minix_super_block *)buf;

        if (sb->s_magic == MINIX_SUPER_MAGIC ||
            sb->s_magic == MINIX_SUPER_MAGIC2) {
 ...

minix_super_block->s_magic corresponds to the same location on disk as
ext3_super_block->s_free_inodes_count.

So if s_free_inodes_count & 0xffff == 0x138f or 0x137f, fstype will
think it's minix.

There doesn't seem to be a good solution, if the checks were reversed
then it might erroneously report a minix filesystem as being ext3.
However given the relative popularity of the two filesystems, it would
seem that would be a lesser evil.

** Affects: Ubuntu
     Importance: Untriaged
         Status: Unconfirmed

** Description changed:

  fstype, from klibc-utils, is used in the Ubuntu initrd to determine the
  type of the root filesystem before it can be mounted. Unfortunately the
  method fstype uses to determine the filesystem type is not all that
  rigorous, and can be easily fooled into misidentifying the filesystem
  type.
  
  I have seen this cause at least one box to fail at boot, however any
  machine with an ext3 root filesystem is vulnerable, it merely depends on
  the free inode count.
  
  eg:
  
  # dd if=/dev/zero of=ext3.img bs=1M count=100
  100+0 records in
  100+0 records out
  104857600 bytes (105 MB) copied, 0.267534 seconds, 392 MB/s
  # losetup /dev/loop0 ext3.img
  # mke2fs -j /dev/loop0
  mke2fs 1.38 (30-Jun-2005)
  Filesystem label=
  OS type: Linux
  Block size=1024 (log=0)
  Fragment size=1024 (log=0)
  25688 inodes, 102400 blocks
  5120 blocks (5.00%) reserved for the super user
  ...
  # mkdir mnt
  # /usr/lib/klibc/bin/fstype ext3.img
  FSTYPE=ext3
  FSSIZE=102400
  # mount -t ext3 /dev/loop0 mnt/
  # df -i mnt/
  Filesystem            Inodes   IUsed   IFree IUse% Mounted on
  /dev/loop0             25688      11   25677    1% /home/michael/fstype/mnt
  # cd mnt/
  # typeset -i i=0
  # while [[ $i -lt 20670 ]]
  > do
  >       touch file-$i
  >       i=$i+1
  > done
  # df -i mnt/
  Filesystem            Inodes   IUsed   IFree IUse% Mounted on
  /dev/loop0             25688   20681    5007   81% /home/michael/fstype/mnt
  # umount mnt
  # /usr/lib/klibc/bin/fstype ext3.img
  FSTYPE=minix
  FSSIZE=0
  
  
  The relevant code from fstype is:
  
  static int minix_image(const unsigned char *buf, unsigned long *blocks)
  {
          const struct minix_super_block *sb =
                  (const struct minix_super_block *)buf;
  
          if (sb->s_magic == MINIX_SUPER_MAGIC ||
              sb->s_magic == MINIX_SUPER_MAGIC2) {
   ...
  
  minix_super_block->s_magic corresponds to the same location on disk as
  ext3_super_block->s_free_inodes_count.
  
  So if s_free_inodes_count & 0xffff == 0x138f or 0x137f, fstype will
  think it's minix.
  
  There doesn't seem to be a good solution, if the checks were reversed
  then it might erroneously report a minix filesystem as being ext3.
  However given the relative popularity of the two filesystems, it would
  seem that would be a lesser evil.
- 
- This patch would do that:
- === modified file 'utils/fstype.c'
- --- utils/fstype.c      2006-09-20 05:29:13 +0000
- +++ utils/fstype.c      2006-09-20 05:29:20 +0000
- @@ -206,9 +206,9 @@
-         { 0,    "cramfs",       cramfs_image    },
-         { 0,    "romfs",        romfs_image     },
-         { 0,    "xfs",          xfs_image       },
- -       { 1,    "minix",        minix_image     },
-         { 1,    "ext3",         ext3_image      },
-         { 1,    "ext2",         ext2_image      },
- +       { 1,    "minix",        minix_image     },
-         { 8,    "reiserfs",     reiserfs_image  },
-         { 64,   "reiserfs",     reiserfs_image  },
-         { 32,   "jfs",          jfs_image       }

-- 
Machine won't boot because fstype misidentifies ext3 filesystem as minix
https://launchpad.net/bugs/61361

-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to