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

@ -55,6 +55,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioc_cmos.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
@ -94,8 +95,11 @@ int bcd_to_dec(int n);
int dec_to_bcd(int n);
void usage(void);
#define CMOS_DEV "/dev/cmos"
PUBLIC int main(int argc, char **argv)
{
int fd;
struct tm time1;
struct tm time2;
struct tm tmnow;
@ -105,6 +109,7 @@ PUBLIC int main(int argc, char **argv)
unsigned char mach_id, cmos_state;
struct sysgetenv sysgetenv;
message m;
int request;
/* Process options. */
@ -144,14 +149,17 @@ PUBLIC int main(int argc, char **argv)
/* sleep, unless first iteration */
if (i > 0) sleep(5);
/* get_time(&time1); */
m.m_type = CMOSTIME;
m.ADDRESS = (void *) &time1;
m.REQUEST = y2kflag;
if (0 != (s=sendrec(FS_PROC_NR, &m))) {
fprintf(stderr, "Couldn't get CMOS time from FS: %d.\n",s);
/* Open the CMOS device to read the system time. */
if ((fd = open(CMOS_DEV, O_RDONLY)) < 0) {
fprintf(stderr, "Couldn't open CMOS device: %d.\n",s);
exit(1);
}
request = (y2kflag) ? CIOCGETTIME : CIOCGETTIMEY2K;
if ((s=ioctl(fd, request, (void *) &time1)) < 0) {
fprintf(stderr, "Couldn't do CMOS ioctl: %d.\n",s);
exit(1);
}
close(fd);
now = time(NULL);
@ -159,7 +167,9 @@ PUBLIC int main(int argc, char **argv)
time2 = time1;
rtc= mktime(&time1); /* Transform to a time_t. */
if (rtc != -1) break;
if (rtc != -1) {
break;
}
fprintf(stderr,
"readclock: Invalid time read from CMOS RTC: %d-%02d-%02d %02d:%02d:%02d\n",
@ -168,7 +178,7 @@ PUBLIC int main(int argc, char **argv)
}
if (i >= MAX_RETRIES) exit(1);
/* Set system time. */
/* Now set system time. */
if (nflag) {
printf("stime(%lu)\n", (unsigned long) rtc);
} else {

View file

@ -26,4 +26,5 @@ all install depend clean:
cd ./dpeth && $(MAKE) $@
cd ./log && $(MAKE) $@
cd ./bios_wini && $(MAKE) $@
cd ./cmos && $(MAKE) $@
cd ./random && $(MAKE) $@

View file

@ -352,12 +352,14 @@ message *m_ptr;
return(ENXIO);
}
#if VERBOSE
printf("%s: AT driver detected ", w_name());
if (wn->state & (SMART|ATAPI)) {
printf("%.40s\n", w_id_string);
} else {
printf("%ux%ux%u\n", wn->pcylinders, wn->pheads, wn->psectors);
}
#endif
}
/* Partition the drive if it's being opened for the first time,

49
drivers/cmos/Makefile Normal file
View file

@ -0,0 +1,49 @@
# Makefile for the CMOS driver
DRIVER = cmos
# directories
u = /usr
i = $u/include
s = $i/sys
m = $i/minix
b = $i/ibm
d = ..
# programs, flags, etc.
MAKE = exec make
CC = exec cc
CFLAGS = -I$i
LDFLAGS = -i
LIBS = -lsys -lsysutil
OBJ = cmos.o
LIBDRIVER = $d/libdriver/driver.o
# build local binary
all build: $(DRIVER)
$(DRIVER): $(OBJ) $(LIBDRIVER) readclock.o
$(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBDRIVER) $(LIBS)
install -S 1024w $(DRIVER)
$(CC) -o readclock readclock.c
$(LIBDRIVER):
cd $d/libdriver && $(MAKE)
# install with other drivers
install: /sbin/$(DRIVER)
/sbin/$(DRIVER): $(DRIVER)
install -o root -cs $? $@
# clean up local files
clean:
rm -f $(DRIVER) *.o *.bak
depend:
/usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c ../libdriver/*.c > .depend
# Include generated dependencies.
include .depend

View file

@ -1,12 +1,12 @@
#include "fs.h"
#include <minix/com.h>
#include <minix/callnr.h>
#include <time.h>
#include <ibm/cmos.h>
#include <ibm/bios.h>
/* Manufacturers usually use the ID value of the IBM model they emulate.
/* This file contains a device driver that can access the CMOS chip to
* get or set the system time. It drives the special file:
*
* /dev/cmos - CMOS chip
*
* Changes:
* Aug 04, 2005 Created. Read CMOS time. (Jorrit N. Herder)
*
* Manufacturers usually use the ID value of the IBM model they emulate.
* However some manufacturers, notably HP and COMPAQ, have had different
* ideas in the past.
*
@ -15,20 +15,126 @@
* published by Microsoft Press
*/
#include "../drivers.h"
#include <sys/ioc_cmos.h>
#include <time.h>
#include <ibm/cmos.h>
#include <ibm/bios.h>
extern int errno; /* error number for PM calls */
FORWARD _PROTOTYPE( int gettime, (int who, int y2kflag, vir_bytes dst_time));
FORWARD _PROTOTYPE( void reply, (int reply, int replyee, int proc, int s));
FORWARD _PROTOTYPE( int read_register, (int register_address));
FORWARD _PROTOTYPE( int get_cmostime, (struct tm *tmp, int y2kflag));
FORWARD _PROTOTYPE( int dec_to_bcd, (int dec));
FORWARD _PROTOTYPE( int bcd_to_dec, (int bcd));
/*===========================================================================*
* main *
*===========================================================================*/
PUBLIC void main(void)
{
message m;
int y2kflag;
int result;
int suspended = NONE;
int s;
PUBLIC int do_cmostime(void)
while(TRUE) {
/* Get work. */
if (OK != (s=receive(ANY, &m)))
panic("CMOS", "attempt to receive work failed", s);
/* Handle request. */
switch(m.m_type) {
case DEV_OPEN:
case DEV_CLOSE:
case CANCEL:
reply(TASK_REPLY, m.m_source, m.PROC_NR, OK);
break;
case DEV_IOCTL:
/* Probably best to SUSPEND the caller, CMOS I/O has nasty timeouts.
* This way we don't block the rest of the system. First check if
* another process is already suspended. We cannot handle multiple
* requests at a time.
*/
if (suspended != NONE) {
reply(TASK_REPLY, m.m_source, m.PROC_NR, EBUSY);
break;
}
suspended = m.PROC_NR;
reply(TASK_REPLY, m.m_source, m.PROC_NR, SUSPEND);
switch(m.REQUEST) {
case CIOCGETTIME: /* get CMOS time */
case CIOCGETTIMEY2K:
y2kflag = (m.REQUEST = CIOCGETTIME) ? 0 : 1;
result = gettime(m.PROC_NR, y2kflag, (vir_bytes) m.ADDRESS);
break;
case CIOCSETTIME:
case CIOCSETTIMEY2K:
default: /* unsupported ioctl */
result = ENOSYS;
}
/* Request completed. Tell the caller to check our status. */
notify(m.m_source);
break;
case DEV_STATUS:
/* The FS calls back to get our status. Revive the suspended
* processes and return the status of reading the CMOS.
*/
if (suspended == NONE)
reply(DEV_NO_STATUS, m.m_source, NONE, OK);
else
reply(DEV_REVIVE, m.m_source, suspended, result);
suspended = NONE;
break;
case SYN_ALARM: /* shouldn't happen */
case SYS_SIG: /* ignore system events */
continue;
default:
reply(TASK_REPLY, m.m_source, m.PROC_NR, EINVAL);
}
}
}
/*===========================================================================*
* reply *
*===========================================================================*/
PRIVATE void reply(int code, int replyee, int process, int status)
{
message m;
int s;
m.m_type = code; /* TASK_REPLY or REVIVE */
m.REP_STATUS = status; /* result of device operation */
m.REP_PROC_NR = process; /* which user made the request */
if (OK != (s=send(replyee, &m)))
panic("CMOS", "sending reply failed", s);
}
/*===========================================================================*
* gettime *
*===========================================================================*/
PRIVATE int gettime(int who, int y2kflag, vir_bytes dst_time)
{
unsigned char mach_id, cmos_state;
struct tm time1;
int i, s;
int y2kflag = m_in.REQUEST;
vir_bytes dst_time = (vir_bytes) m_in.ADDRESS;
/* First obtain the machine ID to see if we can read the CMOS clock. Only
* for PS_386 and PC_AT this is possible. Otherwise, return an error.

View file

@ -29,11 +29,6 @@ $(DRIVER): $(OBJ) $(LIBDRIVER)
$(LIBDRIVER):
cd $d/libdriver && $(MAKE)
aes/rijndael_api.o:
$(CC) -c -o $@ aes/rijndael_api.c
aes/rijndael_alg.o:
$(CC) -c -o $@ aes/rijndael_alg.c
# install with other drivers
install: /usr/sbin/$(DRIVER)

View file

@ -9,7 +9,6 @@
*
* Changes:
* Apr 29, 2005 added null byte generator (Jorrit N. Herder)
* Apr 27, 2005 added random device handling (Jorrit N. Herder)
* Apr 09, 2005 added support for boot device (Jorrit N. Herder)
* Jul 26, 2004 moved RAM driver to user-space (Jorrit N. Herder)
* Apr 20, 1992 device dependent/independent split (Kees J. Bot)

View file

@ -874,7 +874,7 @@ tty_t *tp;
* is updated automatically later.
*/
scroll_screen(cons, SCROLL_UP);
cons->c_row = scr_lines-1;
cons->c_row = scr_lines - 1;
cons->c_column = 0;
}
select_console(0);

View file

@ -181,6 +181,7 @@ PUBLIC void main(void)
panic("TTY","Couldn't obtain kernel environment.", s);
}
printf("\n");
while (TRUE) {
/* Check for and handle any events on any of the ttys. */

20
etc/rc
View file

@ -11,6 +11,20 @@ usage()
exec intr sh
}
up()
{
service=$1
args=$2
device=$3
# Function to dynamically start a system service
command="/sbin/$service"
if [ ! -z "$args" ]; then command="$command -args \"$args\""; fi
if [ ! -z "$device" ]; then command="$command -dev \"$device\""; fi
echo -n " $service"
eval service up $command
}
while getopts 'saf' opt
do
case $opt in
@ -37,6 +51,12 @@ start)
# National keyboard?
test -f /etc/keymap && loadkeys /etc/keymap
# Start crucial system services
echo -n "Starting services:"
up is ""
up cmos "" /dev/cmos
echo .
# Set timezone.
. /etc/profile

