NetBSD Problem Report #48799
From www@NetBSD.org Sat May 10 21:48:47 2014
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
(using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits))
(Client CN "mail.netbsd.org", Issuer "Postmaster NetBSD.org" (verified OK))
by mollari.NetBSD.org (Postfix) with ESMTPS id F24CAA5813
for <gnats-bugs@gnats.NetBSD.org>; Sat, 10 May 2014 21:48:46 +0000 (UTC)
Message-Id: <20140510214845.9634EA5854@mollari.NetBSD.org>
Date: Sat, 10 May 2014 21:48:45 +0000 (UTC)
From: scdbackup@gmx.net
Reply-To: scdbackup@gmx.net
To: gnats-bugs@NetBSD.org
Subject: 32 bit ino_t bottleneck in interface of cd9660 to vfsops sabotages NFS
X-Send-Pr-Version: www-1.0
>Number: 48799
>Category: kern
>Synopsis: 32 bit ino_t bottleneck in interface of cd9660 to vfsops sabotages NFS
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat May 10 21:50:00 +0000 2014
>Closed-Date: Wed May 14 06:33:09 +0000 2014
>Last-Modified: Wed May 14 06:33:09 +0000 2014
>Originator: Thomas Schmitt
>Release: 6.1.3
>Organization:
>Environment:
NetBSD netbsd 6.1.3 NetBSD 6.1.3 (GENERIC) i386
>Description:
During my assessment of the relation between struct iso_node and
ISO 9660 File Sections, i came to the definition of the cd9660
version of vsops struct fid.
struct ifid is declared in cd9660_vfsops.c with comment
"File handle to vnode":
struct ifid {
ushort ifid_len;
ushort ifid_pad;
int ifid_ino;
long ifid_start;
};
Function cd9660_vptofh() copies this struct over a struct fid
which is provided by the caller.
Before this copying ifid_ino gets filled with the lower 32 bit of
an ino_t value (ip is a struct iso_node, ip->i_number is ino_t):
ifh.ifid_ino = ip->i_number;
The higher bits are thrown away, obviously.
Function cd9660_fhtovp() copies such bytes back from struct fid
into a local struct ifid and uses .ifid_ino with
if ((error = VFS_VGET(mp, ifh.ifid_ino, &nvp)) != 0) {
VFS_VGET to my assessment is actually function cd9660_vget_internal().
It uses cd9660_ihashget() to look up a vnode.
man 9 vfsops mentions that VFS_FHTOVP is related to NFS.
Taylor R Campbell on tech-kern teached me how to get an NFS
server running.
The attempt to produce the problem shows a sufficiently
undesirable result.
>How-To-Repeat:
Test ISO is
http://scdbackup.webframe.org/large.iso.bz2
4470 bytes, MD5 7d78dc3efaec8ea3f1801335329f410d.
It inflates to 4,329,897,984 bytes.
Do this only if the fix of kern/48787 is applied.
If not, you will not get rid of the /mnt/iso mount point until reboot !
If the ISO is submitted as /dev/cd0, do:
mount_cd9660 /dev/cd0a /mnt/iso
mount_nfs localhost:/mnt/iso /mnt/nfs
Situation afterwards:
netbsd# mount
...
/dev/cd0a on /mnt/iso type cd9660 (read-only, NFS exported, local)
localhost:/mnt/iso on /mnt/nfs type nfs
netbsd# ls -l /mnt/nfs
-r-xr-xr-x 1 root wheel 0 Jan 1 1970 /mnt/nfs
Other than with kern/48787, it is possible to umount /mnt/nfs.
After the fix, expect
netbsd# ls -l /mnt/nfs
total 4
drwxr-xr-x 1 thomas dbus 2048 May 6 15:30 my
-rw-r--r-- 1 thomas dbus 6 May 6 15:34 small_file
>Fix:
Changing the type of .ifid_ino to ino_t fixes the problem.
>Release-Note:
>Audit-Trail:
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48799
Date: Sun, 11 May 2014 00:01:36 +0200
--- sys/fs/cd9660/cd9660_vfsops.c.orig 2014-04-16 18:55:18.000000000 +0000
+++ sys/fs/cd9660/cd9660_vfsops.c 2014-05-10 21:19:52.000000000 +0000
@@ -641,7 +641,7 @@ cd9660_sync(struct mount *mp, int waitfo
struct ifid {
ushort ifid_len;
ushort ifid_pad;
- int ifid_ino;
+ ino_t ifid_ino;
long ifid_start;
};
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48799
Date: Sun, 11 May 2014 12:17:19 +0200
After finishing my assessment of struct ifid.ifid_start,
i now understand better the remark of Taylor R Campbell in
http://mail-index.netbsd.org/tech-kern/2014/05/10/msg017044.html
"The ifid_start field seems to be unused, incidentally,
so we needn't even expand the size of cd9660 file handles."
I had the wrong impression that struct fid would be a maximum
sized wrapper, like a union. But now i see the size inquiry
protocol of VFS_VPTOFH(,fh_size).
So i will update my patch by a few ifdefs which exclude the
member .ifid_start from struct ifid by default.
For completeness, i also quote Taylor's other remark:
"As an aside, it seems from glancing at struct ufid in ufs/ufs/inode.h
that UFS will have a similar 32-bit overflow problem."
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48799
Date: Sun, 11 May 2014 12:22:32 +0200
--- sys/fs/cd9660/cd9660_vfsops.c.orig 2014-04-16 18:55:18.000000000 +0000
+++ sys/fs/cd9660/cd9660_vfsops.c 2014-05-11 10:02:49.000000000 +0000
@@ -641,8 +641,12 @@ cd9660_sync(struct mount *mp, int waitfo
struct ifid {
ushort ifid_len;
ushort ifid_pad;
- int ifid_ino;
+ ino_t ifid_ino;
+
+#ifdef ISOFS_DBG
long ifid_start;
+#endif
+
};
/* ARGSUSED */
@@ -792,6 +796,7 @@ cd9660_vget_internal(struct mount *mp, i
}
#if 0
+#ifdef ISOFS_DBG
if (isonum_733(isodir->extent) +
isonum_711(isodir->ext_attr_length) != ifhp->ifid_start) {
if (bp != 0)
@@ -801,6 +806,7 @@ cd9660_vget_internal(struct mount *mp, i
ifhp->ifid_start);
return (ESTALE);
}
+#endif /* ISOFS_DBG */
#endif
} else
bp = 0;
@@ -914,7 +920,11 @@ cd9660_vptofh(struct vnode *vp, struct f
memset(&ifh, 0, sizeof(ifh));
ifh.ifid_len = sizeof(struct ifid);
ifh.ifid_ino = ip->i_number;
+
+#ifdef ISOFS_DBG
ifh.ifid_start = ip->iso_start;
+#endif
+
memcpy(fhp, &ifh, sizeof(ifh));
#ifdef ISOFS_DBG
From: "Martin Husemann" <martin@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/48799 CVS commit: src/sys/fs/cd9660
Date: Tue, 13 May 2014 17:05:26 +0000
Module Name: src
Committed By: martin
Date: Tue May 13 17:05:26 UTC 2014
Modified Files:
src/sys/fs/cd9660: cd9660_vfsops.c
Log Message:
PR kern/48799: make filehandles properly use 64bit inodes on CD9660 file
systems. Patch from Thomas Schmitt, with slight modifications.
To generate a diff of this commit:
cvs rdiff -u -r1.84 -r1.85 src/sys/fs/cd9660/cd9660_vfsops.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->closed
State-Changed-By: martin@NetBSD.org
State-Changed-When: Wed, 14 May 2014 06:33:09 +0000
State-Changed-Why:
Fixed, thanks for the patch!
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.