Add missing NULL check in physio().

When destroying a character device the si_devsw field is set to NULL
before all references are gone, to indicate the character device is
going away. This can cause a NULL-dereference fault inside physio().

The callers of physio() should own a thread reference on the cdev and
if si_devsw is seen as non-NULL, it is usable during the execution of
the function. Else an ENXIO error code is returned.

Reviewed by:	kib
MFC after:	2 weeks
This commit is contained in:
Hans Petter Selasky 2015-10-29 13:53:37 +00:00
parent 043fd51a74
commit cb3450e26e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=290140

View File

@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
int
physio(struct cdev *dev, struct uio *uio, int ioflag)
{
struct cdevsw *csw;
struct buf *pbuf;
struct bio *bp;
struct vm_page **pages;
@ -46,6 +47,11 @@ physio(struct cdev *dev, struct uio *uio, int ioflag)
int error, i, npages, maxpages;
vm_prot_t prot;
csw = dev->si_devsw;
/* check if character device is being destroyed */
if (csw == NULL)
return (ENXIO);
/* XXX: sanity check */
if(dev->si_iosize_max < PAGE_SIZE) {
printf("WARNING: %s si_iosize_max=%d, using DFLTPHYS.\n",
@ -165,7 +171,7 @@ physio(struct cdev *dev, struct uio *uio, int ioflag)
}
}
dev->si_devsw->d_strategy(bp);
csw->d_strategy(bp);
if (uio->uio_rw == UIO_READ)
biowait(bp, "physrd");
else