Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Nov 2018 17:08:08 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r341082 - stable/12/sys/kern
Message-ID:  <201811271708.wARH88UE051401@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markj
Date: Tue Nov 27 17:08:07 2018
New Revision: 341082
URL: https://svnweb.freebsd.org/changeset/base/341082

Log:
  MFC r340898:
  Ensure that knotes do not get registered when KQ_CLOSING is set.
  
  PR:	228858

Modified:
  stable/12/sys/kern/kern_event.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/kern/kern_event.c
==============================================================================
--- stable/12/sys/kern/kern_event.c	Tue Nov 27 17:03:15 2018	(r341081)
+++ stable/12/sys/kern/kern_event.c	Tue Nov 27 17:08:07 2018	(r341082)
@@ -1463,8 +1463,11 @@ findkn:
 					break;
 		}
 	} else {
-		if ((kev->flags & EV_ADD) == EV_ADD)
-			kqueue_expand(kq, fops, kev->ident, waitok);
+		if ((kev->flags & EV_ADD) == EV_ADD) {
+			error = kqueue_expand(kq, fops, kev->ident, waitok);
+			if (error != 0)
+				goto done;
+		}
 
 		KQ_LOCK(kq);
 
@@ -1700,12 +1703,12 @@ kqueue_expand(struct kqueue *kq, struct filterops *fop
 {
 	struct klist *list, *tmp_knhash, *to_free;
 	u_long tmp_knhashmask;
-	int size;
-	int fd;
+	int error, fd, size;
 	int mflag = waitok ? M_WAITOK : M_NOWAIT;
 
 	KQ_NOTOWNED(kq);
 
+	error = 0;
 	to_free = NULL;
 	if (fops->f_isfd) {
 		fd = ident;
@@ -1717,9 +1720,11 @@ kqueue_expand(struct kqueue *kq, struct filterops *fop
 			if (list == NULL)
 				return ENOMEM;
 			KQ_LOCK(kq);
-			if (kq->kq_knlistsize > fd) {
+			if ((kq->kq_state & KQ_CLOSING) != 0) {
 				to_free = list;
-				list = NULL;
+				error = EBADF;
+			} else if (kq->kq_knlistsize > fd) {
+				to_free = list;
 			} else {
 				if (kq->kq_knlist != NULL) {
 					bcopy(kq->kq_knlist, list,
@@ -1740,9 +1745,12 @@ kqueue_expand(struct kqueue *kq, struct filterops *fop
 			tmp_knhash = hashinit(KN_HASHSIZE, M_KQUEUE,
 			    &tmp_knhashmask);
 			if (tmp_knhash == NULL)
-				return ENOMEM;
+				return (ENOMEM);
 			KQ_LOCK(kq);
-			if (kq->kq_knhashmask == 0) {
+			if ((kq->kq_state & KQ_CLOSING) != 0) {
+				to_free = tmp_knhash;
+				error = EBADF;
+			} else if (kq->kq_knhashmask == 0) {
 				kq->kq_knhash = tmp_knhash;
 				kq->kq_knhashmask = tmp_knhashmask;
 			} else {
@@ -1754,7 +1762,7 @@ kqueue_expand(struct kqueue *kq, struct filterops *fop
 	free(to_free, M_KQUEUE);
 
 	KQ_NOTOWNED(kq);
-	return 0;
+	return (error);
 }
 
 static void
@@ -2605,6 +2613,8 @@ knote_attach(struct knote *kn, struct kqueue *kq)
 	KASSERT(kn_in_flux(kn), ("knote %p not marked influx", kn));
 	KQ_OWNED(kq);
 
+	if ((kq->kq_state & KQ_CLOSING) != 0)
+		return (EBADF);
 	if (kn->kn_fop->f_isfd) {
 		if (kn->kn_id >= kq->kq_knlistsize)
 			return (ENOMEM);



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