Check if kernel calls is allowed (from process' call mask) added. Not yet

enforced. If a call is denied, this will be kprinted. Please report any such
errors, so that I can adjust the mask before returning errors instead of
warnings.

Wrote CMOS driver. All CMOS code from FS has been removed. Currently the
driver only supports get time calls. Set time is left out as an exercise
for the book readers ... startup scripts were updated because the CMOS driver
is needed early on. (IS got same treatment.) Don't forget to run MAKEDEV cmos
in /dev/, otherwise the driver cannot be loaded.
This commit is contained in:
Jorrit Herder
2005-08-04 19:23:03 +00:00
parent b98eb4e144
commit 74711a3b14
33 changed files with 376 additions and 162 deletions

View File

@@ -14,9 +14,8 @@
*/
#define vir2phys(vir) (kinfo.data_base + (vir_bytes) (vir))
/* Map a process number to a privilege structure id. Used at boot time. */
/* Map a process number to a privilege structure id. */
#define s_nr_to_id(n) (NR_TASKS + (n) + 1)
#define s(n) (1 << s_nr_to_id(n))
/* Translate a pointer to a field in a structure to a pointer to the structure
* itself. So it translates '&struct_ptr->field' back to 'struct_ptr'.

View File

@@ -82,8 +82,9 @@ PUBLIC void main()
strncpy(rp->p_name, ip->proc_name, P_NAME_LEN); /* set process name */
(void) get_priv(rp, (ip->flags & SYS_PROC)); /* assign structure */
priv(rp)->s_flags = ip->flags; /* process flags */
priv(rp)->s_call_mask = ip->call_mask; /* allowed traps */
priv(rp)->s_send_mask.chunk[0] = ip->send_mask; /* restrict targets */
priv(rp)->s_trap_mask = ip->trap_mask; /* allowed traps */
priv(rp)->s_call_mask = ip->call_mask; /* kernel call mask */
priv(rp)->s_ipc_to.chunk[0] = ip->ipc_to; /* restrict targets */
if (iskerneln(proc_nr(rp))) { /* part of the kernel? */
if (ip->stksize > 0) { /* HARDWARE stack size is 0 */
rp->p_priv->s_stack_guard = (reg_t *) ktsb;

View File

@@ -21,9 +21,10 @@ struct priv {
sys_id_t s_id; /* index of this system structure */
short s_flags; /* PREEMTIBLE, BILLABLE, etc. */
short s_call_mask; /* allowed system call traps */
sys_map_t s_send_mask; /* allowed send destinations */
long s_sys_mask; /* allowed kernel calls */
short s_trap_mask; /* allowed system call traps */
sys_map_t s_ipc_from; /* allowed callers to receive from */
sys_map_t s_ipc_to; /* allowed destination processes */
long s_call_mask; /* allowed kernel calls */
sys_map_t s_notify_pending; /* bit map with pending notifications */
irq_id_t s_int_pending; /* pending hardware interrupts */

View File

@@ -112,7 +112,7 @@ message *m_ptr; /* pointer to message in the caller's space */
* kernel may only be SENDREC, because tasks always reply and may not block
* if the caller doesn't do receive().
*/
if (! (priv(caller_ptr)->s_call_mask & (1 << function)) ||
if (! (priv(caller_ptr)->s_trap_mask & (1 << function)) ||
(iskerneln(src_dst) && function != SENDREC))
return(ECALLDENIED);
@@ -141,7 +141,7 @@ message *m_ptr; /* pointer to message in the caller's space */
* that the destination is still alive.
*/
if (function & CHECK_DST) {
if (! get_sys_bit(priv(caller_ptr)->s_send_mask, nr_to_id(src_dst))) {
if (! get_sys_bit(priv(caller_ptr)->s_ipc_to, nr_to_id(src_dst))) {
kprintf("Warning, send_mask denied %d sending to %d\n",
proc_nr(caller_ptr), src_dst);
return(ECALLDENIED);

View File

@@ -22,6 +22,7 @@
*
* Changes:
* 2004 to 2005 many new system calls (see system.h) (Jorrit N. Herder)
* Aug 04, 2005 check if kernel call is allowed (Jorrit N. Herder)
* Jul 20, 2005 send signal to services with message (Jorrit N. Herder)
* Jan 15, 2005 new, generalized virtual copy function (Jorrit N. Herder)
* Oct 10, 2004 dispatch system calls from call vector (Jorrit N. Herder)
@@ -62,22 +63,30 @@ PUBLIC void sys_task()
/* Main entry point of sys_task. Get the message and dispatch on type. */
static message m;
register int result;
unsigned int call;
register struct proc *caller_ptr;
unsigned int call_nr;
int s;
/* Initialize the system task. */
initialize();
while (TRUE) {
/* Get work. */
receive(ANY, &m);
/* Get work. Block and wait until a request message arrives. */
receive(ANY, &m);
call_nr = (unsigned) m.m_type - KERNEL_CALL;
caller_ptr = proc_addr(m.m_source);
/* Handle the request. */
call = (unsigned) m.m_type - KERNEL_CALL; /* substract offset */
if (call < NR_SYS_CALLS) { /* check call number */
result = (*call_vec[call])(&m); /* handle the kernel call */
} else {
kprintf("Warning, illegal SYSTASK request from %d.\n", m.m_source);
/* See if the caller made a valid request and try to handle it. */
if (! (priv(caller_ptr)->s_call_mask & (1<<call_nr))) {
kprintf("SYSTEM: request %d from %d denied.\n", call_nr,m.m_source);
result = ECALLDENIED; /* illegal message type */
}
if (call_nr >= NR_SYS_CALLS) { /* check call number */
kprintf("SYSTEM: illegal request %d from %d.\n", call_nr,m.m_source);
result = EBADREQUEST; /* illegal message type */
}
else {
result = (*call_vec[call_nr])(&m); /* handle the kernel call */
}
/* Send a reply, unless inhibited by a handler function. Use the kernel
@@ -86,9 +95,8 @@ PUBLIC void sys_task()
*/
if (result != EDONTREPLY) {
m.m_type = result; /* report status of call */
if (OK != lock_send(m.m_source, &m)) {
kprintf("Warning, SYSTASK couldn't reply to request from %d.\n",
m.m_source);
if (OK != (s=lock_send(m.m_source, &m))) {
kprintf("SYSTEM, reply to %d failed: %d\n", m.m_source, s);
}
}
}

View File

@@ -58,18 +58,18 @@ message *m_ptr; /* pointer to request message */
sigemptyset(&priv(rp)->s_sig_pending); /* - signals */
/* Now update the process' privileges as requested. */
rp->p_priv->s_call_mask = FILLED_MASK;
rp->p_priv->s_trap_mask = FILLED_MASK;
for (i=0; i<BITMAP_CHUNKS(NR_SYS_PROCS); i++) {
rp->p_priv->s_send_mask.chunk[i] = FILLED_MASK;
rp->p_priv->s_ipc_to.chunk[i] = FILLED_MASK;
}
unset_sys_bit(rp->p_priv->s_send_mask, USER_PRIV_ID);
unset_sys_bit(rp->p_priv->s_ipc_to, USER_PRIV_ID);
/* All process that this process can send to must be able to reply.
* Therefore, their send masks should be updated as well.
*/
for (i=0; i<NR_SYS_PROCS; i++) {
if (get_sys_bit(rp->p_priv->s_send_mask, i)) {
set_sys_bit(priv_addr(i)->s_send_mask, priv_id(rp));
if (get_sys_bit(rp->p_priv->s_ipc_to, i)) {
set_sys_bit(priv_addr(i)->s_ipc_to, priv_id(rp));
}
}

View File

@@ -22,7 +22,7 @@
* include 'boot_image' (this file) and 'idt' and 'gdt' (protect.c).
*
* Changes:
* Aug 02, 2005 minimal boot image and cleanup (Jorrit N. Herder)
* Aug 02, 2005 set privileges and minimal boot image (Jorrit N. Herder)
* Oct 17, 2004 updated above and tasktab comments (Jorrit N. Herder)
* May 01, 2004 changed struct for system image (Jorrit N. Herder)
*/
@@ -48,7 +48,7 @@ PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
/* Define flags for the various process types. */
#define IDL_F (BILLABLE | SYS_PROC) /* idle task */
#define TSK_F (SYS_PROC) /* kernel tasks */
#define SRV_F (PREEMPTIBLE | SYS_PROC) /* system services */
#define SRV_F (BILLABLE | PREEMPTIBLE | SYS_PROC) /* system services */
#define USR_F (PREEMPTIBLE | BILLABLE) /* user processes */
/* Define system call traps for the various process types. These call masks
@@ -64,19 +64,26 @@ PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
* processes in the boot image, so that the send mask that is defined here
* can be directly copied onto map[0] of the actual send mask. Privilege
* structure 0 is shared by user processes.
*
* Note that process numbers in the boot image should not be higher than
* "BITCHUNK_BITS - NR_TASKS", because a bitchunk_t field is used to store
* the send masks in the table that describes that processes in the image.
*/
#define s(n) (1 << s_nr_to_id(n))
#define SRV_M (~0)
#define SYS_M (~0)
#define USR_M (s(PM_PROC_NR)|s(FS_PROC_NR)|s(SM_PROC_NR))
#define DRV_M (USR_M | s(SYSTEM)|s(CLOCK)|s(LOG_PROC_NR)|s(TTY_PROC_NR))
/* Sanity check to make sure the send masks can be set. */
extern int dummy[(BITCHUNK_BITS-NR_TASKS > INIT_PROC_NR) ? 1 : -1];
#define USR_M (s(PM_PROC_NR) | s(FS_PROC_NR) | s(SM_PROC_NR))
#define DRV_M (USR_M | s(SYSTEM) | s(CLOCK) | s(LOG_PROC_NR) | s(TTY_PROC_NR))
/* Define kernel calls that processes are allowed to make. This is not looking
* very nice, but we really need to set access rights on a per call basis.
* Note that the system services manager has all bits on, because it should
* be allowed to distribute rights to services that it starts.
*/
#define c(n) (1 << ((n)-KERNEL_CALL))
#define SM_C ~0
#define PM_C ~(c(SYS_DEVIO) | c(SYS_SDEVIO) | c(SYS_VDEVIO) \
| c(SYS_IRQCTL) | c(SYS_INT86))
#define FS_C (c(SYS_KILL) | c(SYS_VIRCOPY) | c(SYS_VIRVCOPY) | c(SYS_UMAP) \
| c(SYS_GETINFO) | c(SYS_EXIT) | c(SYS_TIMES) | c(SYS_SETALARM))
#define DRV_C (FS_C | c(SYS_SEGCTL) | c(SYS_IRQCTL) | c(SYS_INT86) \
| c(SYS_DEVIO) | c(SYS_VDEVIO) | c(SYS_SDEVIO))
/* The system image table lists all programs that are part of the boot image.
* The order of the entries here MUST agree with the order of the programs
@@ -86,25 +93,29 @@ extern int dummy[(BITCHUNK_BITS-NR_TASKS > INIT_PROC_NR) ? 1 : -1];
* initial program counter and stack size is also provided for kernel tasks.
*/
PUBLIC struct boot_image image[] = {
/* process nr, pc, flags, qs, queue, stack, traps, ipc, sys, name */
{ IDLE, idle_task, IDL_F, 32, IDLE_Q, IDL_S, 0, 0, 0, "IDLE" },
{ CLOCK,clock_task, TSK_F, 0, TASK_Q, TSK_S, TSK_T, 0, 0, "CLOCK" },
{ SYSTEM, sys_task, TSK_F, 0, TASK_Q, TSK_S, TSK_T, 0, 0, "SYSTEM" },
{ HARDWARE, 0, TSK_F, 0, TASK_Q, HRD_S, 0, 0, 0, "KERNEL" },
{ PM_PROC_NR, 0, SRV_F, 16, 3, 0, SRV_T, SRV_M, ~0, "pm" },
{ FS_PROC_NR, 0, SRV_F, 16, 4, 0, SRV_T, SRV_M, ~0, "fs" },
{ SM_PROC_NR, 0, SRV_F, 16, 3, 0, SRV_T, SYS_M, ~0, "sm" },
{ TTY_PROC_NR, 0, SRV_F, 16, 1, 0, SRV_T, SYS_M, ~0, "tty" },
{ MEM_PROC_NR, 0, SRV_F, 16, 2, 0, SRV_T, DRV_M, ~0, "memory" },
{ LOG_PROC_NR, 0, SRV_F, 16, 2, 0, SRV_T, SYS_M, ~0, "log" },
{ DRVR_PROC_NR, 0, SRV_F, 16, 2, 0, SRV_T, DRV_M, ~0, "driver" },
{ INIT_PROC_NR, 0, USR_F, 8, USER_Q, 0, USR_T, USR_M, 0, "init" },
/* process nr, pc, flags, qs, queue, stack, traps, ipcto, call, name */
{ IDLE, idle_task, IDL_F, 32, IDLE_Q, IDL_S, 0, 0, 0, "IDLE" },
{ CLOCK,clock_task, TSK_F, 0, TASK_Q, TSK_S, TSK_T, 0, 0, "CLOCK" },
{ SYSTEM, sys_task, TSK_F, 0, TASK_Q, TSK_S, TSK_T, 0, 0, "SYSTEM"},
{ HARDWARE, 0, TSK_F, 0, TASK_Q, HRD_S, 0, 0, 0, "KERNEL"},
{ PM_PROC_NR, 0, SRV_F, 16, 3, 0, SRV_T, SRV_M, PM_C, "pm" },
{ FS_PROC_NR, 0, SRV_F, 16, 4, 0, SRV_T, SRV_M, FS_C, "fs" },
{ SM_PROC_NR, 0, SRV_F, 16, 3, 0, SRV_T, SYS_M, SM_C, "sm" },
{ TTY_PROC_NR, 0, SRV_F, 16, 1, 0, SRV_T, SYS_M, DRV_C, "tty" },
{ MEM_PROC_NR, 0, SRV_F, 16, 2, 0, SRV_T, DRV_M, DRV_C, "memory"},
{ LOG_PROC_NR, 0, SRV_F, 16, 2, 0, SRV_T, SYS_M, DRV_C, "log" },
{ DRVR_PROC_NR, 0, SRV_F, 16, 2, 0, SRV_T, SYS_M, DRV_C, "driver"},
{ INIT_PROC_NR, 0, USR_F, 8, USER_Q, 0, USR_T, USR_M, 0, "init" },
};
/* Verify the size of the system image table at compile time. If the number
* is not correct, the size of the 'dummy' array will be negative, causing
* a compile time error. Note that no space is allocated because 'dummy' is
* declared extern.
*/
/* Verify the size of the system image table at compile time. Also verify that
* the first chunk of the ipc mask has enough bits to accommodate the processes
* in the image.
* If a problem is detected, the size of the 'dummy' array will be negative,
* causing a compile time error. Note that no space is actually allocated
* because 'dummy' is declared extern.
*/
extern int dummy[(NR_BOOT_PROCS==sizeof(image)/sizeof(struct boot_image))?1:-1];
extern int dummy[(BITCHUNK_BITS > NR_BOOT_PROCS - 1) ? 1 : -1];

View File

@@ -17,9 +17,9 @@ struct boot_image {
char quantum; /* quantum (tick count) */
int priority; /* scheduling priority */
int stksize; /* stack size for tasks */
short call_mask; /* allowed system call traps */
bitchunk_t send_mask; /* send mask protection */
long sys_mask; /* system call protection */
short trap_mask; /* allowed system call traps */
bitchunk_t ipc_to; /* send mask protection */
long call_mask; /* system call protection */
char proc_name[P_NAME_LEN]; /* name in process table */
};