git: acabc20906ed - stable/13 - kevent: Prohibit negative change and event list lengths

Mark Johnston markj at FreeBSD.org
Sat Aug 21 17:59:08 UTC 2021


The branch stable/13 has been updated by markj:

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

commit acabc20906ed93a9e556b0d452a45e103f2e6eb6
Author:     Mark Johnston <markj at FreeBSD.org>
AuthorDate: 2021-05-27 19:49:32 +0000
Commit:     Mark Johnston <markj at FreeBSD.org>
CommitDate: 2021-08-21 16:08:58 +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
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit e00bae5c181ac8282caf41cd33a076da03cf8ac9)
---
 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 c277ac085d62..bf04dae2ee5c 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -1301,6 +1301,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;
@@ -1885,6 +1888,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-all mailing list