svn commit: r265517 - in user/dchagin/lemul/sys: compat/linux kern sys
Dmitry Chagin
dchagin at FreeBSD.org
Wed May 7 07:42:48 UTC 2014
Author: dchagin
Date: Wed May 7 07:42:47 2014
New Revision: 265517
URL: http://svnweb.freebsd.org/changeset/base/265517
Log:
Be a bit secure. To avoid a double fp lookup add a kern_kevent_fp
counterpart for kern_kevent with file pointer parameter instead
of file descriptor an pass the buck to it.
Suggested by: mjg
Modified:
user/dchagin/lemul/sys/compat/linux/linux_event.c
user/dchagin/lemul/sys/kern/kern_event.c
user/dchagin/lemul/sys/sys/syscallsubr.h
Modified: user/dchagin/lemul/sys/compat/linux/linux_event.c
==============================================================================
--- user/dchagin/lemul/sys/compat/linux/linux_event.c Wed May 7 07:41:58 2014 (r265516)
+++ user/dchagin/lemul/sys/compat/linux/linux_event.c Wed May 7 07:42:47 2014 (r265517)
@@ -345,14 +345,13 @@ linux_epoll_ctl(struct thread *td, struc
return (error);
}
- cap_rights_init(&rights, CAP_POLL_EVENT);
-
- error = fget(td, args->epfd, &rights, &epfp);
+ error = fget(td, args->epfd,
+ cap_rights_init(&rights, CAP_KQUEUE_CHANGE), &epfp);
if (error != 0)
return (error);
/* Protect user data vector from incorrectly supplied fd. */
- error = fget(td, args->fd, &rights, &fp);
+ error = fget(td, args->fd, cap_rights_init(&rights, CAP_POLL_EVENT), &fp);
if (error != 0)
goto leave1;
@@ -390,13 +389,14 @@ linux_epoll_ctl(struct thread *td, struc
goto leave0;
}
- error = epoll_to_kevent(td, epfp, args->fd, &le, &kev_flags, kev, &nchanges);
+ error = epoll_to_kevent(td, epfp, args->fd, &le, &kev_flags,
+ kev, &nchanges);
if (error)
goto leave0;
epoll_fd_install(td, args->fd, le.data);
- error = kern_kevent(td, args->epfd, nchanges, 0, &k_ops, NULL);
+ error = kern_kevent_fp(td, epfp, nchanges, 0, &k_ops, NULL);
leave0:
fdrop(fp, td);
@@ -424,7 +424,8 @@ linux_epoll_wait(struct thread *td, stru
if (args->maxevents <= 0 || args->maxevents > LINUX_MAX_EVENTS)
return (EINVAL);
- error = fget(td, args->epfd, cap_rights_init(&rights, CAP_POLL_EVENT), &epfp);
+ error = fget(td, args->epfd,
+ cap_rights_init(&rights, CAP_KQUEUE_EVENT), &epfp);
if (error != 0)
return (error);
@@ -446,7 +447,7 @@ linux_epoll_wait(struct thread *td, stru
tsp = NULL;
}
- error = kern_kevent(td, args->epfd, 0, args->maxevents, &k_ops, tsp);
+ error = kern_kevent_fp(td, epfp, 0, args->maxevents, &k_ops, tsp);
if (error == 0 && coargs.error != 0)
error = coargs.error;
Modified: user/dchagin/lemul/sys/kern/kern_event.c
==============================================================================
--- user/dchagin/lemul/sys/kern/kern_event.c Wed May 7 07:41:58 2014 (r265516)
+++ user/dchagin/lemul/sys/kern/kern_event.c Wed May 7 07:42:47 2014 (r265517)
@@ -859,12 +859,9 @@ int
kern_kevent(struct thread *td, int fd, int nchanges, int nevents,
struct kevent_copyops *k_ops, const struct timespec *timeout)
{
- struct kevent keva[KQ_NEVENTS];
- struct kevent *kevp, *changes;
- struct kqueue *kq;
- struct file *fp;
cap_rights_t rights;
- int i, n, nerrors, error;
+ struct file *fp;
+ int error;
cap_rights_init(&rights);
if (nchanges > 0)
@@ -875,9 +872,24 @@ kern_kevent(struct thread *td, int fd, i
if (error != 0)
return (error);
+ error = kern_kevent_fp(td, fp, nchanges, nevents, k_ops, timeout);
+ fdrop(fp, td);
+
+ return (error);
+}
+
+int
+kern_kevent_fp(struct thread *td, struct file *fp, int nchanges, int nevents,
+ struct kevent_copyops *k_ops, const struct timespec *timeout)
+{
+ struct kevent keva[KQ_NEVENTS];
+ struct kevent *kevp, *changes;
+ struct kqueue *kq;
+ int i, n, nerrors, error;
+
error = kqueue_acquire(fp, &kq);
if (error != 0)
- goto done_norel;
+ return (error);
nerrors = 0;
@@ -917,8 +929,6 @@ kern_kevent(struct thread *td, int fd, i
error = kqueue_scan(kq, nevents, k_ops, timeout, keva, td);
done:
kqueue_release(kq, 0);
-done_norel:
- fdrop(fp, td);
return (error);
}
Modified: user/dchagin/lemul/sys/sys/syscallsubr.h
==============================================================================
--- user/dchagin/lemul/sys/sys/syscallsubr.h Wed May 7 07:41:58 2014 (r265516)
+++ user/dchagin/lemul/sys/sys/syscallsubr.h Wed May 7 07:42:47 2014 (r265517)
@@ -124,6 +124,9 @@ int kern_jail_get(struct thread *td, str
int kern_jail_set(struct thread *td, struct uio *options, int flags);
int kern_kevent(struct thread *td, int fd, int nchanges, int nevents,
struct kevent_copyops *k_ops, const struct timespec *timeout);
+int kern_kevent_fp(struct thread *td, struct file *fp, int nchanges,
+ int nevents, struct kevent_copyops *k_ops,
+ const struct timespec *timeout);
int kern_kqueue(struct thread *td, int flags);
int kern_kldload(struct thread *td, const char *file, int *fileid);
int kern_kldstat(struct thread *td, int fileid, struct kld_file_stat *stat);
More information about the svn-src-user
mailing list