Author: ed
Date: Tue Aug 11 08:43:50 2015
New Revision: 286618
URL: https://svnweb.freebsd.org/changeset/base/286618

Log:
  Introduce kern_cap_rights_limit().
  
  The existing sys_cap_rights_limit() expects that a cap_rights_t object
  lives in userspace. It is therefore hard to call into it from
  kernelspace.
  
  Move the interesting bits of sys_cap_rights_limit() into
  kern_cap_rights_limit(), so that we can call into it from the CloudABI
  compatibility layer.
  
  Obtained from:        https://github.com/NuxiNL/freebsd
  Differential Revision:        https://reviews.freebsd.org/D3314

Modified:
  head/sys/kern/sys_capability.c
  head/sys/sys/syscallsubr.h

Modified: head/sys/kern/sys_capability.c
==============================================================================
--- head/sys/kern/sys_capability.c      Tue Aug 11 05:58:33 2015        
(r286617)
+++ head/sys/kern/sys_capability.c      Tue Aug 11 08:43:50 2015        
(r286618)
@@ -213,15 +213,41 @@ cap_rights(struct filedesc *fdp, int fd)
        return (cap_rights_fde(&fdp->fd_ofiles[fd]));
 }
 
+int
+kern_cap_rights_limit(struct thread *td, int fd, cap_rights_t *rights)
+{
+       struct filedesc *fdp;
+       int error;
+
+       fdp = td->td_proc->p_fd;
+       FILEDESC_XLOCK(fdp);
+       if (fget_locked(fdp, fd) == NULL) {
+               FILEDESC_XUNLOCK(fdp);
+               return (EBADF);
+       }
+       error = _cap_check(cap_rights(fdp, fd), rights, CAPFAIL_INCREASE);
+       if (error == 0) {
+               fdp->fd_ofiles[fd].fde_rights = *rights;
+               if (!cap_rights_is_set(rights, CAP_IOCTL)) {
+                       free(fdp->fd_ofiles[fd].fde_ioctls, M_FILECAPS);
+                       fdp->fd_ofiles[fd].fde_ioctls = NULL;
+                       fdp->fd_ofiles[fd].fde_nioctls = 0;
+               }
+               if (!cap_rights_is_set(rights, CAP_FCNTL))
+                       fdp->fd_ofiles[fd].fde_fcntls = 0;
+       }
+       FILEDESC_XUNLOCK(fdp);
+       return (error);
+}
+
 /*
  * System call to limit rights of the given capability.
  */
 int
 sys_cap_rights_limit(struct thread *td, struct cap_rights_limit_args *uap)
 {
-       struct filedesc *fdp;
        cap_rights_t rights;
-       int error, fd, version;
+       int error, version;
 
        cap_rights_init(&rights);
 
@@ -252,30 +278,9 @@ sys_cap_rights_limit(struct thread *td, 
                ktrcaprights(&rights);
 #endif
 
-       fd = uap->fd;
-
-       AUDIT_ARG_FD(fd);
+       AUDIT_ARG_FD(uap->fd);
        AUDIT_ARG_RIGHTS(&rights);
-
-       fdp = td->td_proc->p_fd;
-       FILEDESC_XLOCK(fdp);
-       if (fget_locked(fdp, fd) == NULL) {
-               FILEDESC_XUNLOCK(fdp);
-               return (EBADF);
-       }
-       error = _cap_check(cap_rights(fdp, fd), &rights, CAPFAIL_INCREASE);
-       if (error == 0) {
-               fdp->fd_ofiles[fd].fde_rights = rights;
-               if (!cap_rights_is_set(&rights, CAP_IOCTL)) {
-                       free(fdp->fd_ofiles[fd].fde_ioctls, M_FILECAPS);
-                       fdp->fd_ofiles[fd].fde_ioctls = NULL;
-                       fdp->fd_ofiles[fd].fde_nioctls = 0;
-               }
-               if (!cap_rights_is_set(&rights, CAP_FCNTL))
-                       fdp->fd_ofiles[fd].fde_fcntls = 0;
-       }
-       FILEDESC_XUNLOCK(fdp);
-       return (error);
+       return (kern_cap_rights_limit(td, uap->fd, &rights));
 }
 
 /*

Modified: head/sys/sys/syscallsubr.h
==============================================================================
--- head/sys/sys/syscallsubr.h  Tue Aug 11 05:58:33 2015        (r286617)
+++ head/sys/sys/syscallsubr.h  Tue Aug 11 08:43:50 2015        (r286618)
@@ -74,6 +74,7 @@ int   kern_alternate_path(struct thread *t
 int    kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa);
 int    kern_cap_ioctls_limit(struct thread *td, int fd, u_long *cmds,
            size_t ncmds);
+int    kern_cap_rights_limit(struct thread *td, int fd, cap_rights_t *rights);
 int    kern_chdir(struct thread *td, char *path, enum uio_seg pathseg);
 int    kern_clock_getcpuclockid2(struct thread *td, id_t id, int which,
            clockid_t *clk_id);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to