NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/48808
The following reply was made to PR kern/48808; it has been noted by GNATS.
From: "Thomas Schmitt" <scdbackup%gmx.net@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc:
Subject: Re: kern/48808
Date: Sun, 01 Jun 2014 16:56:46 +0200
--- sys/fs/cd9660/cd9660_extern.h.orig 2013-06-23 07:28:36.000000000 +0000
+++ sys/fs/cd9660/cd9660_extern.h 2014-06-01 13:21:20.000000000 +0000
@@ -72,15 +72,17 @@ struct iso_mnt {
int im_bshift;
int im_bmask;
- int volume_space_size;
+ unsigned int volume_space_size;
char root[ISODCL (157, 190)];
- int root_extent;
- int root_size;
+ unsigned int root_extent;
+ unsigned int root_size;
enum ISO_FTYPE iso_ftype;
int rr_skip;
int rr_skip0;
+
+ unsigned int im_ssector;
};
#define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data))
--- sys/fs/cd9660/cd9660_mount.h.orig 2005-12-03 17:34:43.000000000 +0000
+++ sys/fs/cd9660/cd9660_mount.h 2014-06-01 13:04:55.000000000 +0000
@@ -38,6 +38,8 @@
#ifndef _ISOFS_CD9660_CD9660_MOUNT_H_
#define _ISOFS_CD9660_CD9660_MOUNT_H_
+#include <sys/types.h>
+
/*
* Arguments to mount ISO 9660 filesystems.
*/
@@ -45,6 +47,9 @@ struct iso_args {
const char *fspec; /* block special device to mount */
struct export_args30 _pad1; /* compat with old userland tools */
int flags; /* mounting flags, see below */
+ uint32_t ssector; /* start sector of session,
+ * if flags & ISOFSMNT_SSECTOR
+ */
};
#define ISOFSMNT_NORRIP 0x00000001 /* disable Rock Ridge Ext.*/
#define ISOFSMNT_GENS 0x00000002 /* enable generation numbers
*/
@@ -52,8 +57,30 @@ struct iso_args {
#define ISOFSMNT_NOJOLIET 0x00000008 /* disable Joliet extensions
*/
#define ISOFSMNT_NOCASETRANS 0x00000010 /* do not make names lower
case */
#define ISOFSMNT_RRCASEINS 0x00000020 /* case insensitive Rock
Ridge */
+#define ISOFSMNT_SSECTOR 0x00000040 /* use ssector as session
start */
-#define ISOFSMNT_BITS "\177\20" \
+#define ISOFSMNT_BITS "\177\020" \
"b\00norrip\0b\01gens\0b\02extatt\0b\03nojoliet\0" \
- "b\04nocasetrans\0b\05rrcaseins\0"
+ "b\04nocasetrans\0b\05rrcaseins\0b\06ssector\0\0"
+
+
+/* Compatibility precaution:
+ *
+ * struct old_iso_args_v_1_6 is the definition of struct iso_args before
+ * may 2014. Such structs are still accepted by mount(2) and will be defaulted
+ * to (flags & ~ISOFSMNT_SSECTOR).
+ *
+ * The old struct is exposed here to serve as size benchmark for the reply
+ * of mount(2) with MNT_GETARGS. If after successful mount(2), the inquiry
+ * by MNT_GETARGS yields sizeof(struct old_iso_args_v_1_6) then the
+ * kernel was built with the old struct iso_args. In this case it silently
+ * ignored ISOFSMNT_SSECTOR and iso_args.ssector.
+ * This test can be done only after mounting, because else -1 gets returned.
+ */
+struct old_iso_args_v_1_6 {
+ const char *fspec;
+ struct export_args30 _pad1;
+ int flags;
+};
+
#endif /* _ISOFS_CD9660_CD9660_MOUNT_H_ */
--- sys/fs/cd9660/cd9660_vfsops.c.patch_006 2014-06-01 13:16:27.000000000
+0000
+++ sys/fs/cd9660/cd9660_vfsops.c 2014-06-01 13:04:55.000000000 +0000
@@ -215,21 +215,45 @@ cd9660_mount(struct mount *mp, const cha
struct iso_args *args = data;
int error;
struct iso_mnt *imp = VFSTOISOFS(mp);
+ struct iso_args defaulted_iso_args;
if (args == NULL)
return EINVAL;
- if (*data_len < sizeof *args)
- return EINVAL;
-
+ if (*data_len < sizeof *args) {
+ if (*data_len < sizeof (struct old_iso_args_v_1_6))
+ return EINVAL; /* Too small even for old iso_args */
+ if (!(mp->mnt_flag & MNT_GETARGS)) {
+ /* Upgrade old struct by defaults */
+ args = &defaulted_iso_args;
+ memset(args, 0, sizeof *args);
+ memcpy(args, data, sizeof (struct old_iso_args_v_1_6));
+ args->flags &= ~ISOFSMNT_SSECTOR;
+ printf("cd9660_mount: Upgraded old struct iso_args\n");
+ }
+ }
if (mp->mnt_flag & MNT_GETARGS) {
if (imp == NULL)
return EIO;
args->fspec = NULL;
args->flags = imp->im_flags;
- *data_len = sizeof (*args);
+ if (*data_len >= sizeof *args) {
+ args->ssector = imp->im_ssector;
+ *data_len = sizeof (*args);
+ } else {
+ *data_len = sizeof (struct old_iso_args_v_1_6);
+ }
return 0;
}
+ /* XXX Check for any unknown flags and eventually throw EINVAL ?
+ * This would allow future extensions to fail on old kernels
+ * rather than to be silently ignored, which causes the need
+ * to verify their effectiveness.
+ * See cd9660_mount.h: struct old_iso_args_v_1_6
+ * (One cannot use *data_len as indicator for undue demands.
+ * A newer iso_args may well express old fulfillable wishes.)
+ */
+
if ((mp->mnt_flag & MNT_RDONLY) == 0)
return (EROFS);
@@ -244,7 +268,6 @@ cd9660_mount(struct mount *mp, const cha
NSM_FOLLOW_NOEMULROOT, &devvp);
if (error != 0)
return (error);
-
if (devvp->v_type != VBLK) {
vrele(devvp);
return ENOTBLK;
@@ -277,11 +300,22 @@ cd9660_mount(struct mount *mp, const cha
VOP_UNLOCK(devvp);
/* reference to devvp is donated through iso_mountfs */
} else {
+ if ((imp->im_flags & ISOFSMNT_SSECTOR ? imp->im_ssector : 0) !=
+ (args->flags & ISOFSMNT_SSECTOR ? args->ssector : 0)) {
+ error = EINVAL; /* wish to change superblock */
+ goto fail;
+ }
if (devvp != imp->im_devvp &&
devvp->v_rdev != imp->im_devvp->v_rdev) {
error = EINVAL; /* needs translation */
goto fail;
}
+
+ /* XXX Should not something be done here ?
+ norrip, nojoliet, nomaplcase, ... ?
+ */
+ /* XXX UDF throws EOPNOTSUPP instead of silently ignoring */
+
VOP_UNLOCK(devvp);
vrele(devvp);
}
@@ -345,11 +379,11 @@ iso_mountfs(struct vnode *devvp, struct
int error = EINVAL;
int ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
int iso_bsize;
- int iso_blknum;
+ uint32_t iso_blknum;
int joliet_level;
struct iso_volume_descriptor *vdp;
struct iso_supplementary_descriptor *sup;
- int sess = 0;
+ uint32_t sess = 0;
int ext_attr_length;
struct disklabel label;
@@ -376,12 +410,15 @@ iso_mountfs(struct vnode *devvp, struct
if (error)
sess = 0; /* never mind */
}
+ if (argp->flags & ISOFSMNT_SSECTOR)
+ sess = argp->ssector;
#ifdef ISO_DEBUG
- printf("isofs: session offset (part %"PRId32") %d\n", DISKPART(dev),
sess);
+ printf("isofs: session offset (part %"PRId32") %"PRIu32"\n",
DISKPART(dev), sess);
#endif
for (iso_blknum = 16; iso_blknum < 100; iso_blknum++) {
- if ((error = bread(devvp, (iso_blknum+sess) * btodb(iso_bsize),
+ if ((error = bread(devvp, ((daddr_t) iso_blknum + sess)
+ * btodb(iso_bsize),
iso_bsize, NOCRED, 0, &bp)) != 0)
goto out;
@@ -434,6 +471,8 @@ iso_mountfs(struct vnode *devvp, struct
goto out;
}
+ if (argp->flags & ISOFSMNT_SSECTOR)
+ isomp->im_ssector = argp->ssector;
isomp->volume_space_size += sess;
brelse(pribp, BC_AGE);
@@ -479,7 +518,8 @@ iso_mountfs(struct vnode *devvp, struct
bp = NULL;
}
isomp->im_flags = argp->flags & (ISOFSMNT_NORRIP | ISOFSMNT_GENS |
- ISOFSMNT_EXTATT | ISOFSMNT_NOJOLIET | ISOFSMNT_RRCASEINS);
+ ISOFSMNT_EXTATT | ISOFSMNT_NOJOLIET | ISOFSMNT_NOCASETRANS |
+ ISOFSMNT_RRCASEINS | ISOFSMNT_SSECTOR);
if (isomp->im_flags & ISOFSMNT_GENS)
isomp->iso_ftype = ISO_FTYPE_9660;
Home |
Main Index |
Thread Index |
Old Index