mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 02:43:15 +01:00
273 lines
7.5 KiB
C
273 lines
7.5 KiB
C
/*
|
|
* Codezero Capability Definitions
|
|
*
|
|
* Copyright (C) 2009 Bahadir Balban
|
|
*/
|
|
#ifndef __GENERIC_CAPABILITY_H__
|
|
#define __GENERIC_CAPABILITY_H__
|
|
|
|
#include <l4/lib/list.h>
|
|
#include <l4/api/exregs.h>
|
|
|
|
/*
|
|
* Some resources that capabilities possess don't
|
|
* have unique ids or need ids at all.
|
|
*
|
|
* E.g. a threadpool does not need a resource id.
|
|
* A virtual memory capability does not require
|
|
* a resource id, its capid is sufficient.
|
|
*/
|
|
#define CAP_RESID_NONE -1
|
|
|
|
/*
|
|
* A capability is a unique representation of security
|
|
* qualifiers on a particular resource.
|
|
*
|
|
* In this structure:
|
|
*
|
|
* The capid denotes the unique capability ID.
|
|
* The resid denotes the unique ID of targeted resource.
|
|
* The owner denotes the unique ID of the one and only capability owner. This is
|
|
* almost always a thread ID.
|
|
*
|
|
* The type field contains two types:
|
|
* - The capability type,
|
|
* - The targeted resource type.
|
|
*
|
|
* The targeted resouce type denotes what type of resource the capability is
|
|
* allowed to operate on. For example a thread, a thread group, an address space
|
|
* or a memory can be of this type.
|
|
*
|
|
* The capability type defines the general set of operations allowed on a
|
|
* particular resource. For example a capability type may be thread_control,
|
|
* exchange_registers, ipc, or map operations. A resource type may be such as a
|
|
* thread, a thread group, a virtual or physical memory region.
|
|
*
|
|
* There are also quantitative capability types. While their names denote
|
|
* quantitative objects such as memory, threads, and address spaces, these
|
|
* types actually define the quantitative operations available on those
|
|
* resources such as creation and deletion of a thread, allocation and
|
|
* deallocation of a memory region etc.
|
|
*
|
|
* The access field denotes the fine-grain operations available on a particular
|
|
* resource. The meaning of each bitfield differs according to the type of the
|
|
* capability. For example, for a capability type thread_control, the bitfields
|
|
* may mean suspend, resume, create, delete etc.
|
|
*/
|
|
struct capability {
|
|
struct link list;
|
|
|
|
/* Capability identifiers */
|
|
l4id_t capid; /* Unique capability ID */
|
|
l4id_t owner; /* Capability owner ID */
|
|
l4id_t resid; /* Targeted resource ID */
|
|
unsigned int type; /* Capability and target resource type */
|
|
|
|
/* Capability limits/permissions */
|
|
u32 access; /* Permitted operations */
|
|
|
|
/* Limits on the resource (NOTE: must never have signed type) */
|
|
unsigned long start; /* Resource start value */
|
|
unsigned long end; /* Resource end value */
|
|
unsigned long size; /* Resource size */
|
|
|
|
/* Used amount on resource _or_ user-defined attributes */
|
|
unsigned long user;
|
|
};
|
|
|
|
struct cap_list {
|
|
int ktcb_refs;
|
|
int ncaps;
|
|
struct link caps;
|
|
};
|
|
|
|
void capability_init(struct capability *cap);
|
|
struct capability *capability_create(void);
|
|
struct capability *boot_capability_create(void);
|
|
|
|
|
|
static inline void cap_list_init(struct cap_list *clist)
|
|
{
|
|
clist->ncaps = 0;
|
|
link_init(&clist->caps);
|
|
}
|
|
|
|
static inline void cap_list_insert(struct capability *cap,
|
|
struct cap_list *clist)
|
|
{
|
|
list_insert(&cap->list, &clist->caps);
|
|
clist->ncaps++;
|
|
}
|
|
|
|
static inline void cap_list_remove(struct capability *cap,
|
|
struct cap_list *clist)
|
|
{
|
|
list_remove(&cap->list);
|
|
clist->ncaps--;
|
|
}
|
|
|
|
/* Detach a whole list of capabilities from list head */
|
|
static inline struct capability *
|
|
cap_list_detach(struct cap_list *clist)
|
|
{
|
|
struct link *list = list_detach(&clist->caps);
|
|
clist->ncaps = 0;
|
|
return link_to_struct(list, struct capability, list);
|
|
}
|
|
|
|
/* Attach a whole list of capabilities to list head */
|
|
static inline void cap_list_attach(struct capability *cap,
|
|
struct cap_list *clist)
|
|
{
|
|
/* Attach as if cap is the list and clist is the element */
|
|
list_insert(&clist->caps, &cap->list);
|
|
|
|
/* Count the number of caps attached */
|
|
list_foreach_struct(cap, &clist->caps, list)
|
|
clist->ncaps++;
|
|
}
|
|
|
|
static inline void cap_list_move(struct cap_list *to,
|
|
struct cap_list *from)
|
|
{
|
|
struct capability *cap_head = cap_list_detach(from);
|
|
cap_list_attach(cap_head, to);
|
|
}
|
|
|
|
/* Have to have these as tcb.h includes this file */
|
|
struct ktcb;
|
|
struct task_ids;
|
|
|
|
/* Capability checking for quantitative capabilities */
|
|
int capability_consume(struct capability *cap, int quantity);
|
|
int capability_free(struct capability *cap, int quantity);
|
|
struct capability *capability_find_by_rtype(struct ktcb *task,
|
|
unsigned int rtype);
|
|
int cap_count(struct ktcb *task);
|
|
struct capability *cap_list_find_by_rtype(struct cap_list *clist,
|
|
unsigned int rtype);
|
|
struct capability *cap_find_by_capid(l4id_t capid, struct cap_list **clist);
|
|
|
|
/* Capability checking on system calls */
|
|
int cap_map_check(struct ktcb *task, unsigned long phys, unsigned long virt,
|
|
unsigned long npages, unsigned int flags);
|
|
int cap_thread_check(struct ktcb *task, unsigned int flags,
|
|
struct task_ids *ids);
|
|
int cap_exregs_check(struct ktcb *task, struct exregs_data *exregs);
|
|
int cap_ipc_check(l4id_t to, l4id_t from,
|
|
unsigned int flags, unsigned int ipc_type);
|
|
int cap_cap_check(struct ktcb *task, unsigned int req, unsigned int flags);
|
|
int cap_mutex_check(unsigned long mutex_address, int mutex_op);
|
|
|
|
#if 0
|
|
/* Virtual memory space allocated to container */
|
|
struct capability cap_virtmap = {
|
|
.capid = id_alloc(capids),
|
|
.resid = container_id,
|
|
.owner = pagerid,
|
|
.type = CAP_TYPE_VIRTMEM,
|
|
.access = 0, /* No access operations */
|
|
.start = 0xF0000000,
|
|
.end = 0xF1000000,
|
|
.size = 0x1000000
|
|
};
|
|
|
|
/* Physical memory space allocated to container */
|
|
struct capability cap_physmap = {
|
|
.capid = id_alloc(capids),
|
|
.resid = container_id,
|
|
.owner = pagerid,
|
|
.type = CAP_TYPE_PHYSMEM,
|
|
.access = 0, /* No access operations */
|
|
.start = 0x0,
|
|
.end = 0x1000000,
|
|
.size = 0x1000000
|
|
};
|
|
|
|
/* IPC operations permitted on target thread */
|
|
struct capability cap_ipc = {
|
|
.capid = id_alloc(capids),
|
|
.resid = target_tid,
|
|
.owner = tid,
|
|
.type = CAP_TYPE_IPC,
|
|
.access = CAP_IPC_SEND | CAP_IPC_RECV | CAP_IPC_FULL | CAP_IPC_SHORT | CAP_IPC_EXTENDED,
|
|
.start = 0xF0000000,
|
|
.end = 0xF1000000,
|
|
.size = 0x1000000
|
|
};
|
|
|
|
/* Thread control operations permitted on target thread */
|
|
struct capability cap_thread_control = {
|
|
.capid = id_alloc(capids),
|
|
.resid = target_tid,
|
|
.owner = pagerid,
|
|
.type = CAP_TYPE_THREAD_CONTROL,
|
|
.access = CAP_THREAD_SUSPEND | CAP_THREAD_RUN | CAP_THREAD_RECYCLE | CAP_THREAD_CREATE | CAP_THREAD_DESTROY,
|
|
.start = 0,
|
|
.end = 0,
|
|
.size = 0,
|
|
};
|
|
|
|
/* Exregs operations permitted on target thread */
|
|
struct capability cap_exregs = {
|
|
.capid = id_alloc(capids),
|
|
.resid = target_tid,
|
|
.owner = pagerid,
|
|
.type = CAP_TYPE_EXREGS,
|
|
.access = CAP_EXREGS_RW_PAGER | CAP_EXREGS_RW_SP | CAP_EXREGS_RW_PC | CAP_EXREGS_RW_UTCB | CAP_EXREGS_RW_OTHERS,
|
|
.start = 0,
|
|
.end = 0,
|
|
.size = 0
|
|
};
|
|
|
|
/* Number of threads allocated to container */
|
|
struct capability cap_threads = {
|
|
.capid = id_alloc(capids),
|
|
.resid = container_id,
|
|
.owner = pagerid,
|
|
.type = CAP_TYPE_THREADS,
|
|
.access = 0,
|
|
.start = 0,
|
|
.end = 0,
|
|
.size = 256,
|
|
};
|
|
|
|
/* Number of spaces allocated to container */
|
|
struct capability cap_spaces = {
|
|
.capid = id_alloc(capids),
|
|
.resid = container_id,
|
|
.owner = pagerid,
|
|
.type = CAP_TYPE_SPACES,
|
|
.access = 0,
|
|
.start = 0,
|
|
.end = 0,
|
|
.size = 128,
|
|
};
|
|
|
|
/* CPU time allocated to container */
|
|
struct capability cap_cputime = {
|
|
.capid = id_alloc(capids),
|
|
.resid = container_id,
|
|
.owner = pagerid,
|
|
.type = CAP_TYPE_CPUTIME,
|
|
.access = 0,
|
|
.start = 0,
|
|
.end = 0,
|
|
.size = 55, /* Percentage */
|
|
};
|
|
|
|
struct capability cap_cpuprio = {
|
|
.capid = id_alloc(capids),
|
|
.resid = container_id,
|
|
.owner = pagerid,
|
|
.type = CAP_TYPE_CPUPRIO,
|
|
.access = 0,
|
|
.start = 0,
|
|
.end = 0,
|
|
.size = 55, /* Priority No */
|
|
};
|
|
|
|
#endif
|
|
|
|
#endif /* __GENERIC_CAPABILITY_H__ */
|