NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/48787: 32 bit rollover makes ISO multi-session medium unusable via mount

>Number:         48787
>Category:       kern
>Synopsis:       32 bit rollover makes ISO multi-session medium unusable via 
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue May 06 14:15:00 +0000 2014
>Originator:     Thomas Schmitt
>Release:        6.1.3
NetBSD netbsd 6.1.3 NetBSD 6.1.3 (GENERIC) i386
This bug shows up when mounting a multi-session ISO 9660 medium
which has its directory tree above 4 GiB. (Not possible with CD,
but with DVD or BD.)

  netbsd# mount -t cd9660 /dev/cd0a /mnt
  netbsd# ls -l /mnt
  -r-xr-xr-x  1 root  wheel  0 Jan  1  1970 /mnt
  netbsd# umount /mnt
  umount: /mnt: Invalid argument
  netbsd# umount /dev/cd0a
  umount: /mnt: Invalid argument
  netbsd# mount
  /dev/wd0a on / type ffs (local)
  kernfs on /kern type kernfs (local)
  ptyfs on /dev/pts type ptyfs (local)
  procfs on /proc type procfs (local)
  /dev/cd0a on /mnt type cd9660 (read-only, local)
I can get rid of the mount point only by reboot.

It does not happen with

  mount -t cd9660 -o norrip /dev/cd0a /mnt

To my assessment it is caused by a 32 bit rollover in
which leads to a wrong reverse computed block address of the
directory extent in sys/fs/cd9660/cd9660_vfsops.c line 815:
                ip->iso_start = ino >> imp->im_bshift;

Although sizeof(ino_t) == 8, the computation in isodirino() rolls over
at least on NetBSD i386 because none of the operands of the computation
is 64 bit wide.

A test in userspace confirms:

  sizeof(ino_t) = 8
  ( 2113952 + 0 ) << 11 = 34406400
  ( ((uint64_t) 2113952) + 0 ) << 11 = 4329373696

Fixing the rollover makes the ISO mountable and umount-able.
Inode numbers above (2 exp 32 - 1) are shown rolled-over by ls -i

  34445556 -rw-r--r--  1 thomas  dbus         396 Aug 26  2011

Create an appendable ISO 9660 DVD or BD with more than 4 GiB of data.
Then add another ISO session, eject, load, and mount the medium.

Or create such a multi-session ISO 9660 image and submit it to 
a qemu-based NetBSD as -cdrom. This will be handled much like a 
DVD+RW or BD-RE medium.

Programs which create such ISO media or images are growisofs out
of package dvd+rw-tools, or xorriso out of package libisoburn,
which was added to pkgsrc a few days ago.

Inject a (uint64_t) cast into the computation of isodirino().

Home | Main Index | Thread Index | Old Index