Author: oshogbo
Date: Mon Sep 12 22:46:19 2016
New Revision: 305756
URL: https://svnweb.freebsd.org/changeset/base/305756

Log:
  fd: add fget_cap and fget_cap_locked primitives
  
  They can be used to obtain capabilities along with a referenced fp.
  
  Reviewed by:  mjg@

Modified:
  head/sys/kern/kern_descrip.c
  head/sys/sys/filedesc.h

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c        Mon Sep 12 22:07:35 2016        
(r305755)
+++ head/sys/kern/kern_descrip.c        Mon Sep 12 22:46:19 2016        
(r305756)
@@ -2446,6 +2446,77 @@ finit(struct file *fp, u_int flag, short
 }
 
 int
+fget_cap_locked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
+    struct file **fpp, struct filecaps *havecapsp)
+{
+       struct filedescent *fde;
+       int error;
+
+       FILEDESC_LOCK_ASSERT(fdp);
+
+       fde = fdeget_locked(fdp, fd);
+       if (fde == NULL) {
+               error = EBADF;
+               goto out;
+       }
+
+#ifdef CAPABILITIES
+       error = cap_check(cap_rights_fde(fde), needrightsp);
+       if (error != 0)
+               goto out;
+#endif
+
+       if (havecapsp != NULL)
+               filecaps_copy(&fde->fde_caps, havecapsp, true);
+
+       fhold(fde->fde_file);
+       *fpp = fde->fde_file;
+
+       error = 0;
+out:
+       return (error);
+}
+
+int
+fget_cap(struct thread *td, int fd, cap_rights_t *needrightsp,
+    struct file **fpp, struct filecaps *havecapsp)
+{
+       struct filedesc *fdp;
+       struct file *fp;
+       int error;
+       seq_t seq;
+
+       fdp = td->td_proc->p_fd;
+       for (;;) {
+               error = fget_unlocked(fdp, fd, needrightsp, &fp, &seq);
+               if (error != 0)
+                       return (error);
+
+               if (havecapsp != NULL) {
+                       if (!filecaps_copy(&fdp->fd_ofiles[fd].fde_caps,
+                           havecapsp, false)) {
+                               fdrop(fp, td);
+                               goto get_locked;
+                       }
+               }
+
+               if (!fd_modified(fdp, fd, seq))
+                       break;
+               fdrop(fp, td);
+       }
+
+       *fpp = fp;
+       return (0);
+
+get_locked:
+       FILEDESC_SLOCK(fdp);
+       error = fget_cap_locked(fdp, fd, needrightsp, fpp, havecapsp);
+       FILEDESC_SUNLOCK(fdp);
+
+       return (error);
+}
+
+int
 fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
     struct file **fpp, seq_t *seqp)
 {

Modified: head/sys/sys/filedesc.h
==============================================================================
--- head/sys/sys/filedesc.h     Mon Sep 12 22:07:35 2016        (r305755)
+++ head/sys/sys/filedesc.h     Mon Sep 12 22:46:19 2016        (r305756)
@@ -190,6 +190,11 @@ int        getvnode(struct thread *td, int fd, 
            struct file **fpp);
 void   mountcheckdirs(struct vnode *olddp, struct vnode *newdp);
 
+int    fget_cap_locked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
+           struct file **fpp, struct filecaps *havecapsp);
+int    fget_cap(struct thread *td, int fd, cap_rights_t *needrightsp,
+           struct file **fpp, struct filecaps *havecapsp);
+
 /* Return a referenced file from an unlocked descriptor. */
 int    fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
            struct file **fpp, seq_t *seqp);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to