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
This commit is contained in:
Mark Johnston 2021-05-27 15:49:32 -04:00
parent f885100773
commit e00bae5c18
2 changed files with 10 additions and 1 deletions

View File

@ -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

View File

@ -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) {