From: Jorrit Herder Date: Tue, 2 Aug 2005 15:28:09 +0000 (+0000) Subject: Cleaned up table. Moved policies to table. X-Git-Tag: v3.1.0~482 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/cppcheck-error.log?a=commitdiff_plain;h=ab7c0a9926d81e597df2118e2eef9a5f9d8fa4bc;p=minix.git Cleaned up table. Moved policies to table. Small fixes to do_copy, do_privctl and do_fork. --- diff --git a/kernel/ipc.h b/kernel/ipc.h index ffff3cf2c..04b86acd7 100644 --- a/kernel/ipc.h +++ b/kernel/ipc.h @@ -7,8 +7,6 @@ #define SYSCALL_FUNC 0x0F /* mask for system call function */ #define SYSCALL_FLAGS 0xF0 /* mask for system call flags */ #define NON_BLOCKING 0x10 /* prevent blocking, return error */ -#define FRESH_ANSWER 0x20 /* ignore pending notifications as answer */ - /* (default behaviour for SENDREC calls) */ /* System call numbers that are passed when trapping to the kernel. The * numbers are carefully defined so that it can easily be seen (based on @@ -25,13 +23,6 @@ #define CHECK_DST 0x05 /* 0 1 0 1 : validate message destination */ #define CHECK_SRC 0x02 /* 0 0 1 0 : validate message source */ -/* Call masks indicating which system calls (traps) a process can make. - * System processes can do anything; user processes are highly restricted. - */ -#define EMPTY_MASK (0) -#define FILLED_MASK (~0) -#define TASK_CALL_MASK (1 << RECEIVE) -#define USER_CALL_MASK ((1 << SENDREC) | (1 << ECHO)) /* Send masks determine to whom processes can send messages or notifications. * The values here are used for the processes in the boot image. We rely on @@ -44,13 +35,12 @@ * "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_nr_to_id(n) (NR_TASKS + (n) + 1) -#define s(n) (1 << s_nr_to_id(n)) -#define USER_SEND_MASK (s(PM_PROC_NR) | s(FS_PROC_NR)) -#define DRIVER_SEND_MASK (s(PM_PROC_NR) | s(FS_PROC_NR) | s(SYSTEM) | \ - s(CLOCK) | s(PRINTF_PROC) | s(TTY)) -#define SERVER_SEND_MASK (~0) -#define SYSTEM_SEND_MASK (~1) +#define s_nr_to_id(n) (NR_TASKS + (n) + 1) +#define s(n) (1 << s_nr_to_id(n)) +#define SERV_M (~0) +#define SYST_M (~0) +#define USER_M (s(PM_PROC_NR)|s(FS_PROC_NR)|s(SM_PROC_NR)) +#define DRIV_M (USER_M | s(SYSTEM)|s(CLOCK)|s(LOG_PROC_NR)|s(TTY)) /* Sanity check to make sure the send masks can be set. */ extern int dummy[(BITCHUNK_BITS-NR_TASKS > INIT_PROC_NR) ? 1 : -1]; diff --git a/kernel/proc.c b/kernel/proc.c index ddba8b1fa..9cae2905c 100755 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -117,8 +117,10 @@ message *m_ptr; /* pointer to message in the caller's space */ return(ECALLDENIED); /* Require a valid source and/ or destination process, unless echoing. */ - if (! (isokprocn(src_dst) || src_dst == ANY || function == ECHO)) + if (! (isokprocn(src_dst) || src_dst == ANY || function == ECHO)) { + kprintf("sys_call: function %d, src_dst %d\n", function, src_dst); return(EBADSRCDST); + } /* If the call involves a message buffer, i.e., for SEND, RECEIVE, SENDREC, * or ECHO, check the message pointer. This check allows a message to be diff --git a/kernel/proc.h b/kernel/proc.h index e40beb234..6e5bc8da3 100755 --- a/kernel/proc.h +++ b/kernel/proc.h @@ -66,6 +66,7 @@ struct proc { #define SIGNALED 0x10 /* set when new kernel signal arrives */ #define SIG_PENDING 0x20 /* unready while signal being processed */ #define P_STOP 0x40 /* set when process is being traced */ +#define NO_PRIV 0x80 /* keep forked system process from running */ /* Scheduling priorities for p_priority. Values must start at zero (highest * priority) and increment. Priorities of the processes in the boot image can diff --git a/kernel/system/do_copy.c b/kernel/system/do_copy.c index 9212329cb..d685a4cfa 100644 --- a/kernel/system/do_copy.c +++ b/kernel/system/do_copy.c @@ -27,7 +27,7 @@ register message *m_ptr; /* pointer to request message */ * are two different system calls so that permissions can be checked. */ struct vir_addr vir_addr[2]; /* virtual source and destination address */ - vir_bytes bytes; /* number of bytes to copy */ + phys_bytes bytes; /* number of bytes to copy */ int i; /* Dismember the command message. */ diff --git a/kernel/system/do_fork.c b/kernel/system/do_fork.c index a342d2e6b..a68f65250 100644 --- a/kernel/system/do_fork.c +++ b/kernel/system/do_fork.c @@ -32,17 +32,19 @@ register message *m_ptr; /* pointer to request message */ rpc = proc_addr(m_ptr->PR_PROC_NR); if (isemptyp(rpp) || ! isemptyp(rpc)) return(EINVAL); - /* If this is a system process, make sure the child process gets its own - * privilege structure for accounting. This is the only part that can fail, - * so do this before allocating the process table slot. +#if DEAD_CODE + /* If the parent is a privileged process, ensure the child process also gets + * its own privilege structure for accounting. This is the only part that can + * fail, so do this before allocating the process table slot. */ - if (priv(rpc)->s_flags & SYS_PROC) { + if (priv(rpp)->s_flags & SYS_PROC) { if (OK != (i=get_priv(rpc, SYS_PROC))) return(i); /* get structure */ for (i=0; i< BITMAP_CHUNKS(NR_SYS_PROCS); i++) /* remove pending: */ priv(rpc)->s_notify_pending.chunk[i] = 0; /* - notifications */ priv(rpc)->s_int_pending = 0; /* - interrupts */ sigemptyset(&priv(rpc)->s_sig_pending); /* - signals */ } +#endif /* Copy parent 'proc' struct to child. And reinitialize some fields. */ #if (CHIP == INTEL) @@ -63,6 +65,14 @@ register message *m_ptr; /* pointer to request message */ rpc->p_user_time = 0; /* set all the accounting times to 0 */ rpc->p_sys_time = 0; + /* If the parent is a privileged process, take away the privileges from the + * child process and inhibit it from running by setting the NO_PRIV flag. + * The caller should explicitely set the new privileges before executing. + */ + if (priv(rpp)->s_flags & SYS_PROC) { + rpc->p_priv = priv_addr(USER_PRIV_ID); + rpc->p_rts_flags |= NO_PRIV; + } return(OK); } diff --git a/kernel/system/do_privctl.c b/kernel/system/do_privctl.c index 0882569c8..3fbf495e4 100644 --- a/kernel/system/do_privctl.c +++ b/kernel/system/do_privctl.c @@ -2,14 +2,17 @@ * m_type: SYS_PRIVCTL * * The parameters for this system call are: - * m2_i1: CTL_PROC_NR (process number of caller) + * m1_i1: PR_PROC_NR (process number of caller) */ #include "../system.h" #include "../ipc.h" +#include #if USE_PRIVCTL +#define FILLED_MASK (~0) + /*===========================================================================* * do_privctl * *===========================================================================*/ @@ -19,21 +22,40 @@ message *m_ptr; /* pointer to request message */ /* Handle sys_privctl(). Update a process' privileges. If the process is not * yet a system process, make sure it gets its own privilege structure. */ + register struct proc *caller_ptr; register struct proc *rp; register struct priv *sp; int proc_nr; + int priv_id; + int old_flags; int i; - /* Extract message parameters. */ - proc_nr = m_ptr->CTL_PROC_NR; - if (proc_nr == SELF) proc_nr = m_ptr->m_source; + /* Check whether caller is allowed to make this call. Privileged proceses + * can only update the privileges of processes that are inhibited from + * running by the NO_PRIV flag. This flag is set when a privileged process + * forks. + */ + caller_ptr = proc_addr(m_ptr->m_source); + if (! (priv(caller_ptr)->s_flags & SYS_PROC)) return(EPERM); + proc_nr = m_ptr->PR_PROC_NR; if (! isokprocn(proc_nr)) return(EINVAL); - rp = proc_addr(proc_nr); + if (! (rp->p_rts_flags & NO_PRIV)) return(EPERM); - /* Make sure this process has its own privileges structure. */ - if (! (priv(rp)->s_flags & SYS_PROC)) - if ((i=get_priv(rp, SYS_PROC)) != OK) return(i); + /* Make sure this process has its own privileges structure. This may fail, + * since there are only a limited number of system processes. Then copy the + * privileges from the caller and restore some defaults. + */ + if ((i=get_priv(rp, SYS_PROC)) != OK) return(i); + priv_id = priv(rp)->s_id; /* backup privilege id */ + *priv(rp) = *priv(caller_ptr); /* copy privileges */ + priv(rp)->s_id = priv_id; /* restore privilege id */ + priv(rp)->s_proc_nr = proc_nr; /* reassociate process nr */ + + for (i=0; i< BITMAP_CHUNKS(NR_SYS_PROCS); i++) /* remove pending: */ + priv(rp)->s_notify_pending.chunk[i] = 0; /* - notifications */ + priv(rp)->s_int_pending = 0; /* - interrupts */ + sigemptyset(&priv(rp)->s_sig_pending); /* - signals */ /* Now update the process' privileges as requested. */ rp->p_priv->s_call_mask = FILLED_MASK; @@ -50,6 +72,11 @@ message *m_ptr; /* pointer to request message */ set_sys_bit(priv_addr(i)->s_send_mask, priv_id(rp)); } } + + /* Done. Privileges have been set. Allow process to run again. */ + old_flags = rp->p_rts_flags; /* save value of the flags */ + rp->p_rts_flags &= ~NO_PRIV; + if (old_flags != 0 && rp->p_rts_flags == 0) lock_ready(rp); return(OK); } diff --git a/kernel/table.c b/kernel/table.c index 7aad53114..466c4e9f9 100755 --- a/kernel/table.c +++ b/kernel/table.c @@ -26,7 +26,6 @@ * Oct 17, 2004 updated above and tasktab comments (Jorrit N. Herder) * May 01, 2004 changed struct for system image (Jorrit N. Herder) */ - #define _TABLE #include "kernel.h" @@ -35,75 +34,57 @@ #include #include -/* Define stack sizes for all tasks included in the system image. */ +/* Define stack sizes for the kernel tasks included in the system image. */ #define NO_STACK 0 #define SMALL_STACK (128 * sizeof(char *)) -#if (CHIP == INTEL) /* 3 intr, 3 temps, 4 db */ -#define IDLE_S ((3+3+4) * sizeof(char *)) -#else -#define IDLE_S SMALL_STACK -#endif -#define HARDWARE_S NO_STACK /* dummy task, uses kernel stack */ -#define SYSTEM_S SMALL_STACK -#define CLOCK_S SMALL_STACK +#define IDLE_S SMALL_STACK /* 3 intr, 3 temps, 4 db for Intel */ +#define HRDW_S NO_STACK /* dummy task, uses kernel stack */ +#define TASK_S SMALL_STACK /* system and clock task */ /* Stack space for all the task stacks. Declared as (char *) to align it. */ -#define TOT_STACK_SPACE (IDLE_S + HARDWARE_S + CLOCK_S + SYSTEM_S) +#define TOT_STACK_SPACE (IDLE_S + HRDW_S + (2 * TASK_S)) PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)]; +/* Define flags for the various process types. */ +#define IDLE_F (BILLABLE | SYS_PROC) /* idle task */ +#define TASK_F (SYS_PROC) /* kernel tasks */ +#define SERV_F (PREEMPTIBLE | SYS_PROC) /* system services */ +#define USER_F (PREEMPTIBLE | BILLABLE) /* user processes */ + +/* Define system call traps for the various process types. These call masks + * determine what system call traps a process is allowed to make. + */ +#define TASK_T (1 << RECEIVE) /* clock and system */ +#define SERV_T (~0) /* system services */ +#define USER_T ((1 << SENDREC) | (1 << ECHO)) /* user processes */ + /* 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 * in the boot image and all kernel tasks must come first. - * Each entry provides the process number, type, scheduling priority, send - * mask, and a name for the process table. For kernel processes, the startup - * routine and stack size is also provided. + * Each entry provides the process number, flags, quantum size (qs), scheduling + * queue, allowed traps, ipc mask, and a name for the process table. The + * initial program counter and stack size is also provided for kernel tasks. */ -#define USER_F (PREEMPTIBLE | BILLABLE) -#define IDLE_F (BILLABLE | SYS_PROC) -#define SYS_F (PREEMPTIBLE | SYS_PROC) -#define TASK_F (SYS_PROC) - -#define IDLE_T 32 /* ticks */ -#define USER_T 8 /* ticks */ -#define SYS_T 16 /* ticks */ - PUBLIC struct boot_image image[] = { - { IDLE, idle_task, IDLE_F, IDLE_T, IDLE_Q, IDLE_S, EMPTY_MASK, EMPTY_MASK, "IDLE" }, - { CLOCK, clock_task, TASK_F, SYS_T, TASK_Q, CLOCK_S, TASK_CALL_MASK, SYSTEM_SEND_MASK, "CLOCK" }, - { SYSTEM, sys_task, TASK_F, SYS_T, TASK_Q, SYSTEM_S, TASK_CALL_MASK, SYSTEM_SEND_MASK, "SYSTEM" }, - { HARDWARE, 0, TASK_F, SYS_T, TASK_Q, HARDWARE_S, EMPTY_MASK, SYSTEM_SEND_MASK, "KERNEL" }, - { PM_PROC_NR, 0, SYS_F, SYS_T, 3, 0, FILLED_MASK, SERVER_SEND_MASK, "PM" }, - { FS_PROC_NR, 0, SYS_F, SYS_T, 4, 0, FILLED_MASK, SERVER_SEND_MASK, "FS" }, - { SM_PROC_NR, 0, SYS_F, SYS_T, 3, 0, FILLED_MASK, SYSTEM_SEND_MASK, "SM" }, - { IS_PROC_NR, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "IS" }, - { TTY, 0, SYS_F, SYS_T, 1, 0, FILLED_MASK, SYSTEM_SEND_MASK, "TTY" }, - { MEMORY, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "MEMORY" }, +/* process nr, pc, flags, qs, queue, stack, traps, ipc mask, name */ + { IDLE, idle_task, IDLE_F, 32, IDLE_Q, IDLE_S, 0, 0, "IDLE" }, + { CLOCK, clock_task, TASK_F, 0, TASK_Q, TASK_S, TASK_T, 0, "CLOCK" }, + { SYSTEM, sys_task, TASK_F, 0, TASK_Q, TASK_S, TASK_T, 0, "SYSTEM" }, + { HARDWARE, 0, TASK_F, 0, TASK_Q, HRDW_S, 0, 0, "KERNEL" }, + { PM_PROC_NR, 0, SERV_F, 16, 3, 0, SERV_T, SERV_M, "PM" }, + { FS_PROC_NR, 0, SERV_F, 16, 4, 0, SERV_T, SERV_M, "FS" }, + { SM_PROC_NR, 0, SERV_F, 16, 3, 0, SERV_T, SYST_M, "SM" }, + { TTY, 0, SERV_F, 16, 1, 0, SERV_T, SYST_M, "TTY" }, + { MEMORY, 0, SERV_F, 16, 2, 0, SERV_T, DRIV_M, "MEMORY" }, + { LOG_PROC_NR, 0, SERV_F, 16, 2, 0, SERV_T, SYST_M, "LOG" }, #if ENABLE_AT_WINI - { AT_WINI, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "AT_WINI" }, -#endif -#if ENABLE_FLOPPY - { FLOPPY, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "FLOPPY" }, -#endif -#if ENABLE_PRINTER - { PRINTER, 0, SYS_F, SYS_T, 3, 0, FILLED_MASK, DRIVER_SEND_MASK, "PRINTER" }, -#endif -#if ENABLE_RTL8139 - { RTL8139, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "RTL8139" }, -#endif -#if ENABLE_FXP - { FXP, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "FXP" }, -#endif -#if ENABLE_DPETH - { DPETH, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "DPETH" }, -#endif -#if ENABLE_LOG - { LOG_PROC_NR, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, SYSTEM_SEND_MASK, "LOG" }, + { AT_WINI, 0, SERV_F, 16, 2, 0, SERV_T, DRIV_M, "AT_WINI" }, #endif #if ENABLE_BIOS_WINI - { BIOS_WINI, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, SYSTEM_SEND_MASK, "BIOS" }, + { BIOS_WINI, 0, SERV_F, 16, 2, 0, SERV_T, SYST_M, "BIOS" }, #endif - { INIT_PROC_NR, 0, USER_F, USER_T, USER_Q, 0, USER_CALL_MASK, USER_SEND_MASK, "INIT" }, + { INIT_PROC_NR, 0, USER_F, 8, USER_Q, 0, USER_T, USER_M, "INIT" }, }; /* Verify the size of the system image table at compile time. If the number