Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/security/cap.c

    rda1bafb rb3f8fb7  
    2727 */
    2828
    29 /** @addtogroup generic
     29/** @addtogroup generic 
    3030 * @{
    3131 */
    3232
    3333/**
    34  * @file cap.c
    35  * @brief Capabilities control.
     34 * @file        cap.c
     35 * @brief       Capabilities control.
    3636 *
    3737 * @see cap.h
    3838 */
    39 
     39 
    4040#include <security/cap.h>
    4141#include <proc/task.h>
     
    4848/** Set capabilities.
    4949 *
    50  * @param task Task whose capabilities are to be changed.
     50 * @param t Task whose capabilities are to be changed.
    5151 * @param caps New set of capabilities.
    52  *
    5352 */
    54 void cap_set(task_t *task, cap_t caps)
     53void cap_set(task_t *t, cap_t caps)
    5554{
    56         irq_spinlock_lock(&task->lock, true);
    57         task->capabilities = caps;
    58         irq_spinlock_unlock(&task->lock, true);
     55        ipl_t ipl;
     56       
     57        ipl = interrupts_disable();
     58        spinlock_lock(&t->lock);
     59       
     60        t->capabilities = caps;
     61       
     62        spinlock_unlock(&t->lock);
     63        interrupts_restore(ipl);
    5964}
    6065
    6166/** Get capabilities.
    6267 *
    63  * @param task Task whose capabilities are to be returned.
    64  *
     68 * @param t Task whose capabilities are to be returned.
    6569 * @return Task's capabilities.
    66  *
    6770 */
    68 cap_t cap_get(task_t *task)
     71cap_t cap_get(task_t *t)
    6972{
    70         irq_spinlock_lock(&task->lock, true);
    71         cap_t caps = task->capabilities;
    72         irq_spinlock_unlock(&task->lock, true);
     73        ipl_t ipl;
     74        cap_t caps;
     75       
     76        ipl = interrupts_disable();
     77        spinlock_lock(&t->lock);
     78       
     79        caps = t->capabilities;
     80       
     81        spinlock_unlock(&t->lock);
     82        interrupts_restore(ipl);
    7383       
    7484        return caps;
     
    8393 *
    8494 * @return Zero on success or an error code from @ref errno.h.
    85  *
    8695 */
    8796unative_t sys_cap_grant(sysarg64_t *uspace_taskid_arg, cap_t caps)
    8897{
     98        sysarg64_t taskid_arg;
     99        task_t *t;
     100        ipl_t ipl;
     101        int rc;
     102       
    89103        if (!(cap_get(TASK) & CAP_CAP))
    90104                return (unative_t) EPERM;
    91105       
    92         sysarg64_t taskid_arg;
    93         int rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
     106        rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
    94107        if (rc != 0)
    95108                return (unative_t) rc;
    96        
    97         irq_spinlock_lock(&tasks_lock, true);
    98         task_t *task = task_find_by_id((task_id_t) taskid_arg.value);
    99        
    100         if ((!task) || (!context_check(CONTEXT, task->context))) {
    101                 irq_spinlock_unlock(&tasks_lock, true);
     109               
     110        ipl = interrupts_disable();
     111        spinlock_lock(&tasks_lock);
     112        t = task_find_by_id((task_id_t) taskid_arg.value);
     113        if ((!t) || (!context_check(CONTEXT, t->context))) {
     114                spinlock_unlock(&tasks_lock);
     115                interrupts_restore(ipl);
    102116                return (unative_t) ENOENT;
    103117        }
    104118       
    105         irq_spinlock_lock(&task->lock, false);
    106         task->capabilities |= caps;
    107         irq_spinlock_unlock(&task->lock, false);
     119        spinlock_lock(&t->lock);
     120        cap_set(t, cap_get(t) | caps);
     121        spinlock_unlock(&t->lock);
    108122       
    109         irq_spinlock_unlock(&tasks_lock, true);
     123        spinlock_unlock(&tasks_lock);
     124        interrupts_restore(ipl);       
    110125        return 0;
    111126}
     
    120135 *
    121136 * @return Zero on success or an error code from @ref errno.h.
    122  *
    123137 */
    124138unative_t sys_cap_revoke(sysarg64_t *uspace_taskid_arg, cap_t caps)
    125139{
    126140        sysarg64_t taskid_arg;
    127         int rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
     141        task_t *t;
     142        ipl_t ipl;
     143        int rc;
     144       
     145        rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
    128146        if (rc != 0)
    129147                return (unative_t) rc;
    130        
    131         irq_spinlock_lock(&tasks_lock, true);
    132        
    133         task_t *task = task_find_by_id((task_id_t) taskid_arg.value);
    134         if ((!task) || (!context_check(CONTEXT, task->context))) {
    135                 irq_spinlock_unlock(&tasks_lock, true);
     148
     149        ipl = interrupts_disable();
     150        spinlock_lock(&tasks_lock);     
     151        t = task_find_by_id((task_id_t) taskid_arg.value);
     152        if ((!t) || (!context_check(CONTEXT, t->context))) {
     153                spinlock_unlock(&tasks_lock);
     154                interrupts_restore(ipl);
    136155                return (unative_t) ENOENT;
    137156        }
    138        
     157
    139158        /*
    140159         * Revoking capabilities is different from granting them in that
     
    142161         * doesn't have CAP_CAP.
    143162         */
    144         irq_spinlock_unlock(&TASK->lock, false);
    145        
    146         if ((!(TASK->capabilities & CAP_CAP)) || (task != TASK)) {
    147                 irq_spinlock_unlock(&TASK->lock, false);
    148                 irq_spinlock_unlock(&tasks_lock, true);
     163        if (!(cap_get(TASK) & CAP_CAP) || !(t == TASK)) {
     164                spinlock_unlock(&tasks_lock);
     165                interrupts_restore(ipl);
    149166                return (unative_t) EPERM;
    150167        }
    151168       
    152         task->capabilities &= ~caps;
    153         irq_spinlock_unlock(&TASK->lock, false);
    154        
    155         irq_spinlock_unlock(&tasks_lock, true);
     169        spinlock_lock(&t->lock);
     170        cap_set(t, cap_get(t) & ~caps);
     171        spinlock_unlock(&t->lock);
     172
     173        spinlock_unlock(&tasks_lock);
     174
     175        interrupts_restore(ipl);
    156176        return 0;
    157177}
     
    159179/** @}
    160180 */
     181
Note: See TracChangeset for help on using the changeset viewer.