Author: pjd
Date: Thu Sep  5 11:58:12 2013
New Revision: 255240
URL: http://svnweb.freebsd.org/changeset/base/255240

Log:
  Handle cases where capability rights are not provided.
  
  Reported by:  kib

Modified:
  head/sys/cddl/compat/opensolaris/sys/file.h
  head/sys/dev/aacraid/aacraid_linux.c
  head/sys/fs/fdescfs/fdesc_vnops.c
  head/sys/kern/kern_descrip.c
  head/sys/ofed/include/linux/file.h
  head/sys/security/audit/audit_bsm_klib.c

Modified: head/sys/cddl/compat/opensolaris/sys/file.h
==============================================================================
--- head/sys/cddl/compat/opensolaris/sys/file.h Thu Sep  5 10:24:09 2013        
(r255239)
+++ head/sys/cddl/compat/opensolaris/sys/file.h Thu Sep  5 11:58:12 2013        
(r255240)
@@ -54,7 +54,7 @@ releasef(int fd)
        struct file *fp;
 
        /* No CAP_ rights required, as we're only releasing. */
-       if (fget(curthread, fd, 0, &fp) == 0) {
+       if (fget(curthread, fd, NULL, &fp) == 0) {
                fdrop(fp, curthread);
                fdrop(fp, curthread);
        }

Modified: head/sys/dev/aacraid/aacraid_linux.c
==============================================================================
--- head/sys/dev/aacraid/aacraid_linux.c        Thu Sep  5 10:24:09 2013        
(r255239)
+++ head/sys/dev/aacraid/aacraid_linux.c        Thu Sep  5 11:58:12 2013        
(r255240)
@@ -34,6 +34,9 @@ __FBSDID("$FreeBSD$");
  */
 
 #include <sys/param.h>
+#if __FreeBSD_version >= 900000
+#include <sys/capability.h>
+#endif
 #include <sys/systm.h>
 #include <sys/conf.h>
 #include <sys/kernel.h>
@@ -77,15 +80,19 @@ static int
 aacraid_linux_ioctl(struct thread *td, struct linux_ioctl_args *args)
 {
        struct file *fp;
+#if __FreeBSD_version >= 900000
+       cap_rights_t rights;
+#endif
        u_long cmd;
        int error;
 
+       if ((error = fget(td, args->fd,
 #if __FreeBSD_version >= 900000
-       if ((error = fget(td, args->fd, 0, &fp)) != 0)
-#else
-       if ((error = fget(td, args->fd, &fp)) != 0)
+           cap_rights_init(&rights, CAP_IOCTL),
 #endif
+           &fp)) != 0) {
                return (error);
+       }
        cmd = args->cmd;
 
        /*

Modified: head/sys/fs/fdescfs/fdesc_vnops.c
==============================================================================
--- head/sys/fs/fdescfs/fdesc_vnops.c   Thu Sep  5 10:24:09 2013        
(r255239)
+++ head/sys/fs/fdescfs/fdesc_vnops.c   Thu Sep  5 11:58:12 2013        
(r255240)
@@ -309,7 +309,7 @@ fdesc_lookup(ap)
        /*
         * No rights to check since 'fp' isn't actually used.
         */
-       if ((error = fget(td, fd, 0, &fp)) != 0)
+       if ((error = fget(td, fd, NULL, &fp)) != 0)
                goto bad;
 
        /* Check if we're looking up ourselves. */

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c        Thu Sep  5 10:24:09 2013        
(r255239)
+++ head/sys/kern/kern_descrip.c        Thu Sep  5 11:58:12 2013        
(r255240)
@@ -586,8 +586,8 @@ kern_fcntl(struct thread *td, int fd, in
 
        case F_SETLK:
        do_setlk:
-               error = fget_unlocked(fdp, fd,
-                   cap_rights_init(&rights, CAP_FLOCK), 0, &fp, NULL);
+               cap_rights_init(&rights, CAP_FLOCK);
+               error = fget_unlocked(fdp, fd, &rights, 0, &fp, NULL);
                if (error != 0)
                        break;
                if (fp->f_type != DTYPE_VNODE) {
@@ -676,7 +676,7 @@ kern_fcntl(struct thread *td, int fd, in
                 * that the closing thread was a bit slower and that the
                 * advisory lock succeeded before the close.
                 */
-               error = fget_unlocked(fdp, fd, 0, 0, &fp2, NULL);
+               error = fget_unlocked(fdp, fd, &rights, 0, &fp2, NULL);
                if (error != 0) {
                        fdrop(fp, td);
                        break;
@@ -733,7 +733,7 @@ kern_fcntl(struct thread *td, int fd, in
                arg = arg ? 128 * 1024: 0;
                /* FALLTHROUGH */
        case F_READAHEAD:
-               error = fget_unlocked(fdp, fd, 0, 0, &fp, NULL);
+               error = fget_unlocked(fdp, fd, NULL, 0, &fp, NULL);
                if (error != 0)
                        break;
                if (fp->f_type != DTYPE_VNODE) {
@@ -2324,13 +2324,15 @@ fget_unlocked(struct filedesc *fdp, int 
                        return (EBADF);
 #ifdef CAPABILITIES
                haverights = *cap_rights(fdp, fd);
-               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);
+               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);
+                               if (error != 0)
+                                       return (error);
+                       }
                }
 #endif
                count = fp->f_count;
@@ -2382,7 +2384,10 @@ _fget(struct thread *td, int fd, struct 
        *fpp = NULL;
        if (td == NULL || (fdp = td->td_proc->p_fd) == NULL)
                return (EBADF);
-       needrights = *needrightsp;
+       if (needrightsp != NULL)
+               needrights = *needrightsp;
+       else
+               cap_rights_init(&needrights);
        if (maxprotp != NULL)
                cap_rights_set(&needrights, CAP_MMAP);
        error = fget_unlocked(fdp, fd, &needrights, 0, &fp, &haverights);
@@ -2517,9 +2522,11 @@ fgetvp_rights(struct thread *td, int fd,
                return (EBADF);
 
 #ifdef CAPABILITIES
-       error = cap_check(cap_rights(fdp, fd), needrightsp);
-       if (error != 0)
-               return (error);
+       if (needrightsp != NULL) {
+               error = cap_check(cap_rights(fdp, fd), needrightsp);
+               if (error != 0)
+                       return (error);
+       }
 #endif
 
        if (fp->f_vnode == NULL)

Modified: head/sys/ofed/include/linux/file.h
==============================================================================
--- head/sys/ofed/include/linux/file.h  Thu Sep  5 10:24:09 2013        
(r255239)
+++ head/sys/ofed/include/linux/file.h  Thu Sep  5 11:58:12 2013        
(r255240)
@@ -47,8 +47,10 @@ linux_fget(unsigned int fd)
 {
        struct file *file;
 
-       if (fget_unlocked(curthread->td_proc->p_fd, fd, 0, 0, &file, NULL) != 0)
+       if (fget_unlocked(curthread->td_proc->p_fd, fd, NULL, 0, &file,
+           NULL) != 0) {
                return (NULL);
+       }
        return (struct linux_file *)file->f_data;
 }
 
@@ -70,8 +72,10 @@ put_unused_fd(unsigned int fd)
 {
        struct file *file;
 
-       if (fget_unlocked(curthread->td_proc->p_fd, fd, 0, 0, &file, NULL) != 0)
+       if (fget_unlocked(curthread->td_proc->p_fd, fd, NULL, 0, &file,
+           NULL) != 0) {
                return;
+       }
        fdclose(curthread->td_proc->p_fd, file, fd, curthread);
 }
 
@@ -80,8 +84,10 @@ fd_install(unsigned int fd, struct linux
 {
        struct file *file;
 
-       if (fget_unlocked(curthread->td_proc->p_fd, fd, 0, 0, &file, NULL) != 0)
+       if (fget_unlocked(curthread->td_proc->p_fd, fd, NULL, 0, &file,
+           NULL) != 0) {
                file = NULL;
+       }
        filp->_file = file;
         finit(file, filp->f_mode, DTYPE_DEV, filp, &linuxfileops);
 }

Modified: head/sys/security/audit/audit_bsm_klib.c
==============================================================================
--- head/sys/security/audit/audit_bsm_klib.c    Thu Sep  5 10:24:09 2013        
(r255239)
+++ head/sys/security/audit/audit_bsm_klib.c    Thu Sep  5 11:58:12 2013        
(r255240)
@@ -496,7 +496,7 @@ audit_canon_path(struct thread *td, int 
                        vhold(cvnp);
                } else {
                        /* XXX: fgetvp() that vhold()s vnode instead of 
vref()ing it would be better */
-                       error = fgetvp(td, dirfd, 0, &cvnp);
+                       error = fgetvp(td, dirfd, NULL, &cvnp);
                        if (error) {
                                cpath[0] = '\0';
                                if (rvnp != NULL)
_______________________________________________
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