View file

@ -75,7 +75,7 @@ start)
rm -rf /tmp/. /usr/run/. /usr/spool/lpd/. /usr/spool/locks/.
# Start servers and drivers set at the boot monitor.
echo -n "Starting services:"
echo -n "More services:"
up random "" /dev/random
# load random number generator
@ -95,7 +95,6 @@ start)
fi
done
up inet ""
up is ""
up printer "" /dev/lp
# up floppy "" /dev/fd0
echo .

View file

@ -66,7 +66,7 @@
/* MINIX specific calls, e.g., to support system services. */
#define SVRCTL 77
#define CMOSTIME 78 /* to FS */
/* unused */
#define GETSYSINFO 79 /* to PM or FS */
#define GETPROCNR 80 /* to PM */
#define DEVCTL 81 /* to FS */

View file

@ -135,7 +135,7 @@
* Messages for networking layer *
*===========================================================================*/
/* Message types for network layer requests. */
/* Message types for network layer requests. This layer acts like a driver. */
#define NW_OPEN DEV_OPEN
#define NW_CLOSE DEV_CLOSE
#define NW_READ DEV_READ
@ -143,18 +143,22 @@
#define NW_IOCTL DEV_IOCTL
#define NW_CANCEL CANCEL
/* Base type for data link layer requests and responses. */
#define DL_RQ_BASE 0x800
#define DL_RS_BASE 0x900
/* Message types for data link layer requests. */
#define DL_WRITE 3
#define DL_WRITEV 4
#define DL_READ 5
#define DL_READV 6
#define DL_INIT 7
#define DL_STOP 8
#define DL_GETSTAT 9
#define DL_WRITE (DL_RQ_BASE + 3)
#define DL_WRITEV (DL_RQ_BASE + 4)
#define DL_READ (DL_RQ_BASE + 5)
#define DL_READV (DL_RQ_BASE + 6)
#define DL_INIT (DL_RQ_BASE + 7)
#define DL_STOP (DL_RQ_BASE + 8)
#define DL_GETSTAT (DL_RQ_BASE + 9)
/* Message type for data link layer replies. */
#define DL_INIT_REPLY 20
#define DL_TASK_REPLY 21
#define DL_INIT_REPLY (DL_RS_BASE + 20)
#define DL_TASK_REPLY (DL_RS_BASE + 21)
/* Field names for data link layer messages. */
#define DL_PORT m2_i1
@ -187,41 +191,41 @@
*/
#define KERNEL_CALL 0x600 /* base for kernel calls to SYSTEM */
# define SYS_TIMES (KERNEL_CALL + 0) /* sys_times() */
# define SYS_EXIT (KERNEL_CALL + 1) /* sys_exit() */
# define SYS_GETKSIG (KERNEL_CALL + 2) /* sys_getsig() */
# define SYS_ENDKSIG (KERNEL_CALL + 3) /* sys_endsig() */
# define SYS_FORK (KERNEL_CALL + 4) /* sys_fork() */
# define SYS_NEWMAP (KERNEL_CALL + 5) /* sys_newmap() */
# define SYS_FORK (KERNEL_CALL + 0) /* sys_fork() */
# define SYS_EXEC (KERNEL_CALL + 1) /* sys_exec() */
# define SYS_EXIT (KERNEL_CALL + 2) /* sys_exit() */
# define SYS_NICE (KERNEL_CALL + 3) /* sys_nice() */
# define SYS_PRIVCTL (KERNEL_CALL + 4) /* sys_privctl() */
# define SYS_TRACE (KERNEL_CALL + 5) /* sys_trace() */
# define SYS_KILL (KERNEL_CALL + 6) /* sys_kill() */
# define SYS_EXEC (KERNEL_CALL + 7) /* sys_exec() */
# define SYS_SIGSEND (KERNEL_CALL + 8) /* sys_sigsend() */
# define SYS_ABORT (KERNEL_CALL + 9) /* sys_abort() */
# define SYS_KILL (KERNEL_CALL + 10) /* sys_kill() */
# define SYS_UMAP (KERNEL_CALL + 11) /* sys_umap() */
# define SYS_GETKSIG (KERNEL_CALL + 7) /* sys_getsig() */
# define SYS_ENDKSIG (KERNEL_CALL + 8) /* sys_endsig() */
# define SYS_SIGSEND (KERNEL_CALL + 9) /* sys_sigsend() */
# define SYS_SIGRETURN (KERNEL_CALL + 10) /* sys_sigreturn() */
# define SYS_TRACE (KERNEL_CALL + 13) /* sys_trace() */
# define SYS_SETALARM (KERNEL_CALL + 16) /* sys_setalarm() */
# define SYS_NEWMAP (KERNEL_CALL + 11) /* sys_newmap() */
# define SYS_SEGCTL (KERNEL_CALL + 12) /* sys_segctl() */
# define SYS_MEMSET (KERNEL_CALL + 13) /* sys_memset() */
# define SYS_UMAP (KERNEL_CALL + 14) /* sys_umap() */
# define SYS_VIRCOPY (KERNEL_CALL + 15) /* sys_vircopy() */
# define SYS_PHYSCOPY (KERNEL_CALL + 16) /* sys_physcopy() */
# define SYS_VIRVCOPY (KERNEL_CALL + 17) /* sys_virvcopy() */
# define SYS_PHYSVCOPY (KERNEL_CALL + 18) /* sys_physvcopy() */
# define SYS_PRIVCTL (KERNEL_CALL + 19) /* sys_privctl() */
# define SYS_SDEVIO (KERNEL_CALL + 20) /* sys_sdevio() */
# define SYS_SIGRETURN (KERNEL_CALL + 21) /* sys_sigreturn() */
# define SYS_GETINFO (KERNEL_CALL + 22) /* sys_getinfo() */
# define SYS_DEVIO (KERNEL_CALL + 23) /* sys_devio() */
# define SYS_VDEVIO (KERNEL_CALL + 24) /* sys_vdevio() */
# define SYS_IRQCTL (KERNEL_CALL + 25) /* sys_irqctl() */
# define SYS_SEGCTL (KERNEL_CALL + 28) /* sys_segctl() */
# define SYS_IRQCTL (KERNEL_CALL + 19) /* sys_irqctl() */
# define SYS_INT86 (KERNEL_CALL + 20) /* sys_int86() */
# define SYS_DEVIO (KERNEL_CALL + 21) /* sys_devio() */
# define SYS_SDEVIO (KERNEL_CALL + 22) /* sys_sdevio() */
# define SYS_VDEVIO (KERNEL_CALL + 23) /* sys_vdevio() */
# define SYS_VIRCOPY (KERNEL_CALL + 30) /* sys_vircopy() */
# define SYS_PHYSCOPY (KERNEL_CALL + 31) /* sys_physcopy() */
# define SYS_VIRVCOPY (KERNEL_CALL + 32) /* sys_virvcopy() */
# define SYS_MEMSET (KERNEL_CALL + 33) /* sys_memset() */
# define SYS_NICE (KERNEL_CALL + 34) /* sys_nice() */
# define SYS_INT86 (KERNEL_CALL + 35) /* sys_int86() */
#define NR_SYS_CALLS 36 /* number of system calls */
# define SYS_SETALARM (KERNEL_CALL + 24) /* sys_setalarm() */
# define SYS_TIMES (KERNEL_CALL + 25) /* sys_times() */
# define SYS_GETINFO (KERNEL_CALL + 26) /* sys_getinfo() */
# define SYS_ABORT (KERNEL_CALL + 27) /* sys_abort() */
#define NR_SYS_CALLS 28 /* number of system calls */
/* Field names for SYS_MEMSET, SYS_SEGCTL. */
#define MEM_PTR m2_p1 /* base */

