git: e00bae5c181a - main - kevent: Prohibit negative change and event list lengths

Mark Johnston markj at FreeBSD.org
Thu May 27 19:53:23 UTC 2021


The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=e00bae5c181ac8282caf41cd33a076da03cf8ac9

commit e00bae5c181ac8282caf41cd33a076da03cf8ac9
Author:     Mark Johnston <markj at FreeBSD.org>
AuthorDate: 2021-05-27 19:49:32 +0000
Commit:     Mark Johnston <markj at FreeBSD.org>
CommitDate: 2021-05-27 19:52:20 +0000

    kevent: Prohibit negative change and event list lengths
    
    Previously, a negative change list length would be treated the same as
    an empty change list.  A negative event list length would result in
    bogus copyouts.  Make kevent(2) return EINVAL for both cases so that
    application bugs are more easily found, and to be more robust against
    future changes to kevent internals.
    
    Reviewed by:    imp, kib
    MFC after:      1 week
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D30480
---
 lib/libc/sys/kqueue.2 | 4 +++-
 sys/kern/kern_event.c | 7 +++++++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/lib/libc/sys/kqueue.2 b/lib/libc/sys/kqueue.2
index b83d85d90d42..9be380bb5d99 100644
--- a/lib/libc/sys/kqueue.2
+++ b/lib/libc/sys/kqueue.2
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd October 8, 2020
+.Dd May 26, 2021
 .Dt KQUEUE 2
 .Os
 .Sh NAME
@@ -762,6 +762,8 @@ events were placed on the kqueue for return.
 A cancellation request was delivered to the thread, but not yet handled.
 .It Bq Er EINVAL
 The specified time limit or filter is invalid.
+.It Bq Er EINVAL
+The specified length of the event or change lists is negative.
 .It Bq Er ENOENT
 The event could not be found to be modified or deleted.
 .It Bq Er ENOMEM
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index e7047e9a7ad9..b224ce87087e 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -1303,6 +1303,9 @@ kqueue_kevent(struct kqueue *kq, struct thread *td, int nchanges, int nevents,
 	struct kevent *kevp, *changes;
 	int i, n, nerrors, error;
 
+	if (nchanges < 0)
+		return (EINVAL);
+
 	nerrors = 0;
 	while (nchanges > 0) {
 		n = nchanges > KQ_NEVENTS ? KQ_NEVENTS : nchanges;
@@ -1887,6 +1890,10 @@ kqueue_scan(struct kqueue *kq, int maxevents, struct kevent_copyops *k_ops,
 
 	if (maxevents == 0)
 		goto done_nl;
+	if (maxevents < 0) {
+		error = EINVAL;
+		goto done_nl;
+	}
 
 	rsbt = 0;
 	if (tsp != NULL) {


More information about the dev-commits-src-main mailing list