Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Nov 2015 08:47:11 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r290705 - stable/10/sys/kern
Message-ID:  <201511120847.tAC8lBZw049829@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Thu Nov 12 08:47:10 2015
New Revision: 290705
URL: https://svnweb.freebsd.org/changeset/base/290705

Log:
  MFC r290140:
  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

Modified:
  stable/10/sys/kern/kern_physio.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/kern/kern_physio.c
==============================================================================
--- stable/10/sys/kern/kern_physio.c	Thu Nov 12 05:53:32 2015	(r290704)
+++ stable/10/sys/kern/kern_physio.c	Thu Nov 12 08:47:10 2015	(r290705)
@@ -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 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
 				}
 			}
 
-			dev->si_devsw->d_strategy(bp);
+			csw->d_strategy(bp);
 			if (uio->uio_rw == UIO_READ)
 				biowait(bp, "physrd");
 			else



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201511120847.tAC8lBZw049829>