cap.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006 Jakub Jermar
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00040 #include <security/cap.h>
00041 #include <proc/task.h>
00042 #include <synch/spinlock.h>
00043 #include <syscall/sysarg64.h>
00044 #include <syscall/copy.h>
00045 #include <arch.h>
00046 #include <typedefs.h>
00047 #include <errno.h>
00048 
00054 void cap_set(task_t *t, cap_t caps)
00055 {
00056         ipl_t ipl;
00057         
00058         ipl = interrupts_disable();
00059         spinlock_lock(&t->lock);
00060         
00061         t->capabilities = caps;
00062         
00063         spinlock_unlock(&t->lock);
00064         interrupts_restore(ipl);
00065 }
00066 
00072 cap_t cap_get(task_t *t)
00073 {
00074         ipl_t ipl;
00075         cap_t caps;
00076         
00077         ipl = interrupts_disable();
00078         spinlock_lock(&t->lock);
00079         
00080         caps = t->capabilities;
00081         
00082         spinlock_unlock(&t->lock);
00083         interrupts_restore(ipl);
00084         
00085         return caps;
00086 }
00087 
00097 __native sys_cap_grant(sysarg64_t *uspace_taskid_arg, cap_t caps)
00098 {
00099         sysarg64_t taskid_arg;
00100         task_t *t;
00101         ipl_t ipl;
00102         int rc;
00103         
00104         if (!(cap_get(TASK) & CAP_CAP))
00105                 return (__native) EPERM;
00106         
00107         rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
00108         if (rc != 0)
00109                 return (__native) rc;
00110                 
00111         ipl = interrupts_disable();
00112         spinlock_lock(&tasks_lock);
00113         t = task_find_by_id((task_id_t) taskid_arg.value);
00114         if (!t) {
00115                 spinlock_unlock(&tasks_lock);
00116                 interrupts_restore(ipl);
00117                 return (__native) ENOENT;
00118         }
00119         
00120         spinlock_lock(&t->lock);
00121         cap_set(t, cap_get(t) | caps);
00122         spinlock_unlock(&t->lock);
00123         
00124         spinlock_unlock(&tasks_lock);
00125         
00126 
00127         
00128         interrupts_restore(ipl);        
00129         return 0;
00130 }
00131 
00142 __native sys_cap_revoke(sysarg64_t *uspace_taskid_arg, cap_t caps)
00143 {
00144         sysarg64_t taskid_arg;
00145         task_t *t;
00146         ipl_t ipl;
00147         int rc;
00148         
00149         rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
00150         if (rc != 0)
00151                 return (__native) rc;
00152 
00153         ipl = interrupts_disable();
00154         spinlock_lock(&tasks_lock);     
00155         t = task_find_by_id((task_id_t) taskid_arg.value);
00156         if (!t) {
00157                 spinlock_unlock(&tasks_lock);
00158                 interrupts_restore(ipl);
00159                 return (__native) ENOENT;
00160         }
00161 
00162         /*
00163          * Revoking capabilities is different from granting them in that
00164          * a task can revoke capabilities from itself even if it
00165          * doesn't have CAP_CAP.
00166          */
00167         if (!(cap_get(TASK) & CAP_CAP) || !(t == TASK)) {
00168                 spinlock_unlock(&tasks_lock);
00169                 interrupts_restore(ipl);
00170                 return (__native) EPERM;
00171         }
00172         
00173         spinlock_lock(&t->lock);
00174         cap_set(t, cap_get(t) & ~caps);
00175         spinlock_unlock(&t->lock);
00176 
00177         spinlock_unlock(&tasks_lock);
00178 
00179         interrupts_restore(ipl);
00180         return 0;
00181 }
00182 

Generated on Sun Jun 18 17:28:04 2006 for HelenOS Kernel (ppc64) by  doxygen 1.4.6