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