Author: mjg
Date: Wed Jul 23 19:33:49 2014
New Revision: 269023
URL: http://svnweb.freebsd.org/changeset/base/269023

Log:
  Prepare fget_unlocked for reading fd table only once.
  
  Some capsicum functions accept fdp + fd and lookup fde based on that.
  Add variants which accept fde.
  
  Reviewed by:  pjd
  MFC after:    1 week

Modified:
  head/sys/kern/kern_descrip.c
  head/sys/kern/sys_capability.c
  head/sys/sys/capsicum.h

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c        Wed Jul 23 18:54:18 2014        
(r269022)
+++ head/sys/kern/kern_descrip.c        Wed Jul 23 19:33:49 2014        
(r269023)
@@ -2301,6 +2301,9 @@ int
 fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
     int needfcntl, struct file **fpp, cap_rights_t *haverightsp)
 {
+#ifdef CAPABILITIES
+       struct filedescent fde;
+#endif
        struct file *fp;
        u_int count;
 #ifdef CAPABILITIES
@@ -2323,17 +2326,22 @@ fget_unlocked(struct filedesc *fdp, int 
         * due to preemption.
         */
        for (;;) {
+#ifdef CAPABILITIES
+               fde = fdp->fd_ofiles[fd];
+               fp = fde.fde_file;
+#else
                fp = fdp->fd_ofiles[fd].fde_file;
+#endif
                if (fp == NULL)
                        return (EBADF);
 #ifdef CAPABILITIES
-               haverights = *cap_rights(fdp, fd);
+               haverights = *cap_rights_fde(&fde);
                if (needrightsp != NULL) {
                        error = cap_check(&haverights, needrightsp);
                        if (error != 0)
                                return (error);
                        if (cap_rights_is_set(needrightsp, CAP_FCNTL)) {
-                               error = cap_fcntl_check(fdp, fd, needfcntl);
+                               error = cap_fcntl_check_fde(&fde, needfcntl);
                                if (error != 0)
                                        return (error);
                        }

Modified: head/sys/kern/sys_capability.c
==============================================================================
--- head/sys/kern/sys_capability.c      Wed Jul 23 18:54:18 2014        
(r269022)
+++ head/sys/kern/sys_capability.c      Wed Jul 23 19:33:49 2014        
(r269023)
@@ -199,11 +199,19 @@ cap_rights_to_vmprot(cap_rights_t *havep
  * any other way, as we want to keep all capability permission evaluation in
  * this one file.
  */
+
+cap_rights_t *
+cap_rights_fde(struct filedescent *fde)
+{
+
+       return (&fde->fde_rights);
+}
+
 cap_rights_t *
 cap_rights(struct filedesc *fdp, int fd)
 {
 
-       return (&fdp->fd_ofiles[fd].fde_rights);
+       return (cap_rights_fde(&fdp->fd_ofiles[fd]));
 }
 
 /*
@@ -486,24 +494,31 @@ out:
  * Test whether a capability grants the given fcntl command.
  */
 int
-cap_fcntl_check(struct filedesc *fdp, int fd, int cmd)
+cap_fcntl_check_fde(struct filedescent *fde, int cmd)
 {
        uint32_t fcntlcap;
 
-       KASSERT(fd >= 0 && fd < fdp->fd_nfiles,
-           ("%s: invalid fd=%d", __func__, fd));
-
        fcntlcap = (1 << cmd);
        KASSERT((CAP_FCNTL_ALL & fcntlcap) != 0,
            ("Unsupported fcntl=%d.", cmd));
 
-       if ((fdp->fd_ofiles[fd].fde_fcntls & fcntlcap) != 0)
+       if ((fde->fde_fcntls & fcntlcap) != 0)
                return (0);
 
        return (ENOTCAPABLE);
 }
 
 int
+cap_fcntl_check(struct filedesc *fdp, int fd, int cmd)
+{
+
+       KASSERT(fd >= 0 && fd < fdp->fd_nfiles,
+           ("%s: invalid fd=%d", __func__, fd));
+
+       return (cap_fcntl_check_fde(&fdp->fd_ofiles[fd], cmd));
+}
+
+int
 sys_cap_fcntls_limit(struct thread *td, struct cap_fcntls_limit_args *uap)
 {
        struct filedesc *fdp;

Modified: head/sys/sys/capsicum.h
==============================================================================
--- head/sys/sys/capsicum.h     Wed Jul 23 18:54:18 2014        (r269022)
+++ head/sys/sys/capsicum.h     Wed Jul 23 19:33:49 2014        (r269023)
@@ -341,6 +341,7 @@ __END_DECLS
 #define IN_CAPABILITY_MODE(td) (((td)->td_ucred->cr_flags & CRED_FLAG_CAPMODE) 
!= 0)
 
 struct filedesc;
+struct filedescent;
 
 /*
  * Test whether a capability grants the requested rights.
@@ -355,9 +356,11 @@ u_char     cap_rights_to_vmprot(cap_rights_t
  * For the purposes of procstat(1) and similar tools, allow kern_descrip.c to
  * extract the rights from a capability.
  */
+cap_rights_t   *cap_rights_fde(struct filedescent *fde);
 cap_rights_t   *cap_rights(struct filedesc *fdp, int fd);
 
 int    cap_ioctl_check(struct filedesc *fdp, int fd, u_long cmd);
+int    cap_fcntl_check_fde(struct filedescent *fde, int cmd);
 int    cap_fcntl_check(struct filedesc *fdp, int fd, int cmd);
 
 #else /* !_KERNEL */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to