christos@ wrote: > On Jul 5, 3:37am, tsut...@ceres.dti.ne.jp (Izumi Tsutsui) wrote: > -- Subject: Re: CVS commit: src/sys/fs/msdosfs > > | > Well, I am not sure if KASSERT() is the best solution here. But > | > what else can we do? I agree that there should be at least a > | > warning. > | > | Check > | (secsize != 0 && secsize <= MAXBSIZE && powerof2(secsize) && numsec > 0) > | in getdisksize() and return ENXIO if it fails? > | It looks callers of getdisksize() check a returned error value > | so they will also fail properly (refusing mountfs etc.), > | even without a diagnostic warning. > > Perhaps print a diagnostic, return -1 with EINVAL so that we know which > driver failed?
getdisksize() returns error from ioctl's directly. (because it's a kernel function?) How about this dumb patch? --- Index: subr_disk_open.c =================================================================== RCS file: /cvsroot/src/sys/kern/subr_disk_open.c,v retrieving revision 1.8 diff -u -p -r1.8 subr_disk_open.c --- subr_disk_open.c 27 Apr 2012 18:15:55 -0000 1.8 +++ subr_disk_open.c 6 Jul 2012 12:51:34 -0000 @@ -89,28 +89,42 @@ opendisk(struct device *dv) } int -getdisksize(struct vnode *vp, uint64_t *numsecp, unsigned *secsizep) +getdisksize(struct vnode *vp, uint64_t *numsecp, unsigned int *secsizep) { struct partinfo dpart; struct dkwedge_info dkw; struct disk *pdk; + unsigned int secsize; + uint64_t numsec; int error; error = VOP_IOCTL(vp, DIOCGPART, &dpart, FREAD, NOCRED); if (error == 0) { - *secsizep = dpart.disklab->d_secsize; - *numsecp = dpart.part->p_size; - return 0; + secsize = dpart.disklab->d_secsize; + numsec = dpart.part->p_size; + } else { + error = VOP_IOCTL(vp, DIOCGWEDGEINFO, &dkw, FREAD, NOCRED); + if (error == 0) { + pdk = disk_find(dkw.dkw_parent); + if (pdk != NULL) { + secsize = DEV_BSIZE << pdk->dk_blkshift; + numsec = dkw.dkw_size; + } else + error = ENODEV; + } } - error = VOP_IOCTL(vp, DIOCGWEDGEINFO, &dkw, FREAD, NOCRED); - if (error == 0) { - pdk = disk_find(dkw.dkw_parent); - if (pdk != NULL) { - *secsizep = DEV_BSIZE << pdk->dk_blkshift; - *numsecp = dkw.dkw_size; - } else - error = ENODEV; + if (error == 0 && + (secsize == 0 || secsize > MAXBSIZE || !powerof2(secsize) || + numsec == 0)) { +#ifdef DIAGNOSTIC + printf("%s: %s returns invalid disksize values" + " (secsize = %u, numsec = %" PRIu64 ")\n", + __func__, + devsw_blk2name(major(vp->v_specnode->sn_rdev)), + secsize, numsec); +#endif + error = EINVAL; } return error; --- Izumi Tsutsui