From: Jorrit Herder Date: Thu, 4 Aug 2005 19:23:03 +0000 (+0000) Subject: Check if kernel calls is allowed (from process' call mask) added. Not yet X-Git-Tag: v3.1.0~450 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/Bv9ARM.html?a=commitdiff_plain;h=74711a3b14b74ebbb1db8fea9ea90f951e0b6696;p=minix.git 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. --- diff --git a/commands/ibm/readclock.c b/commands/ibm/readclock.c index 9f1ed0011..b756929ce 100755 --- a/commands/ibm/readclock.c +++ b/commands/ibm/readclock.c @@ -55,6 +55,7 @@ #include #include +#include #include #include #include @@ -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 { diff --git a/drivers/Makefile b/drivers/Makefile index d59007568..ea9199725 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -26,4 +26,5 @@ all install depend clean: cd ./dpeth && $(MAKE) $@ cd ./log && $(MAKE) $@ cd ./bios_wini && $(MAKE) $@ + cd ./cmos && $(MAKE) $@ cd ./random && $(MAKE) $@ diff --git a/drivers/at_wini/at_wini.c b/drivers/at_wini/at_wini.c index 2c5ff0e5a..2ae7df4a4 100644 --- a/drivers/at_wini/at_wini.c +++ b/drivers/at_wini/at_wini.c @@ -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, diff --git a/drivers/cmos/Makefile b/drivers/cmos/Makefile new file mode 100644 index 000000000..09bbcb742 --- /dev/null +++ b/drivers/cmos/Makefile @@ -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 + diff --git a/servers/fs/cmostime.c b/drivers/cmos/cmos.c similarity index 54% rename from servers/fs/cmostime.c rename to drivers/cmos/cmos.c index 06e5e9012..2f951a927 100644 --- a/servers/fs/cmostime.c +++ b/drivers/cmos/cmos.c @@ -1,12 +1,12 @@ -#include "fs.h" -#include -#include -#include -#include -#include - - -/* 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 +#include +#include +#include + +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; + + 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); +} + -PUBLIC int do_cmostime(void) +/*===========================================================================* + * 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. diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile index e401ccc7b..7e35f4696 100644 --- a/drivers/memory/Makefile +++ b/drivers/memory/Makefile @@ -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) diff --git a/drivers/memory/memory.c b/drivers/memory/memory.c index 553f1a2f1..7e2bd28fe 100644 --- a/drivers/memory/memory.c +++ b/drivers/memory/memory.c @@ -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) diff --git a/drivers/tty/console.c b/drivers/tty/console.c index 839d618a6..de4e3a0cb 100644 --- a/drivers/tty/console.c +++ b/drivers/tty/console.c @@ -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); diff --git a/drivers/tty/tty.c b/drivers/tty/tty.c index 4c24a4c33..438295b78 100644 --- a/drivers/tty/tty.c +++ b/drivers/tty/tty.c @@ -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. */ diff --git a/etc/rc b/etc/rc index 4312e1372..4fa646b3a 100755 --- a/etc/rc +++ b/etc/rc @@ -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 diff --git a/etc/usr/rc b/etc/usr/rc index 88f1f3db2..1aacef5ae 100644 --- a/etc/usr/rc +++ b/etc/usr/rc @@ -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 . diff --git a/include/minix/callnr.h b/include/minix/callnr.h index 710315e75..c8af59c2e 100755 --- a/include/minix/callnr.h +++ b/include/minix/callnr.h @@ -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 */ diff --git a/include/minix/com.h b/include/minix/com.h index 3ce68029b..8c2881d64 100755 --- a/include/minix/com.h +++ b/include/minix/com.h @@ -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_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_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_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_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_TRACE (KERNEL_CALL + 13) /* sys_trace() */ +# 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_SETALARM (KERNEL_CALL + 16) /* sys_setalarm() */ +# 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 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_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 NR_SYS_CALLS 28 /* number of system calls */ /* Field names for SYS_MEMSET, SYS_SEGCTL. */ #define MEM_PTR m2_p1 /* base */ diff --git a/include/sys/ioc_cmos.h b/include/sys/ioc_cmos.h new file mode 100755 index 000000000..e89355ef2 --- /dev/null +++ b/include/sys/ioc_cmos.h @@ -0,0 +1,15 @@ +/* sys/ioc_cmos.h - CMOS ioctl() command codes. + */ + +#ifndef _S_I_CMOS_H +#define _S_I_CMOS_H + +#include + +#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 */ + diff --git a/include/sys/ioctl.h b/include/sys/ioctl.h index 2cfb735d8..289f28735 100755 --- a/include/sys/ioctl.h +++ b/include/sys/ioctl.h @@ -18,6 +18,7 @@ #include /* 'd' */ #include /* 'f' */ #include /* 'm' */ +#include /* 'c' */ #include /* 'M' */ #include /* 'S' */ #include /* 's' */ diff --git a/kernel/const.h b/kernel/const.h index 4bff11036..a9b551d86 100755 --- a/kernel/const.h +++ b/kernel/const.h @@ -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'. diff --git a/kernel/main.c b/kernel/main.c index 242f24e2f..5eb48cbeb 100755 --- a/kernel/main.c +++ b/kernel/main.c @@ -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; diff --git a/kernel/priv.h b/kernel/priv.h index a51bcc0d4..6c54a00fd 100755 --- a/kernel/priv.h +++ b/kernel/priv.h @@ -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 */ diff --git a/kernel/proc.c b/kernel/proc.c index 1de7c4476..e66cd27be 100755 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -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); diff --git a/kernel/system.c b/kernel/system.c index 8ab22bcaf..6fb2f810c 100755 --- a/kernel/system.c +++ b/kernel/system.c @@ -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); - - /* 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); + /* 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); + + /* See if the caller made a valid request and try to handle it. */ + if (! (priv(caller_ptr)->s_call_mask & (1<= 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); } } } diff --git a/kernel/system/do_privctl.c b/kernel/system/do_privctl.c index 003f16d91..8c2e8011c 100644 --- a/kernel/system/do_privctl.c +++ b/kernel/system/do_privctl.c @@ -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; ip_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; ip_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)); } } diff --git a/kernel/table.c b/kernel/table.c index 2c15deb5c..8645c1d3d 100755 --- a/kernel/table.c +++ b/kernel/table.c @@ -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]; + diff --git a/kernel/type.h b/kernel/type.h index 12e3d41ce..a8b75c63b 100755 --- a/kernel/type.h +++ b/kernel/type.h @@ -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 */ }; diff --git a/servers/fs/Makefile b/servers/fs/Makefile index fbe337dac..30bfb1765 100644 --- a/servers/fs/Makefile +++ b/servers/fs/Makefile @@ -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 diff --git a/servers/fs/dmap.c b/servers/fs/dmap.c index 0e9afbea8..6251ae8c9 100644 --- a/servers/fs/dmap.c +++ b/servers/fs/dmap.c @@ -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. */ diff --git a/servers/fs/main.c b/servers/fs/main.c index 37e006dd0..de4b4b1b7 100644 --- a/servers/fs/main.c +++ b/servers/fs/main.c @@ -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. */ diff --git a/servers/fs/proto.h b/servers/fs/proto.h index 81cb74cc0..9eaf914c0 100644 --- a/servers/fs/proto.h +++ b/servers/fs/proto.h @@ -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) ); diff --git a/servers/fs/table.c b/servers/fs/table.c index 23129b6f1..45ebd1c70 100644 --- a/servers/fs/table.c +++ b/servers/fs/table.c @@ -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 */ diff --git a/servers/is/Makefile b/servers/is/Makefile index 4dac26067..724f46a5b 100644 --- a/servers/is/Makefile +++ b/servers/is/Makefile @@ -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 $? $@ diff --git a/servers/is/dmp_kernel.c b/servers/is/dmp_kernel.c index a532f6211..488fa9323 100644 --- a/servers/is/dmp_kernel.c +++ b/servers/is/dmp_kernel.c @@ -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; msend_mask & (1<ipc_to & (1<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; diff --git a/servers/pm/signal.c b/servers/pm/signal.c index 49ef40c9b..f29c0f64d 100644 --- a/servers/pm/signal.c +++ b/servers/pm/signal.c @@ -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 */ } diff --git a/servers/pm/table.c b/servers/pm/table.c index 4f0ee23ef..d38d6126c 100644 --- a/servers/pm/table.c +++ b/servers/pm/table.c @@ -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 */ diff --git a/servers/sm/manager.c b/servers/sm/manager.c index 8df0738a8..9cdf607d3 100644 --- a/servers/sm/manager.c +++ b/servers/sm/manager.c @@ -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