From 18327f02a8105d11273b8b8061649efa980a53c5 Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Thu, 27 Jul 2006 16:23:01 +0000 Subject: [PATCH] Introduced unprivileged getsysinfo variant, to retrieve harmless data in formats that don't change (or is upwards compatible). --- include/minix/callnr.h | 3 ++- include/minix/com.h | 5 +++++ include/minix/sysinfo.h | 17 +++++++++++++++++ include/minix/type.h | 4 ++-- lib/other/_getsysinfo.c | 20 ++++++++++++++++++-- lib/posix/getloadavg.c | 8 +++++++- lib/syscall/getsysinfo.s | 4 ++++ servers/fs/table.c | 1 + servers/pm/misc.c | 32 ++++++++++++++++++++++++++++++++ servers/pm/proto.h | 1 + servers/pm/table.c | 1 + 11 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 include/minix/sysinfo.h diff --git a/include/minix/callnr.h b/include/minix/callnr.h index c863153b6..6e045e919 100755 --- a/include/minix/callnr.h +++ b/include/minix/callnr.h @@ -1,4 +1,4 @@ -#define NCALLS 97 /* number of system calls allowed */ +#define NCALLS 98 /* number of system calls allowed */ #define EXIT 1 #define FORK 2 @@ -77,6 +77,7 @@ #define FTRUNCATE 94 /* to FS */ #define FCHMOD 95 /* to FS */ #define FCHOWN 96 /* to FS */ +#define GETSYSINFO_UP 97 /* to PM or 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 diff --git a/include/minix/com.h b/include/minix/com.h index cbc595182..18c928c1a 100755 --- a/include/minix/com.h +++ b/include/minix/com.h @@ -516,6 +516,11 @@ #define SEL_ERRORFDS m8_p3 #define SEL_TIMEOUT m8_p4 +/* Field names for GETSYSINFO_UP (PM). */ +#define SIU_WHAT m2_i1 +#define SIU_LEN m2_i2 +#define SIU_WHERE m2_p1 + /* Message for SYS_READBIOS */ #define RDB_SIZE m2_i1 #define RDB_ADDR m2_l1 diff --git a/include/minix/sysinfo.h b/include/minix/sysinfo.h new file mode 100644 index 000000000..2669159ff --- /dev/null +++ b/include/minix/sysinfo.h @@ -0,0 +1,17 @@ + +#ifndef _MINIX_SYSINFO_H +#define _MINIX_SYSINFO_H + +#include +#include + +_PROTOTYPE( int getsysinfo, (endpoint_t who, int what, void *where) ); +_PROTOTYPE( ssize_t getsysinfo_up, (endpoint_t who, int what, size_t size, + void *where)); + +#define SIU_LOADINFO 1 /* retrieve load info data */ + +/* Exported system parameters. */ + +#endif + diff --git a/include/minix/type.h b/include/minix/type.h index 114b338ef..90c629bc4 100755 --- a/include/minix/type.h +++ b/include/minix/type.h @@ -116,10 +116,10 @@ struct kinfo { }; /* Load data accounted every this no. of seconds. */ -#define _LOAD_UNIT_SECS 6 +#define _LOAD_UNIT_SECS 6 /* Changing this breaks ABI. */ /* Load data history is kept for this long. */ -#define _LOAD_HISTORY_MINUTES 15 +#define _LOAD_HISTORY_MINUTES 15 /* Changing this breaks ABI. */ #define _LOAD_HISTORY_SECONDS (60*_LOAD_HISTORY_MINUTES) /* We need this many slots to store the load history. */ diff --git a/lib/other/_getsysinfo.c b/lib/other/_getsysinfo.c index ec1395445..fa8c22338 100644 --- a/lib/other/_getsysinfo.c +++ b/lib/other/_getsysinfo.c @@ -1,10 +1,12 @@ #include +#include #define getsysinfo _getsysinfo -#include +#define getsysinfo_up _getsysinfo_up +#include PUBLIC int getsysinfo(who, what, where) -int who; /* from whom to request info */ +endpoint_t who; /* from whom to request info */ int what; /* what information is requested */ void *where; /* where to put it */ { @@ -15,3 +17,17 @@ void *where; /* where to put it */ return(0); } +/* Unprivileged variant of getsysinfo. */ +PUBLIC ssize_t getsysinfo_up(who, what, size, where) +endpoint_t who; /* from whom to request info */ +int what; /* what information is requested */ +size_t size; /* input and output size */ +void *where; /* where to put it */ +{ + message m; + m.SIU_WHAT = what; + m.SIU_WHERE = where; + m.SIU_LEN = size; + return _syscall(who, GETSYSINFO_UP, &m); +} + diff --git a/lib/posix/getloadavg.c b/lib/posix/getloadavg.c index a2e4f2cdb..2d6976d19 100755 --- a/lib/posix/getloadavg.c +++ b/lib/posix/getloadavg.c @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -11,12 +12,17 @@ int getloadavg(double *loadavg, int nelem) int h, p, unfilled_ticks; #define PERIODS 3 int minutes[3] = { 1, 5, 15 }; + size_t loadsize; + ssize_t l; if(nelem < 1) { errno = ENOSPC; return -1; } - if(getsysinfo(PM_PROC_NR, SI_LOADINFO, &loadinfo) < 0) + loadsize = sizeof(loadinfo); + if((l=getsysinfo_up(PM_PROC_NR, SIU_LOADINFO, loadsize, &loadinfo)) < 0) + return -1; + if(l != sizeof(loadinfo)) return -1; if(nelem > PERIODS) nelem = PERIODS; diff --git a/lib/syscall/getsysinfo.s b/lib/syscall/getsysinfo.s index 0f6327af3..da6ca3a2e 100644 --- a/lib/syscall/getsysinfo.s +++ b/lib/syscall/getsysinfo.s @@ -1,7 +1,11 @@ .sect .text .extern __getsysinfo .define _getsysinfo +.extern __getsysinfo_up +.define _getsysinfo_up .align 2 _getsysinfo: jmp __getsysinfo +_getsysinfo_up: + jmp __getsysinfo_up diff --git a/servers/fs/table.c b/servers/fs/table.c index 633277ef4..262d7f4b5 100644 --- a/servers/fs/table.c +++ b/servers/fs/table.c @@ -114,6 +114,7 @@ PUBLIC _PROTOTYPE (int (*call_vec[]), (void) ) = { do_ftruncate, /* 94 = truncate */ do_chmod, /* 95 = fchmod */ do_chown, /* 96 = fchown */ + no_sys, /* 97 = (getsysinfo_up) */ }; /* 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/misc.c b/servers/pm/misc.c index 1c795fe4a..7ce14d634 100644 --- a/servers/pm/misc.c +++ b/servers/pm/misc.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -276,6 +277,37 @@ PUBLIC int do_getsysinfo() return(OK); } +/*===========================================================================* + * do_getsysinfo_up * + *===========================================================================*/ +PUBLIC int do_getsysinfo_up() +{ + vir_bytes src_addr, dst_addr; + struct loadinfo loadinfo; + size_t len, real_len; + int s, r; + + switch(m_in.SIU_WHAT) { + case SIU_LOADINFO: /* loadinfo is obtained via PM */ + sys_getloadinfo(&loadinfo); + src_addr = (vir_bytes) &loadinfo; + real_len = sizeof(struct loadinfo); + break; + default: + return(EINVAL); + } + + /* Let application know what the length was. */ + len = real_len; + if(len > m_in.SIU_LEN) + len = m_in.SIU_LEN; + + dst_addr = (vir_bytes) m_in.SIU_WHERE; + if (OK != (s=sys_datacopy(SELF, src_addr, who_e, dst_addr, len))) + return(s); + return(real_len); +} + /*===========================================================================* * do_getprocnr * *===========================================================================*/ diff --git a/servers/pm/proto.h b/servers/pm/proto.h index bf0cd4a20..518f7650c 100644 --- a/servers/pm/proto.h +++ b/servers/pm/proto.h @@ -66,6 +66,7 @@ _PROTOTYPE( int do_reboot, (void) ); _PROTOTYPE( int do_procstat, (void) ); _PROTOTYPE( int do_sysuname, (void) ); _PROTOTYPE( int do_getsysinfo, (void) ); +_PROTOTYPE( int do_getsysinfo_up, (void) ); _PROTOTYPE( int do_getprocnr, (void) ); _PROTOTYPE( int do_svrctl, (void) ); _PROTOTYPE( int do_allocmem, (void) ); diff --git a/servers/pm/table.c b/servers/pm/table.c index 01dc02a58..a130221b3 100644 --- a/servers/pm/table.c +++ b/servers/pm/table.c @@ -112,6 +112,7 @@ _PROTOTYPE (int (*call_vec[NCALLS]), (void) ) = { no_sys, /* 94 = (ftruncate) */ no_sys, /* 95 = (fchmod) */ no_sys, /* 96 = (fchown) */ + do_getsysinfo_up,/* 97 = getsysinfo_up */ }; /* This should not fail with "array size is negative": */ extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1]; -- 2.44.0