15
include/sys/ioc_cmos.h Executable file
View file

@ -0,0 +1,15 @@
/* sys/ioc_cmos.h - CMOS ioctl() command codes.
*/
#ifndef _S_I_CMOS_H
#define _S_I_CMOS_H
#include <minix/ioctl.h>
#define CIOCGETTIME _IOR('c', 1, u32_t)
#define CIOCGETTIMEY2K _IOR('c', 2, u32_t)
#define CIOCSETTIME _IOW('c', 3, u32_t)
#define CIOCSETTIMEY2K _IOW('c', 4, u32_t)
#endif /* _S_I_CMOS_H */

View file

@ -18,6 +18,7 @@
#include <sys/ioc_disk.h> /* 'd' */
#include <sys/ioc_file.h> /* 'f' */
#include <sys/ioc_memory.h> /* 'm' */
#include <sys/ioc_cmos.h> /* 'c' */
#include <sys/ioc_tape.h> /* 'M' */
#include <sys/ioc_scsi.h> /* 'S' */
#include <sys/ioc_sound.h> /* 's' */

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 */
};

View file

@ -16,7 +16,7 @@ LIBS = -lsys -lsysutil -ltimers
OBJ = main.o open.o read.o write.o pipe.o dmap.o \
device.o path.o mount.o link.o super.o inode.o \
cache.o cache2.o filedes.o stadir.o protect.o time.o \
cmostime.o lock.o misc.o utility.o select.o timers.o table.o \
lock.o misc.o utility.o select.o timers.o table.o \
cdprobe.o
# build local binary

