From e9aabcf2f8891956566af592a58e2953d095a4b1 Mon Sep 17 00:00:00 2001 From: Philip Homburg Date: Fri, 19 May 2006 12:19:37 +0000 Subject: [PATCH] Disabled building rescue driver (no longer needed). Moved allocmem from library to the memory driver. Always put output from within TTY directly on the console. Removed second include of driver.h from tty.c. Made tty_inrepcode bigger. First step to move PM and FS calls that are not regular (API) system calls out of callnr.h (renumbered them, and removed them from the table.c files). Imported the Minix-vmd uname implementation. This provides a more stable ABI than the current implementation. Added a bit of security checking. Unfortunately not nearly enough to get a secure system. Fixed a bug related to the sizes of the programs in the image (in PM patch_mem_chunks). --- drivers/Makefile | 1 - drivers/memory/Makefile | 2 +- drivers/memory/allocmem.c | 14 ++++ drivers/tty/console.c | 2 + drivers/tty/tty.c | 1 - drivers/tty/tty.h | 2 +- include/minix/callnr.h | 40 ++++++----- include/netinet/if_ether.h | 0 include/sys/utsname.h | 23 +++++++ lib/other/Makefile.in | 3 +- lib/other/_sysuname.c | 26 +++++++ lib/posix/_uname.c | 105 ++++++++++++++-------------- lib/syscall/Makefile.in | 3 +- lib/syscall/sysuname.s | 7 ++ servers/fs/dmap.c | 8 +++ servers/fs/main.c | 47 +++++++++---- servers/fs/misc.c | 28 +++----- servers/fs/proto.h | 1 - servers/fs/table.c | 39 +++++------ servers/fs/utility.c | 1 + servers/pm/glo.h | 3 + servers/pm/main.c | 35 +++++++++- servers/pm/misc.c | 138 +++++++++++++++++++++++++++++++++++++ servers/pm/param.h | 4 ++ servers/pm/proto.h | 1 + servers/pm/table.c | 42 +++++------ servers/pm/utility.c | 2 +- 27 files changed, 425 insertions(+), 153 deletions(-) create mode 100644 drivers/memory/allocmem.c create mode 100644 include/netinet/if_ether.h create mode 100644 lib/other/_sysuname.c create mode 100644 lib/syscall/sysuname.s diff --git a/drivers/Makefile b/drivers/Makefile index bd5374fcf..cb7338ff6 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -27,7 +27,6 @@ all install depend clean: cd ./bios_wini && $(MAKE) $@ cd ./cmos && $(MAKE) $@ cd ./random && $(MAKE) $@ - cd ./rescue && $(MAKE) $@ cd ./dp8390 && $(MAKE) $@ cd ./sb16 && $(MAKE) $@ cd ./lance && $(MAKE) $@ diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile index e5d8ed687..3210a298c 100644 --- a/drivers/memory/Makefile +++ b/drivers/memory/Makefile @@ -22,7 +22,7 @@ LIBS = -lsys -lsysutil IMGRD=imgrd_s.o #IMGRD=imgrd.c -OBJ = memory.o $(IMGRD) +OBJ = memory.o allocmem.o $(IMGRD) LIBDRIVER = $d/libdriver/driver.o diff --git a/drivers/memory/allocmem.c b/drivers/memory/allocmem.c new file mode 100644 index 000000000..31599da73 --- /dev/null +++ b/drivers/memory/allocmem.c @@ -0,0 +1,14 @@ +#include +#include + +PUBLIC int allocmem(size, base) +phys_bytes size; /* size of mem chunk requested */ +phys_bytes *base; /* return base address */ +{ + message m; + m.m4_l1 = size; + if (_syscall(MM, ALLOCMEM, &m) < 0) return(-1); + *base = m.m4_l2; + return(0); +} + diff --git a/drivers/tty/console.c b/drivers/tty/console.c index 2865c15be..b49acb545 100644 --- a/drivers/tty/console.c +++ b/drivers/tty/console.c @@ -991,7 +991,9 @@ int c; return; #endif +#if 0 if (panicing) +#endif cons_putk(c); if (c != 0) { kmess.km_buf[kmess.km_next] = c; /* put normal char in buffer */ diff --git a/drivers/tty/tty.c b/drivers/tty/tty.c index 7598f83a3..fc5d3de43 100644 --- a/drivers/tty/tty.c +++ b/drivers/tty/tty.c @@ -56,7 +56,6 @@ * Jul 13, 2004 support for function key observers (Jorrit N. Herder) */ -#include "../drivers.h" #include "../drivers.h" #include #if ENABLE_SRCCOMPAT || ENABLE_BINCOMPAT diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h index b7ee072b5..fb7da506e 100644 --- a/drivers/tty/tty.h +++ b/drivers/tty/tty.h @@ -62,7 +62,7 @@ typedef struct tty { char tty_openct; /* count of number of opens of this tty */ /* Information about incomplete I/O requests is stored here. */ - char tty_inrepcode; /* reply code, TASK_REPLY or REVIVE */ + int tty_inrepcode; /* reply code, TASK_REPLY or REVIVE */ char tty_inrevived; /* set to 1 if revive callback is pending */ int tty_incaller; /* process that made the call (usually FS) */ int tty_inproc; /* process that wants to read from tty */ diff --git a/include/minix/callnr.h b/include/minix/callnr.h index f6a4c3683..ec02aaae0 100755 --- a/include/minix/callnr.h +++ b/include/minix/callnr.h @@ -53,14 +53,6 @@ #define SETSID 62 #define GETPGRP 63 -/* The following are not system calls, but are processed like them. */ -#define UNPAUSE 65 /* to PM or FS: check for EINTR */ -#define EXEC_NEWMEM 66 /* from FS to PM: new memory map for exec */ -#define REVIVE 67 /* to FS: revive a sleeping process */ -#define TASK_REPLY 68 /* to FS: reply code from tty task */ -#define FORK_NB 69 /* to PM: special fork call for RS */ -#define EXEC_RESTART 70 /* to PM: final part of exec for RS */ - /* Posix signal handling. */ #define SIGACTION 71 #define SIGSUSPEND 72 @@ -68,17 +60,11 @@ #define SIGPROCMASK 74 #define SIGRETURN 75 -#define REBOOT 76 /* to PM */ - -/* MINIX specific calls, e.g., to support system services. */ +#define REBOOT 76 #define SVRCTL 77 -#define PROCSTAT 78 /* to PM */ +#define SYSUNAME 78 #define GETSYSINFO 79 /* to PM or FS */ -#define GETPROCNR 80 /* to PM */ -#define DEVCTL 81 /* to FS */ #define FSTATFS 82 /* to FS */ -#define ALLOCMEM 83 /* to PM */ -#define FREEMEM 84 /* to PM */ #define SELECT 85 /* to FS */ #define FCHDIR 86 /* to FS */ #define FSYNC 87 /* to FS */ @@ -91,3 +77,25 @@ #define FTRUNCATE 94 /* to FS */ #define FCHMOD 95 /* to FS */ #define FCHOWN 96 /* to FS */ + +/* Calls provided by PM and FS that are not part of the API */ +#define EXEC_NEWMEM 100 /* from FS or RS to PM: new memory map for + * exec + */ +#define FORK_NB 101 /* to PM: special fork call for RS */ +#define EXEC_RESTART 102 /* to PM: final part of exec for RS */ +#define PROCSTAT 103 /* to PM */ +#define GETPROCNR 104 /* to PM */ +#define ALLOCMEM 105 /* to PM */ +#if 0 +#define FREEMEM 106 /* to PM, not used, not implemented */ +#endif + +#define DEVCTL 120 /* to FS, map or unmap a device */ +#define TASK_REPLY 121 /* to FS: reply code from drivers, not + * really a standalone call. + */ + +#define REVIVE 150 /* to FS: revive a sleeping process, to be + * removed + */ diff --git a/include/netinet/if_ether.h b/include/netinet/if_ether.h new file mode 100644 index 000000000..e69de29bb diff --git a/include/sys/utsname.h b/include/sys/utsname.h index 0066689b0..ca4085dbb 100755 --- a/include/sys/utsname.h +++ b/include/sys/utsname.h @@ -19,4 +19,27 @@ struct utsname { /* Function Prototypes. */ _PROTOTYPE( int uname, (struct utsname *_name) ); +#ifdef _MINIX +/* Uname() is implemented with sysuname(). */ + +_PROTOTYPE( int sysuname, (int _req, int _field, char *_value, + size_t _len)); + +/* req: Get or set a string. */ +#define _UTS_GET 0 +#define _UTS_SET 1 + +/* field: What field to get or set. These values can't be changed lightly. */ +#define _UTS_ARCH 0 +#define _UTS_KERNEL 1 +#define _UTS_MACHINE 2 +#define _UTS_HOSTNAME 3 +#define _UTS_NODENAME 4 +#define _UTS_RELEASE 5 +#define _UTS_VERSION 6 +#define _UTS_SYSNAME 7 +#define _UTS_BUS 8 +#define _UTS_MAX 9 /* Number of strings. */ +#endif /* _MINIX */ + #endif /* _UTSNAME_H */ diff --git a/lib/other/Makefile.in b/lib/other/Makefile.in index d0b802560..bf8496f86 100644 --- a/lib/other/Makefile.in +++ b/lib/other/Makefile.in @@ -5,11 +5,9 @@ CFLAGS="-O -D_MINIX -D_POSIX_SOURCE -I../../servers" LIBRARIES=libc libc_FILES=" \ - _allocmem.c \ _brk.c \ _devctl.c \ __pm_findproc.c \ - _freemem.c \ _getnpid.c \ _getsigset.c \ _getnprocnr.c \ @@ -18,6 +16,7 @@ libc_FILES=" \ _getsysinfo.c \ _reboot.c \ _seekdir.c \ + _sysuname.c \ _svrctl.c \ asynchio.c \ basename.c \ diff --git a/lib/other/_sysuname.c b/lib/other/_sysuname.c new file mode 100644 index 000000000..461c36c35 --- /dev/null +++ b/lib/other/_sysuname.c @@ -0,0 +1,26 @@ +/* sysuname(2) - transfer uname(3) strings. Author: Kees J. Bot + * 5 Dec 1992 + */ + +#define sysuname _sysuname +#include + +int sysuname(int req, int field, char *value, size_t len) +{ + message m; + + m.m1_i1 = req; + m.m1_i2 = field; + m.m1_i3 = len; + m.m1_p1 = value; + + /* Clear unused fields */ + m.m1_p2 = NULL; + m.m1_p3 = NULL; + + return _syscall(MM, SYSUNAME, &m); +} + +/* + * $PchId: _sysuname.c,v 1.4 1995/11/27 19:42:09 philip Exp $ + */ diff --git a/lib/posix/_uname.c b/lib/posix/_uname.c index 9ad0cc489..5ee45dc78 100755 --- a/lib/posix/_uname.c +++ b/lib/posix/_uname.c @@ -1,59 +1,62 @@ -/* uname() - get system info Author: Kees J. Bot - * 7 Nov 1994 - * Returns information about the Minix system. Alas most - * of it is gathered at compile time, so machine is wrong, and - * release and version become wrong if not recompiled. - * More chip types and Minix versions need to be added. +/* uname(3) - describe the machine. Author: Kees J. Bot + * 5 Dec 1992 */ -#define uname _uname -#define open _open -#define read _read -#define close _close -#include -#include -#include + +#define uname _uname +#include #include +#include #include -#include -#include -#include -#include +#include +#include -int uname(name) struct utsname *name; -{ - int hf, n, err; - struct kinfo kinfo; - char *nl; +#define uts_get(field, string) \ + if (sysuname(_UTS_GET, field, name->string, sizeof(name->string)) < 0) \ + return -1; \ + name->string[sizeof(name->string)-1]= 0; - /* Read the node name from /etc/hostname.file. */ - if ((hf = open("/etc/hostname.file", O_RDONLY)) < 0) { - if (errno != ENOENT) return(-1); - strcpy(name->nodename, "noname"); - } else { - n = read(hf, name->nodename, sizeof(name->nodename) - 1); - err = errno; - close(hf); - errno = err; - if (n < 0) return(-1); - name->nodename[n] = 0; - if ((nl = strchr(name->nodename, '\n')) != NULL) { - memset(nl, 0, (name->nodename + sizeof(name->nodename)) - nl); - } - } - - getsysinfo(PM_PROC_NR, SI_KINFO, &kinfo); +int uname(name) +struct utsname *name; +{ + int hf, n, err; + char *nl; - strcpy(name->sysname, "Minix"); - strcpy(name->release, kinfo.release); - strcpy(name->version, kinfo.version); -#if (CHIP == INTEL) - name->machine[0] = 'i'; - strcpy(name->machine + 1, itoa(getprocessor())); -#if _WORD_SIZE == 4 - strcpy(name->arch, "i386"); -#else - strcpy(name->arch, "i86"); -#endif + /* Get each of the strings with a sysuname call. Null terminate them, + * because the buffers in the kernel may grow before this and the + * programs are recompiled. + */ + uts_get(_UTS_SYSNAME, sysname); + uts_get(_UTS_NODENAME, nodename); + uts_get(_UTS_RELEASE, release); + uts_get(_UTS_VERSION, version); + uts_get(_UTS_MACHINE, machine); + uts_get(_UTS_ARCH, arch); +#if 0 + uts_get(_UTS_KERNEL, kernel); + uts_get(_UTS_HOSTNAME, hostname); + uts_get(_UTS_BUS, bus); #endif - return(0); + + /* Try to read the node name from /etc/hostname.file. This information + * should be stored in the kernel. + */ + if ((hf = open("/etc/hostname.file", O_RDONLY)) < 0) { + if (errno != ENOENT) return(-1); + } else { + n = read(hf, name->nodename, sizeof(name->nodename) - 1); + err = errno; + close(hf); + errno = err; + if (n < 0) return(-1); + name->nodename[n] = 0; + if ((nl = strchr(name->nodename, '\n')) != NULL) { + memset(nl, 0, (name->nodename + + sizeof(name->nodename)) - nl); + } + } + return 0; } + +/* + * $PchId: _uname.c,v 1.4 1995/11/27 20:09:08 philip Exp $ + */ diff --git a/lib/syscall/Makefile.in b/lib/syscall/Makefile.in index 556aa4f25..ceb1d9d09 100644 --- a/lib/syscall/Makefile.in +++ b/lib/syscall/Makefile.in @@ -7,7 +7,6 @@ libc_FILES=" \ _pm_findproc.s \ access.s \ alarm.s \ - allocmem.s \ brk.s \ cfgetispeed.s \ cfgetospeed.s \ @@ -34,7 +33,6 @@ libc_FILES=" \ fcntl.s \ fork.s \ fpathconf.s \ - freemem.s \ fstat.s \ fstatfs.s \ getcwd.s \ @@ -96,6 +94,7 @@ libc_FILES=" \ svrctl.s \ symlink.s \ sync.s \ + sysuname.s \ tcdrain.s \ tcflow.s \ tcflush.s \ diff --git a/lib/syscall/sysuname.s b/lib/syscall/sysuname.s new file mode 100644 index 000000000..2d8d7541c --- /dev/null +++ b/lib/syscall/sysuname.s @@ -0,0 +1,7 @@ +.sect .text +.extern __sysuname +.define _sysuname +.align 2 + +_sysuname: + jmp __sysuname diff --git a/servers/fs/dmap.c b/servers/fs/dmap.c index bc33cc0b3..8ab0d016b 100644 --- a/servers/fs/dmap.c +++ b/servers/fs/dmap.c @@ -60,6 +60,14 @@ PRIVATE struct dmap init_dmap[] = { *===========================================================================*/ PUBLIC int do_devctl() { + if (!super_user) + { + printf("FS: unauthorized call of do_devctl by proc %d\n", + who_e); + return(EPERM); /* only su (should be only RS or some drivers) + * may call do_devctl. + */ + } return fs_devctl(m_in.ctl_req, m_in.dev_nr, m_in.driver_nr, m_in.dev_style, m_in.m_force); } diff --git a/servers/fs/main.c b/servers/fs/main.c index 5ed17d85a..6335803ae 100644 --- a/servers/fs/main.c +++ b/servers/fs/main.c @@ -59,24 +59,45 @@ PUBLIC int main() printf("FS: strange, got message %d from PM\n", call_nr); /* Check for special control messages first. */ - if (call_nr == PROC_EVENT) { - /* PM tries to get FS to do something */ - service_pm(); - } else if (call_nr == SYN_ALARM) { - /* Alarm timer expired. Used only for select(). Check it. */ - fs_expire_timers(m_in.NOTIFY_TIMESTAMP); - } else if ((call_nr & NOTIFY_MESSAGE)) { - /* Device notifies us of an event. */ - dev_status(&m_in); - } else { + if ((call_nr & NOTIFY_MESSAGE)) { + if (call_nr == PROC_EVENT) + { + /* PM tries to get FS to do something */ + service_pm(); + } + else if (call_nr == SYN_ALARM) + { + /* Alarm timer expired. Used only for select(). + * Check it. + */ + fs_expire_timers(m_in.NOTIFY_TIMESTAMP); + } + else + { + /* Device notifies us of an event. */ + dev_status(&m_in); + } + continue; + } + + switch(call_nr) + { + case DEVCTL: + error= do_devctl(); + if (error != SUSPEND) reply(who_e, error); + break; + + default: /* Call the internal function that does the work. */ if (call_nr < 0 || call_nr >= NCALLS) { error = ENOSYS; - /* Not supposed to happen. */ - printf("FS, warning illegal %d system call by %d\n", call_nr, who_e); + /* Not supposed to happen. */ + printf("FS, warning illegal %d system call by %d\n", + call_nr, who_e); } else if (fp->fp_pid == PID_FREE) { error = ENOSYS; - printf("FS, bad process, who = %d, call_nr = %d, endpt1 = %d\n", + printf( + "FS, bad process, who = %d, call_nr = %d, endpt1 = %d\n", who_e, call_nr, m_in.endpt1); } else { error = (*call_vec[call_nr])(); diff --git a/servers/fs/misc.c b/servers/fs/misc.c index d10abf5ed..cfb850575 100644 --- a/servers/fs/misc.c +++ b/servers/fs/misc.c @@ -13,7 +13,6 @@ * do_exit: a process has exited; note that in the tables * pm_setgid: set group ids for some process * pm_setuid: set user ids for some process - * do_revive: revive a process that was waiting for something (e.g. TTY) * do_svrctl: file system control * do_getsysinfo: request copy of FS data structure * pm_dumpcore: create a core dump @@ -56,6 +55,15 @@ PUBLIC int do_getsysinfo() size_t len; int s; + if (!super_user) + { + printf("FS: unauthorized call of do_getsysinfo by proc %d\n", who_e); + return(EPERM); /* only su may call do_getsysinfo. This call may leak + * information (and is not stable enough to be part + * of the API/ABI). + */ + } + switch(m_in.info_what) { case SI_PROC_ADDR: proc_addr = &fproc[0]; @@ -480,24 +488,6 @@ int ruid; } -/*===========================================================================* - * do_revive * - *===========================================================================*/ -PUBLIC int do_revive() -{ -/* A driver, typically TTY, has now gotten the characters that were needed for - * a previous read. The process did not get a reply when it made the call. - * Instead it was suspended. Now we can send the reply to wake it up. This - * business has to be done carefully, since the incoming message is from - * a driver (to which no reply can be sent), and the reply must go to a process - * that blocked earlier. The reply to the caller is inhibited by returning the - * 'SUSPEND' pseudo error, and the reply to the blocked process is done - * explicitly in revive(). - */ - revive(m_in.REP_ENDPT, m_in.REP_STATUS); - return(SUSPEND); /* don't reply to the TTY task */ -} - /*===========================================================================* * do_svrctl * *===========================================================================*/ diff --git a/servers/fs/proto.h b/servers/fs/proto.h index 2ef7c6679..5a612f6be 100644 --- a/servers/fs/proto.h +++ b/servers/fs/proto.h @@ -104,7 +104,6 @@ _PROTOTYPE( int do_dup, (void) ); _PROTOTYPE( void pm_exit, (int proc) ); _PROTOTYPE( int do_fcntl, (void) ); _PROTOTYPE( void pm_fork, (int pproc, int cproc, int cpid) ); -_PROTOTYPE( int do_revive, (void) ); _PROTOTYPE( void pm_setgid, (int proc_e, int egid, int rgid) ); _PROTOTYPE( void pm_setuid, (int proc_e, int euid, int ruid) ); _PROTOTYPE( int do_sync, (void) ); diff --git a/servers/fs/table.c b/servers/fs/table.c index 94166d844..633277ef4 100644 --- a/servers/fs/table.c +++ b/servers/fs/table.c @@ -78,38 +78,38 @@ PUBLIC _PROTOTYPE (int (*call_vec[]), (void) ) = { do_umask, /* 60 = umask */ do_chroot, /* 61 = chroot */ no_sys, /* 62 = (setsid) */ - no_sys, /* 63 = getpgrp */ + no_sys, /* 63 = (getpgrp) */ - no_sys, /* 64 = KSIG: signals originating in the kernel */ - do_unpause, /* 65 = UNPAUSE */ + no_sys, /* 64 = unused */ + no_sys, /* 65 = unused */ no_sys, /* 66 = unused */ - do_revive, /* 67 = REVIVE */ - no_sys, /* 68 = TASK_REPLY */ + no_sys, /* 67 = unused */ + no_sys, /* 68 = unused */ no_sys, /* 69 = unused */ no_sys, /* 70 = unused */ - no_sys, /* 71 = si */ - no_sys, /* 72 = sigsuspend */ - no_sys, /* 73 = sigpending */ - no_sys, /* 74 = sigprocmask */ - no_sys, /* 75 = sigreturn */ + no_sys, /* 71 = (sigaction) */ + no_sys, /* 72 = (sigsuspend) */ + no_sys, /* 73 = (sigpending) */ + no_sys, /* 74 = (sigprocmask) */ + no_sys, /* 75 = (sigreturn) */ no_sys, /* 76 = (reboot) */ do_svrctl, /* 77 = svrctl */ - no_sys, /* 78 = unused */ + no_sys, /* 78 = (sysuname) */ do_getsysinfo, /* 79 = getsysinfo */ no_sys, /* 80 = unused */ - do_devctl, /* 81 = devctl */ + no_sys, /* 81 = unused */ do_fstatfs, /* 82 = fstatfs */ - no_sys, /* 83 = memalloc */ - no_sys, /* 84 = memfree */ + no_sys, /* 83 = unused */ + no_sys, /* 84 = unused */ do_select, /* 85 = select */ do_fchdir, /* 86 = fchdir */ do_fsync, /* 87 = fsync */ - no_sys, /* 88 = getpriority */ - no_sys, /* 89 = setpriority */ - no_sys, /* 90 = gettimeofday */ - no_sys, /* 91 = seteuid */ - no_sys, /* 92 = setegid */ + no_sys, /* 88 = (getpriority) */ + no_sys, /* 89 = (setpriority) */ + no_sys, /* 90 = (gettimeofday) */ + no_sys, /* 91 = (seteuid) */ + no_sys, /* 92 = (setegid) */ do_truncate, /* 93 = truncate */ do_ftruncate, /* 94 = truncate */ do_chmod, /* 95 = fchmod */ @@ -117,4 +117,3 @@ PUBLIC _PROTOTYPE (int (*call_vec[]), (void) ) = { }; /* This should not fail with "array size is negative": */ extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1]; - diff --git a/servers/fs/utility.c b/servers/fs/utility.c index afaccdfc5..50821f072 100644 --- a/servers/fs/utility.c +++ b/servers/fs/utility.c @@ -85,6 +85,7 @@ int flag; /* M3 means path may be in message */ PUBLIC int no_sys() { /* Somebody has used an illegal system call number */ + printf("FS: in no_sys: call %d from %d\n", call_nr, who_e); return(EINVAL); } diff --git a/servers/pm/glo.h b/servers/pm/glo.h index 8c4272ecd..6485c1679 100644 --- a/servers/pm/glo.h +++ b/servers/pm/glo.h @@ -10,6 +10,9 @@ EXTERN int procs_in_use; /* how many processes are marked as IN_USE */ EXTERN char monitor_params[128*sizeof(char *)]; /* boot monitor parameters */ EXTERN struct kinfo kinfo; /* kernel information */ +/* Misc.c */ +extern struct utsname uts_val; /* uname info */ + /* The parameters of the call are kept here. */ EXTERN message m_in; /* the incoming message itself is kept here. */ EXTERN int who_p, who_e; /* caller's proc number, endpoint */ diff --git a/servers/pm/main.c b/servers/pm/main.c index 22b973ae4..0c38d98cf 100644 --- a/servers/pm/main.c +++ b/servers/pm/main.c @@ -14,10 +14,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include "mproc.h" #include "param.h" @@ -92,6 +94,24 @@ PUBLIC int main() else result= ENOSYS; break; + case ALLOCMEM: + result= do_allocmem(); + break; + case FORK_NB: + result= do_fork_nb(); + break; + case EXEC_NEWMEM: + result= exec_newmem(); + break; + case EXEC_RESTART: + result= do_execrestart(); + break; + case PROCSTAT: + result= do_procstat(); + break; + case GETPROCNR: + result= do_getprocnr(); + break; default: /* Else, if the system call number is valid, perform the * call. @@ -330,6 +350,10 @@ PRIVATE void pm_init() printf(" total %u KB,", click_to_round_k(total_clicks)); printf(" system %u KB,", click_to_round_k(minix_clicks)); printf(" free %u KB.\n", click_to_round_k(free_clicks)); +#if (CHIP == INTEL) + uts_val.machine[0] = 'i'; + strcpy(uts_val.machine + 1, itoa(getprocessor())); +#endif } /*===========================================================================* @@ -438,10 +462,16 @@ struct mem_map *map_ptr; /* memory to remove */ struct memory *memp; for (memp = mem_chunks; memp < &mem_chunks[NR_MEMS]; memp++) { if (memp->base == map_ptr[T].mem_phys) { - memp->base += map_ptr[T].mem_len + map_ptr[D].mem_len; - memp->size -= map_ptr[T].mem_len + map_ptr[D].mem_len; + memp->base += map_ptr[T].mem_len + map_ptr[S].mem_vir; + memp->size -= map_ptr[T].mem_len + map_ptr[S].mem_vir; + break; } } + if (memp >= &mem_chunks[NR_MEMS]) + { + panic(__FILE__,"patch_mem_chunks: can't find map in mem_chunks, start", + map_ptr[T].mem_phys); + } } #define PAGE_SIZE 4096 @@ -702,7 +732,6 @@ PRIVATE void send_work() } r= send(FS_PROC_NR, &m); if (r != OK) panic("pm", "send_work: send failed", r); - } PRIVATE void handle_fs_reply(m_ptr) diff --git a/servers/pm/misc.c b/servers/pm/misc.c index cc3569d8e..49db944c9 100644 --- a/servers/pm/misc.c +++ b/servers/pm/misc.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,31 @@ #include "param.h" #include "../../kernel/proc.h" +PUBLIC struct utsname uts_val = { + "Minix", /* system name */ + "noname", /* node/network name */ + OS_RELEASE, /* O.S. release (e.g. 1.5) */ + OS_VERSION, /* O.S. version (e.g. 10) */ + "xyzzy", /* machine (cpu) type (filled in later) */ +#if __i386 + "i386", /* architecture */ +#else +#error /* oops, no 'uname -mk' */ +#endif +}; + +PRIVATE char *uts_tbl[] = { + uts_val.arch, + NULL, /* No kernel architecture */ + uts_val.machine, + NULL, /* No hostname */ + uts_val.nodename, + uts_val.release, + uts_val.version, + uts_val.sysname, + NULL, /* No bus */ /* No bus */ +}; + /*===========================================================================* * do_allocmem * *===========================================================================*/ @@ -33,6 +59,16 @@ PUBLIC int do_allocmem() vir_clicks mem_clicks; phys_clicks mem_base; + /* This call is dangerous. Memory will be lost of the requesting process + * forgets about it. + */ + if (mp->mp_effuid != 0) + { + printf("PM: unauthorized call of do_allocmem by proc %d\n", + mp->mp_endpoint); + return EPERM; + } + mem_clicks = (m_in.memsize + CLICK_SIZE -1 ) >> CLICK_SHIFT; mem_base = alloc_mem(mem_clicks); if (mem_base == NO_MEM) return(ENOMEM); @@ -48,6 +84,16 @@ PUBLIC int do_freemem() vir_clicks mem_clicks; phys_clicks mem_base; + /* This call is dangerous. Even memory belonging to other processes can + * be freed. + */ + if (mp->mp_effuid != 0) + { + printf("PM: unauthorized call of do_freemem by proc %d\n", + mp->mp_endpoint); + return EPERM; + } + mem_clicks = (m_in.memsize + CLICK_SIZE -1 ) >> CLICK_SHIFT; mem_base = (m_in.membase + CLICK_SIZE -1 ) >> CLICK_SHIFT; free_mem(mem_base, mem_clicks); @@ -65,6 +111,15 @@ PUBLIC int do_procstat() * Future use might include the FS requesting for process status of * any user process. */ + + /* This call should be removed, or made more general. */ + if (mp->mp_effuid != 0) + { + printf("PM: unauthorized call of do_procstat by proc %d\n", + mp->mp_endpoint); + return EPERM; + } + if (m_in.stat_nr == SELF) { mp->mp_reply.sig_set = mp->mp_sigpending; sigemptyset(&mp->mp_sigpending); @@ -75,6 +130,70 @@ PUBLIC int do_procstat() return(OK); } +/*===========================================================================* + * do_sysuname * + *===========================================================================*/ +PUBLIC int do_sysuname() +{ +/* Set or get uname strings. */ + + int r; + size_t n, len; + char *string, *t; +#if 0 /* for updates */ + char tmp[sizeof(uts_val.nodename)]; + static short sizes[] = { + 0, /* arch, (0 = read-only) */ + 0, /* kernel */ + 0, /* machine */ + 0, /* sizeof(uts_val.hostname), */ + sizeof(uts_val.nodename), + 0, /* release */ + 0, /* version */ + 0, /* sysname */ + }; +#endif + + if ((unsigned) m_in.sysuname_field >= _UTS_MAX) return(EINVAL); + + string = uts_tbl[m_in.sysuname_field]; + if (string == NULL) + return EINVAL; /* Unsupported field */ + + switch (m_in.sysuname_req) { + case _UTS_GET: + /* Copy an uname string to the user. */ + n = strlen(string) + 1; + if (n > m_in.sysuname_len) n = m_in.sysuname_len; + r = sys_vircopy(SELF, D, (phys_bytes) string, + mp->mp_endpoint, D, (phys_bytes) m_in.sysuname_value, + (phys_bytes) n); + if (r < 0) return(r); + break; + +#if 0 /* no updates yet */ + case _UTS_SET: + /* Set an uname string, needs root power. */ + len = sizes[m_in.sysuname_field]; + if (mp->mp_effuid != 0 || len == 0) return(EPERM); + n = len < m_in.sysuname_len ? len : m_in.sysuname_len; + if (n <= 0) return(EINVAL); + r = sys_vircopy(mp->mp_endpoint, D, (phys_bytes) m_in.sysuname_value, + SELF, D, (phys_bytes) tmp, (phys_bytes) n); + if (r < 0) return(r); + tmp[n-1] = 0; + strcpy(string, tmp); + break; +#endif + + default: + return(EINVAL); + } + /* Return the number of bytes moved. */ + return(n); +} + + /*===========================================================================* * do_getsysinfo * *===========================================================================*/ @@ -90,6 +209,17 @@ PUBLIC int do_getsysinfo() int s, r; size_t holesize; + /* This call leaks important information (the contents of registers). + * harmless data (such as the load should get their own calls) + */ + if (mp->mp_effuid != 0) + { + printf("PM: unauthorized call of do_getsysinfo by proc %d '%s'\n", + mp->mp_endpoint, mp->mp_name); + sig_proc(mp, SIGEMT); + return EPERM; + } + switch(m_in.info_what) { case SI_KINFO: /* kernel info is obtained via PM */ sys_getkinfo(&kinfo); @@ -144,6 +274,14 @@ PUBLIC int do_getprocnr() int key_len; int s; + /* This call should be moved to DS. */ + if (mp->mp_effuid != 0) + { + printf("PM: unauthorized call of do_procstat by proc %d\n", + mp->mp_endpoint); + return EPERM; + } + if (m_in.pid >= 0) { /* lookup process by pid */ for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) { if ((rmp->mp_flags & IN_USE) && (rmp->mp_pid==m_in.pid)) { diff --git a/servers/pm/param.h b/servers/pm/param.h index 08e902f82..47f4aedba 100644 --- a/servers/pm/param.h +++ b/servers/pm/param.h @@ -39,6 +39,10 @@ #define stime m2_l1 #define memsize m4_l1 #define membase m4_l2 +#define sysuname_req m1_i1 +#define sysuname_field m1_i2 +#define sysuname_len m1_i3 +#define sysuname_value m1_p1 /* The following names are synonyms for the variables in a reply message. */ #define reply_res m_type diff --git a/servers/pm/proto.h b/servers/pm/proto.h index 1b75cfd7a..44edffce2 100644 --- a/servers/pm/proto.h +++ b/servers/pm/proto.h @@ -63,6 +63,7 @@ _PROTOTYPE( int main, (void) ); /* misc.c */ _PROTOTYPE( int do_reboot, (void) ); _PROTOTYPE( int do_procstat, (void) ); +_PROTOTYPE( int do_sysuname, (void) ); _PROTOTYPE( int do_getsysinfo, (void) ); _PROTOTYPE( int do_getprocnr, (void) ); _PROTOTYPE( int do_svrctl, (void) ); diff --git a/servers/pm/table.c b/servers/pm/table.c index 2aa6eedbc..01dc02a58 100644 --- a/servers/pm/table.c +++ b/servers/pm/table.c @@ -79,13 +79,13 @@ _PROTOTYPE (int (*call_vec[NCALLS]), (void) ) = { do_getset, /* 62 = setsid */ do_getset, /* 63 = getpgrp */ - no_sys, /* 64 = unused */ - no_sys, /* 65 = UNPAUSE */ - exec_newmem, /* 66 = EXEC_NEWMEM */ - no_sys, /* 67 = REVIVE */ - no_sys, /* 68 = TASK_REPLY */ - do_fork_nb, /* 69 = FORK_NB */ - do_execrestart, /* 70 = EXEC_RESTART */ + no_sys, /* 64 = unused */ + no_sys, /* 65 = unused */ + no_sys, /* 66 = unused */ + no_sys, /* 67 = unused */ + no_sys, /* 68 = unused */ + no_sys, /* 69 = unused */ + no_sys, /* 70 = unused */ do_sigaction, /* 71 = sigaction */ do_sigsuspend, /* 72 = sigsuspend */ do_sigpending, /* 73 = sigpending */ @@ -93,25 +93,25 @@ _PROTOTYPE (int (*call_vec[NCALLS]), (void) ) = { do_sigreturn, /* 75 = sigreturn */ do_reboot, /* 76 = reboot */ do_svrctl, /* 77 = svrctl */ - do_procstat, /* 78 = procstat */ + do_sysuname, /* 78 = sysuname */ do_getsysinfo, /* 79 = getsysinfo */ - do_getprocnr, /* 80 = getprocnr */ + no_sys, /* 80 = unused */ no_sys, /* 81 = unused */ - no_sys, /* 82 = fstatfs */ - do_allocmem, /* 83 = memalloc */ - do_freemem, /* 84 = memfree */ - no_sys, /* 85 = select */ - no_sys, /* 86 = fchdir */ - no_sys, /* 87 = fsync */ - do_getsetpriority, /* 88 = getpriority */ - do_getsetpriority, /* 89 = setpriority */ + no_sys, /* 82 = (fstatfs) */ + no_sys, /* 83 = unused */ + no_sys, /* 84 = unused */ + no_sys, /* 85 = (select) */ + no_sys, /* 86 = (fchdir) */ + no_sys, /* 87 = (fsync) */ + do_getsetpriority, /* 88 = getpriority */ + do_getsetpriority, /* 89 = setpriority */ do_time, /* 90 = gettimeofday */ do_getset, /* 91 = seteuid */ do_getset, /* 92 = setegid */ - no_sys, /* 93 = truncate */ - no_sys, /* 94 = ftruncate */ - no_sys, /* 95 = fchmod */ - no_sys, /* 96 = fchown */ + no_sys, /* 93 = (truncate) */ + no_sys, /* 94 = (ftruncate) */ + no_sys, /* 95 = (fchmod) */ + no_sys, /* 96 = (fchown) */ }; /* This should not fail with "array size is negative": */ extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1]; diff --git a/servers/pm/utility.c b/servers/pm/utility.c index 0ed48be35..b38631329 100644 --- a/servers/pm/utility.c +++ b/servers/pm/utility.c @@ -58,7 +58,7 @@ PUBLIC pid_t get_free_pid() PUBLIC int no_sys() { /* A system call number not implemented by PM has been requested. */ - + printf("PM: in no_sys, call nr %d from %d\n", call_nr, who_e); return(ENOSYS); } -- 2.44.0