]> Zhao Yanbai Git Server - minix.git/commitdiff
Support for restricting limiting IPC to a set of endpoints. Not enabled by
authorPhilip Homburg <philip@cs.vu.nl>
Thu, 21 Feb 2008 16:20:22 +0000 (16:20 +0000)
committerPhilip Homburg <philip@cs.vu.nl>
Thu, 21 Feb 2008 16:20:22 +0000 (16:20 +0000)
default, pass -i to service. Do not reply to bogus request types. Reply using
sendnb.

servers/rs/main.c
servers/rs/manager.c
servers/rs/manager.h
servers/rs/service.c

index 74eff80e488b0dc7b470c1423564878f3c74658f..c201d0eb6334762ff6a811e9b5b37e5563fc1d47 100644 (file)
@@ -81,13 +81,21 @@ PUBLIC int main(void)
       /* If this is not a notification message, it is a normal request. 
        * Handle the request and send a reply to the caller. 
        */
-      else {   
+      else {
+         if (call_nr < RS_RQ_BASE || call_nr >= RS_RQ_BASE+0x100)
+         {
+               /* Ignore invalid requests. Do not try to reply. */
+               printf("RS: got invalid request %d from endpoint %d\n",
+                       call_nr, m.m_source);
+               continue;
+         }
+
          /* Only root can make calls to rs */
          euid= getpeuid(m.m_source);
          if (euid != 0)
          {
-               printf("RS: got unauthorized request from endpoint %d\n",
-                       m.m_source);
+               printf("RS: got unauthorized request %d from endpoint %d\n",
+                       call_nr, m.m_source);
                m.m_type = EPERM;
                reply(who_e, &m);
                continue;
@@ -203,12 +211,11 @@ PRIVATE void reply(who, m_out)
 int who;                               /* replyee */
 message *m_out;                         /* reply message */
 {
-    /*message m_out;*/                 /* reply message */
     int s;                             /* send status */
 
-    /*m_out.m_type = result;*/         /* build reply message */
-    if (OK != (s=send(who, m_out)))     /* send the message */
-        panic("RS", "unable to send reply", s);
+    s = sendnb(who, m_out);            /* send the message */
+    if (s != OK)
+        printf("RS: unable to send reply to %d: %d\n", who, s);
 }
 
 
index 457bafdef3a2d4a8dc3cc9a910007949f122926f..0b749573419136e313071fa8b969af3f895a9bae 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include "inc.h"
+#include <ctype.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/types.h>
@@ -260,6 +261,21 @@ message *m_ptr;                                    /* request message pointer */
   rp->r_uid= rs_start.rss_uid;
   rp->r_nice= rs_start.rss_nice;
 
+  if (rs_start.rss_flags & RF_IPC_VALID)
+  {
+       if (rs_start.rss_ipclen+1 > sizeof(rp->r_ipc_list))
+       {
+               printf("rs: ipc list too long for '%s'\n", rp->r_label);
+               return EINVAL;
+       }
+       s=sys_datacopy(m_ptr->m_source, (vir_bytes) rs_start.rss_ipc, 
+               SELF, (vir_bytes) rp->r_ipc_list, rs_start.rss_ipclen);
+       if (s != OK) return(s);
+       rp->r_ipc_list[rs_start.rss_ipclen]= '\0';
+  }
+  else
+       rp->r_ipc_list[0]= '\0';
+
   rp->r_exec= NULL;
   if (rs_start.rss_flags & RF_COPY)
   {
@@ -806,11 +822,13 @@ endpoint_t *endpoint;
   if (rp->r_dev_nr > 0) {                              /* set driver map */
       if ((s=mapdriver5(rp->r_label, strlen(rp->r_label),
              rp->r_dev_nr, rp->r_dev_style, !!use_copy /* force */)) < 0) {
-          report("RS", "couldn't map driver", errno);
+          report("RS", "couldn't map driver (continuing)", errno);
+#if 0
           rp->r_flags |= RS_EXITING;                   /* expect exit */
          if(child_pid > 0) kill(child_pid, SIGKILL);   /* kill driver */
          else report("RS", "didn't kill pid", child_pid);
          return(s);                                    /* return error */
+#endif
       }
   }
 
@@ -970,7 +988,7 @@ struct rproc *rp;
        sprintf(incarnation_str, "%d", rp->r_restarts);
 
        if(rs_verbose) {
-         printf("RS: should call script '%s'\n", rp->r_script);
+         printf("RS: calling script '%s'\n", rp->r_script);
          printf("RS: sevice name: '%s'\n", rp->r_label);
          printf("RS: reason: '%s'\n", reason);
          printf("RS: incarnation: '%s'\n", incarnation_str);
@@ -1016,8 +1034,12 @@ struct priv *privp;
 {
        int i, src_bits_per_word, dst_bits_per_word, src_word, dst_word,
                src_bit, call_nr, chunk, bit, priv_id, slot_nr;
+       endpoint_t proc_nr_e;
+       size_t len;
        unsigned long mask;
+       char *p, *q;
        struct rproc *tmp_rp;
+       char label[MAX_LABEL_LEN+1];
 
        /* Clear s_k_call_mask */
        memset(privp->s_k_call_mask, '\0', sizeof(privp->s_k_call_mask));
@@ -1050,123 +1072,80 @@ struct priv *privp;
        memset(&privp->s_ipc_to, '\0', sizeof(privp->s_ipc_to));
        memset(&privp->s_ipc_sendrec, '\0', sizeof(privp->s_ipc_sendrec));
 
-       if (strcmp(rp->r_label, "dp8390") == 0)
+       if (strlen(rp->r_ipc_list) != 0)
        {
-               printf("init_privs: special code for dp8390\n");
-
-               /* Try to find inet */
-               for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++)
-               {
-                     tmp_rp = &rproc[slot_nr];
-                     if (!(tmp_rp->r_flags & RS_IN_USE))
-                         continue;
-                     if (strcmp(tmp_rp->r_label, "inet") == 0)
-                       break;
-               }
-               if (slot_nr >= NR_SYS_PROCS)
-               {
-                       printf("init_privs: unable to find inet\n");
-                       return;
-               }
-
-               priv_id= sys_getprivid(tmp_rp->r_proc_nr_e);
-               if (priv_id < 0)
-               {
-                       printf(
-                       "init_privs: unable to get priv_id for inet: %d\n",
-                               priv_id);
-                       return;
-               }
-               chunk= (priv_id / (sizeof(bitchunk_t)*8));
-               bit= (priv_id % (sizeof(bitchunk_t)*8));
-               privp->s_ipc_to.chunk[chunk] |= (1 << bit);
-
-               priv_id= sys_getprivid(RS_PROC_NR);
-               if (priv_id < 0)
-               {
-                       printf(
-                       "init_privs: unable to get priv_id for RS: %d\n",
-                               priv_id);
-                       return;
-               }
-               chunk= (priv_id / (sizeof(bitchunk_t)*8));
-               bit= (priv_id % (sizeof(bitchunk_t)*8));
-               privp->s_ipc_to.chunk[chunk] |= (1 << bit);
-
-               priv_id= sys_getprivid(SYSTEM);
-               if (priv_id < 0)
-               {
-                       printf(
-                       "init_privs: unable to get priv_id for SYSTEM: %d\n",
-                               priv_id);
-                       return;
-               }
-               chunk= (priv_id / (sizeof(bitchunk_t)*8));
-               bit= (priv_id % (sizeof(bitchunk_t)*8));
-               privp->s_ipc_sendrec.chunk[chunk] |= (1 << bit);
-
-               priv_id= sys_getprivid(PM_PROC_NR);
-               if (priv_id < 0)
-               {
-                       printf(
-                       "init_privs: unable to get priv_id for PM: %d\n",
-                               priv_id);
-                       return;
-               }
-               chunk= (priv_id / (sizeof(bitchunk_t)*8));
-               bit= (priv_id % (sizeof(bitchunk_t)*8));
-               privp->s_ipc_sendrec.chunk[chunk] |= (1 << bit);
-
-               priv_id= sys_getprivid(LOG_PROC_NR);
-               if (priv_id < 0)
+               for (p= rp->r_ipc_list; p[0] != '\0'; p= q)
                {
-                       printf(
-                       "init_privs: unable to get priv_id for LOG: %d\n",
-                               priv_id);
-                       return;
-               }
-               chunk= (priv_id / (sizeof(bitchunk_t)*8));
-               bit= (priv_id % (sizeof(bitchunk_t)*8));
-               privp->s_ipc_sendrec.chunk[chunk] |= (1 << bit);
-
-               priv_id= sys_getprivid(TTY_PROC_NR);
-               if (priv_id < 0)
-               {
-                       printf(
-                       "init_privs: unable to get priv_id for TTY: %d\n",
-                               priv_id);
-                       return;
-               }
-               chunk= (priv_id / (sizeof(bitchunk_t)*8));
-               bit= (priv_id % (sizeof(bitchunk_t)*8));
-               privp->s_ipc_sendrec.chunk[chunk] |= (1 << bit);
-
-               /* Try to find PCI */
-               for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++)
-               {
-                     tmp_rp = &rproc[slot_nr];
-                     if (!(tmp_rp->r_flags & RS_IN_USE))
-                         continue;
-                     if (strcmp(tmp_rp->r_label, "pci") == 0)
-                       break;
-               }
-               if (slot_nr >= NR_SYS_PROCS)
-               {
-                       printf("init_privs: unable to find PCI\n");
-                       return;
-               }
+                       /* Skip leading space */
+                       while (p[0] != '\0' && isspace((unsigned char)p[0]))
+                               p++;
+
+                       /* Find start of next word */
+                       q= p;
+                       while (q[0] != '\0' && !isspace((unsigned char)q[0]))
+                               q++;
+                       if (q == p)
+                               continue;
+                       len= q-p;
+                       if (len+1 > sizeof(label))
+                       {
+                               printf(
+               "rs:init_privs: bad ipc list entry '.*s' for %s: too long\n",
+                                       len, p, rp->r_label);
+                               continue;
+                       }
+                       memcpy(label, p, len);
+                       label[len]= '\0';
+
+                       if (strcmp(label, "SYSTEM") == 0)
+                               proc_nr_e= SYSTEM;
+                       else if (strcmp(label, "PM") == 0)
+                               proc_nr_e= PM_PROC_NR;
+                       else if (strcmp(label, "VFS") == 0)
+                               proc_nr_e= FS_PROC_NR;
+                       else if (strcmp(label, "RS") == 0)
+                               proc_nr_e= RS_PROC_NR;
+                       else if (strcmp(label, "LOG") == 0)
+                               proc_nr_e= LOG_PROC_NR;
+                       else if (strcmp(label, "TTY") == 0)
+                               proc_nr_e= TTY_PROC_NR;
+                       else if (strcmp(label, "DS") == 0)
+                               proc_nr_e= DS_PROC_NR;
+                       else
+                       {
+                               /* Try to find process */
+                               for (slot_nr = 0; slot_nr < NR_SYS_PROCS;
+                                       slot_nr++)
+                               {
+                                       tmp_rp = &rproc[slot_nr];
+                                       if (!(tmp_rp->r_flags & RS_IN_USE))
+                                               continue;
+                                       if (strcmp(tmp_rp->r_label, label) == 0)
+                                               break;
+                               }
+                               if (slot_nr >= NR_SYS_PROCS)
+                               {
+                                       printf(
+                                       "init_privs: unable to find '%s'\n",
+                                               label);
+                                       continue;
+                               }
+                               proc_nr_e= tmp_rp->r_proc_nr_e;
+                       }
 
-               priv_id= sys_getprivid(tmp_rp->r_proc_nr_e);
-               if (priv_id < 0)
-               {
-                       printf(
-                       "init_privs: unable to get priv_id for PCI: %d\n",
-                               priv_id);
-                       return;
+                       priv_id= sys_getprivid(proc_nr_e);
+                       if (priv_id < 0)
+                       {
+                               printf(
+                       "init_privs: unable to get priv_id for '%s': %d\n",
+                                       label, priv_id);
+                               continue;
+                       }
+                       chunk= (priv_id / (sizeof(bitchunk_t)*8));
+                       bit= (priv_id % (sizeof(bitchunk_t)*8));
+                       privp->s_ipc_to.chunk[chunk] |= (1 << bit);
+                       privp->s_ipc_sendrec.chunk[chunk] |= (1 << bit);
                }
-               chunk= (priv_id / (sizeof(bitchunk_t)*8));
-               bit= (priv_id % (sizeof(bitchunk_t)*8));
-               privp->s_ipc_sendrec.chunk[chunk] |= (1 << bit);
        }
        else
        {
index 642bbc2e11911dc1a5e491d0d0d7da27eb64e24c..817f6d4e51c8e1edb7316bfb57f2c95c578f7a3f 100644 (file)
@@ -15,6 +15,9 @@
 #define MAX_NR_PCI_ID        4         /* maximum number of PCI device IDs */
 #define MAX_NR_PCI_CLASS      4                /* maximum number of PCI class IDs */
 #define MAX_NR_SYSTEM        2         /* should match RSS_NR_SYSTEM */
+#define MAX_IPC_LIST       256         /* Max size of list for IPC target
+                                        * process names
+                                        */
 
 /* Definition of the system process table. This table only has entries for
  * the servers and drivers, and thus is not directly indexed by slot number.
@@ -57,6 +60,7 @@ extern struct rproc {
   struct { u32_t class; u32_t mask; } r_pci_class[MAX_NR_PCI_CLASS];
 
   u32_t r_call_mask[MAX_NR_SYSTEM];
+  char r_ipc_list[MAX_IPC_LIST];
 } rproc[NR_SYS_PROCS];
 
 /* Mapping for fast access to the system process table. */ 
index 79dd9fd747a5eee82b200b358c41e9581d8f16b1..acab09dda1cc70de9e4fa48c2624b7620b8d8129 100644 (file)
@@ -87,6 +87,7 @@ PRIVATE int req_major;
 PRIVATE long req_period;
 PRIVATE char *req_script;
 PRIVATE char *req_label;
+PRIVATE char *req_ipc;
 PRIVATE char *req_config = PATH_CONFIG;
 PRIVATE int req_printep;
 PRIVATE int class_recurs;      /* Nesting level of class statements */
@@ -133,9 +134,10 @@ PRIVATE int parse_arguments(int argc, char **argv)
   int req_nr;
   int c, i;
   int c_flag;
+  int i_flag=0;
 
   c_flag= 0;
-  while (c= getopt(argc, argv, "c?"), c != -1)
+  while (c= getopt(argc, argv, "ci?"), c != -1)
   {
        switch(c)
        {
@@ -145,6 +147,9 @@ PRIVATE int parse_arguments(int argc, char **argv)
        case 'c':
                c_flag= 1;
                break;
+       case 'i':
+               i_flag= 1;
+               break;
        default:
                fprintf(stderr, "%s: getopt failed: %c\n",
                        argv[ARG_NAME], c);
@@ -184,6 +189,8 @@ PRIVATE int parse_arguments(int argc, char **argv)
       rs_start.rss_flags= 0;
       if (c_flag)
        rs_start.rss_flags |= RF_COPY;
+      if (i_flag)
+       rs_start.rss_flags |= RF_IPC_VALID;
 
       if (do_run)
       {
@@ -308,6 +315,7 @@ PRIVATE void fatal(char *fmt, ...)
 #define KW_DEVICE      "device"
 #define KW_CLASS       "class"
 #define KW_SYSTEM      "system"
+#define KW_IPC         "ipc"
 
 FORWARD void do_driver(config_t *cpe, config_t *config);
 
@@ -673,9 +681,57 @@ struct
        { "SETGRANT",           SYS_SETGRANT },
        { "READBIOS",           SYS_READBIOS },
        { "VM_MAP",             SYS_VM_MAP },
+       { "MAPDMAx",            SYS_MAPDMAx },
        { NULL,         0 }
 };
 
+PRIVATE void do_ipc(config_t *cpe)
+{
+       char *list;
+       size_t listsize, wordlen;
+
+       list= NULL;
+       listsize= 1;
+       list= malloc(listsize);
+       if (list == NULL)
+               fatal("do_ipc: unable to malloc %d bytes", listsize);
+       list[0]= '\0';
+
+       /* Process a list of process names that are allowed to be
+        * contacted
+        */
+       for (; cpe; cpe= cpe->next)
+       {
+               if (cpe->flags & CFG_SUBLIST)
+               {
+                       fatal("do_ipc: unexpected sublist at %s:%d",
+                               cpe->file, cpe->line);
+               }
+               if (cpe->flags & CFG_STRING)
+               {
+                       fatal("do_ipc: unexpected string at %s:%d",
+                               cpe->file, cpe->line);
+               }
+
+               wordlen= strlen(cpe->word);
+
+               listsize += 1 + wordlen;
+               list= realloc(list, listsize);
+               if (list == NULL)
+               {
+                       fatal("do_ipc: unable to realloc %d bytes",
+                               listsize);
+               }
+               strcat(list, " ");
+               strcat(list, cpe->word);
+       }
+       printf("do_ipc: got list '%s'\n", list);
+
+       if (req_ipc)
+               fatal("do_ipc: req_ipc is set");
+       req_ipc= list;
+}
+
 PRIVATE void do_system(config_t *cpe)
 {
        int i, call_nr, word, bits_per_word;
@@ -802,6 +858,11 @@ PRIVATE void do_driver(config_t *cpe, config_t *config)
                        do_system(cpe->next);
                        continue;
                }
+               if (strcmp(cpe->word, KW_IPC) == 0)
+               {
+                       do_ipc(cpe->next);
+                       continue;
+               }
 
        }
 }
@@ -941,6 +1002,17 @@ PUBLIC int main(int argc, char **argv)
        do_config(progname, req_config);
       }
 
+      if (req_ipc)
+      {
+             rs_start.rss_ipc= req_ipc+1;      /* Skip initial space */
+             rs_start.rss_ipclen= strlen(rs_start.rss_ipc);
+      }
+      else
+      {
+             rs_start.rss_ipc= NULL;
+             rs_start.rss_ipclen= 0;
+      }
+
       m.RS_CMD_ADDR = (char *) &rs_start;
 
       /* Build request message and send the request. */