View file

@ -50,6 +50,7 @@ struct dmap dmap[NR_DEVICES] = {
DT(0, gen_opcl, gen_io, NONE, DMAP_MUTABLE) /*14 = /dev/mixer */
DT(1, gen_opcl, gen_io, LOG_PROC_NR, 0) /*15 = /dev/klog */
DT(0, gen_opcl, gen_io, NONE, DMAP_MUTABLE) /*16 = /dev/random */
DT(0, gen_opcl, gen_io, NONE, DMAP_MUTABLE) /*17 = /dev/cmos */
#endif /* IBM_PC */
};
@ -61,7 +62,6 @@ PUBLIC int do_devctl()
{
int result;
switch(m_in.ctl_req) {
case DEV_MAP:
/* Try to update device mapping. */

View file

@ -366,7 +366,7 @@ PRIVATE void load_ram(void)
return;
/* Copy the blocks one at a time from the image to the RAM disk. */
printf("Loading RAM disk onto /dev/ram:\33[23CLoaded: 0K ");
printf("Loading RAM disk onto /dev/ram:\33[23CLoaded: 0 KB");
inode[0].i_mode = I_BLOCK_SPECIAL; /* temp inode for rahead() */
inode[0].i_size = LONG_MAX;
@ -398,7 +398,8 @@ PRIVATE void load_ram(void)
put_block(bp1, FULL_DATA_BLOCK);
}
put_block(bp, FULL_DATA_BLOCK);
printf("\b\b\b\b\b\b\b\b%6ldK ", ((long) b * block_size_image)/1024L);
if (b % 11 == 0)
printf("\b\b\b\b\b\b\b\b\b%6ld KB", ((long) b * block_size_image)/1024L);
}
/* Commit changes to RAM so dev_io will see it. */

