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:
parent
043fd51a74
commit
cb3450e26e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=290140
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user