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