View file

@ -164,9 +164,6 @@ _PROTOTYPE( int get_block_size, (dev_t dev) );
_PROTOTYPE( int do_stime, (void) );
_PROTOTYPE( int do_utime, (void) );
/* cmostime.c */
_PROTOTYPE( int do_cmostime, (void) );
/* utility.c */
_PROTOTYPE( time_t clock_time, (void) );
_PROTOTYPE( unsigned conv2, (int norm, int w) );

View file

@ -95,7 +95,7 @@ PUBLIC _PROTOTYPE (int (*call_vec[]), (void) ) = {
do_reboot, /* 76 = reboot */
do_svrctl, /* 77 = svrctl */
do_cmostime, /* 78 = cmostime */
no_sys, /* 78 = unused */
do_getsysinfo, /* 79 = getsysinfo */
no_sys, /* 80 = unused */
do_devctl, /* 81 = devctl */

View file

@ -26,8 +26,8 @@ $(SERVER): $(OBJ)
# install -S 256w $@
# install with other servers
install: /usr/sbin/$(SERVER)
/usr/sbin/$(SERVER): $(SERVER)
install: /sbin/$(SERVER)
/sbin/$(SERVER): $(SERVER)
install -o root -c $? $@
# install -o root -cs $? $@

View file

@ -189,25 +189,25 @@ PUBLIC void image_dmp()
{
int m, i,j,r;
struct boot_image *ip;
static char send_mask[BITCHUNK_BITS*2];
static char ipc_to[BITCHUNK_BITS*2];
if ((r = sys_getimage(image)) != OK) {
report("IS","warning: couldn't get copy of image table", r);
return;
}
printf("Image table dump showing all processes included in system image.\n");
printf("---name-- -nr- -flags- -traps- -sq- ----pc- -stack- -sendmask[0]------\n");
printf("---name-- -nr- -flags- -traps- -sq- ----pc- -stack- -ipc_to[0]--------\n");
for (m=0; m<NR_BOOT_PROCS; m++) {
ip = &image[m];
for (i=j=0; i < BITCHUNK_BITS; i++, j++) {
send_mask[j] = (ip->send_mask & (1<<i)) ? '1' : '0';
if (i % 8 == 7) send_mask[++j] = ' ';
ipc_to[j] = (ip->ipc_to & (1<<i)) ? '1' : '0';
if (i % 8 == 7) ipc_to[++j] = ' ';
}
send_mask[j] = '\0';
ipc_to[j] = '\0';
printf("%8s %4d %s %s %3d %7lu %7lu %s\n",
ip->proc_name, ip->proc_nr,
s_flags_str(ip->flags), s_traps_str(ip->call_mask),
ip->priority, (long)ip->initial_pc, ip->stksize, send_mask);
s_flags_str(ip->flags), s_traps_str(ip->trap_mask),
ip->priority, (long)ip->initial_pc, ip->stksize, ipc_to);
}
printf("\n");
}
@ -344,7 +344,7 @@ PUBLIC void privileges_dmp()
register struct proc *rp;
static struct proc *oldrp = BEG_PROC_ADDR;
register struct priv *sp;
static char send_mask[NR_SYS_PROCS + 1 + NR_SYS_PROCS/8];
static char ipc_to[NR_SYS_PROCS + 1 + NR_SYS_PROCS/8];
int r, i,j, n = 0;
/* First obtain a fresh copy of the current process and system table. */
@ -357,7 +357,7 @@ PUBLIC void privileges_dmp()
return;
}
printf("\n--nr-id-name---- -flags- -traps- -send mask------------------------- \n");
printf("\n--nr-id-name---- -flags- -traps- -ipc_to mask------------------------ \n");
for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
if (isemptyp(rp)) continue;
@ -373,15 +373,15 @@ PUBLIC void privileges_dmp()
}
printf("(%02u) %-7.7s %s %s ",
sp->s_id, rp->p_name,
s_flags_str(sp->s_flags), s_traps_str(sp->s_call_mask)
s_flags_str(sp->s_flags), s_traps_str(sp->s_trap_mask)
);
for (i=j=0; i < NR_SYS_PROCS; i++, j++) {
send_mask[j] = get_sys_bit(sp->s_send_mask, i) ? '1' : '0';
if (i % 8 == 7) send_mask[++j] = ' ';
ipc_to[j] = get_sys_bit(sp->s_ipc_to, i) ? '1' : '0';
if (i % 8 == 7) ipc_to[++j] = ' ';
}
send_mask[j] = '\0';
ipc_to[j] = '\0';
printf(" %s \n", send_mask);
printf(" %s \n", ipc_to);
}
if (rp == END_PROC_ADDR) rp = BEG_PROC_ADDR; else printf("--more--\r");
oldrp = rp;

View file

@ -193,8 +193,6 @@ PUBLIC int do_kill()
{
/* Perform the kill(pid, signo) system call. */
DEBUG(m_in.pid == 11, printf("PM: detected do_kill PRINTER\n"));
return check_sig(m_in.pid, m_in.sig_nr);
}
@ -417,7 +415,6 @@ int signo; /* signal to send to process (1 to _NSIG) */
}
/* Some signals are ignored by default. */
if (sigismember(&rmp->mp_ignore, signo)) {
DEBUG(m_in.pid == 11, printf("PM: sig_proc ignored sig\n"));
return;
}
if (sigismember(&rmp->mp_sigmask, signo)) {
@ -434,7 +431,6 @@ int signo; /* signal to send to process (1 to _NSIG) */
sigflags = rmp->mp_sigact[signo].sa_flags;
if (sigismember(&rmp->mp_catch, signo)) {
DEBUG(m_in.pid == 11, printf("PM: sig_proc catch sig!\n"));
if (rmp->mp_flags & SIGSUSPENDED)
sm.sm_mask = rmp->mp_sigmask2;
else
@ -464,7 +460,6 @@ int signo; /* signal to send to process (1 to _NSIG) */
rmp->mp_sigact[signo].sa_handler = SIG_DFL;
}
DEBUG(m_in.pid == 11, printf("PM: sig_proc about to call sys_sigsend for %d \n",slot));
if (OK == (s=sys_sigsend(slot, &sm))) {
sigdelset(&rmp->mp_sigpending, signo);
@ -483,7 +478,6 @@ int signo; /* signal to send to process (1 to _NSIG) */
}
doterminate:
DEBUG(m_in.pid == 11, printf("PM: sig_proc doterminate\n"));
/* Signal should not or cannot be caught. Take default action. */
if (sigismember(&ign_sset, signo)) return;
@ -499,7 +493,6 @@ doterminate:
tell_fs(CHDIR, slot, FALSE, 0);
dump_core(rmp);
}
DEBUG(m_in.pid == 11, printf("PM: about to exit proc\n"));
mm_exit(rmp, 0); /* terminate process */
}

View file

@ -94,7 +94,7 @@ _PROTOTYPE (int (*call_vec[NCALLS]), (void) ) = {
do_reboot, /* 76 = reboot */
do_svrctl, /* 77 = svrctl */
no_sys, /* 78 = cmostime */
no_sys, /* 78 = unused */
do_getsysinfo, /* 79 = getsysinfo */
do_getprocnr, /* 80 = getprocnr */
no_sys, /* 81 = unused */

View file

@ -45,15 +45,16 @@ PUBLIC int do_start(message *m_ptr)
command[m_ptr->SRV_PATH_LEN] = '\0';
if (command[0] != '/') return(EINVAL);
args[0] = command;
if (m_ptr->SRV_ARGS_LEN > 0) {
if (m_ptr->SRV_ARGS_LEN > MAX_ARGS_LEN) return(E2BIG);
if (OK != (s=sys_datacopy(m_ptr->m_source, (vir_bytes) m_ptr->SRV_ARGS_ADDR,
SELF, (vir_bytes) arg_buf, m_ptr->SRV_ARGS_LEN))) return(s);
arg_buf[m_ptr->SRV_ARGS_LEN] = '\0';
args[0] = &arg_buf[0];
args[1] = NULL;
args[1] = &arg_buf[0];
args[2] = NULL;
} else {
args[0] = NULL;
args[1] = NULL;
}
/* Now try to execute the new system service. Fork a new process. The child