]> Zhao Yanbai Git Server - minix.git/commitdiff
kernel: Inherit allowed memory, IRQ & I/O ranges 82/3082/2
authorCristiano Giuffrida <giuffrida@cs.vu.nl>
Tue, 11 Mar 2014 16:56:03 +0000 (17:56 +0100)
committerDavid van Moolenbroek <david@minix3.org>
Wed, 16 Sep 2015 11:02:44 +0000 (11:02 +0000)
Inherit at live update time all the priviledges previously acquired by
the process.

Change-Id: I1fd6ab16680ea85a1f3d8d1c106a7c716bf65e8e

minix/kernel/proto.h
minix/kernel/system.c
minix/kernel/system/do_privctl.c
minix/kernel/system/do_update.c

index fd1f6f08127e2e240b21e5d30b3bf05010e052f7..e0161879b9adb3fb0dd9fe6530d7af85c1f3efa2 100644 (file)
@@ -107,6 +107,9 @@ void clear_ipc_filters(struct proc *rp);
 int check_ipc_filter(struct ipc_filter_s *ipcf, int fill_flags);
 int allow_ipc_filtered_msg(struct proc *rp, endpoint_t src_e,
     vir_bytes m_src_v, message *m_src_p);
+int priv_add_irq(struct proc *rp, int irq);
+int priv_add_io(struct proc *rp, struct io_range *ior);
+int priv_add_mem(struct proc *rp, struct minix_mem_range *memr);
 
 /* system/do_vtimer.c */
 void vtimer_check(struct proc *rp);
index 4cf9fdcea0ef0605bce96ed339116771e0e42fe6..ddf2d8f9e7df72adb7e562395c5cdfd10b5adc76 100644 (file)
@@ -841,3 +841,86 @@ int allow_ipc_filtered_msg(struct proc *rp, endpoint_t src_e,
        return allow;
 }
 
+/*===========================================================================*
+ *                             priv_add_irq                                  *
+ *===========================================================================*/
+int priv_add_irq(struct proc *rp, int irq)
+{
+        struct priv *priv = priv(rp);
+        int i;
+
+       priv->s_flags |= CHECK_IRQ;     /* Check IRQ */
+
+       /* When restarting a driver, check if it already has the permission */
+       for (i = 0; i < priv->s_nr_irq; i++) {
+               if (priv->s_irq_tab[i] == irq)
+                       return OK;
+       }
+
+       i= priv->s_nr_irq;
+       if (i >= NR_IRQ) {
+               printf("do_privctl: %d already has %d irq's.\n",
+                       rp->p_endpoint, i);
+               return ENOMEM;
+       }
+       priv->s_irq_tab[i]= irq;
+       priv->s_nr_irq++;
+       return OK;
+}
+
+/*===========================================================================*
+ *                             priv_add_io                                   *
+ *===========================================================================*/
+int priv_add_io(struct proc *rp, struct io_range *ior)
+{
+        struct priv *priv = priv(rp);
+        int i;
+
+       priv->s_flags |= CHECK_IO_PORT; /* Check I/O accesses */
+
+       for (i = 0; i < priv->s_nr_io_range; i++) {
+               if (priv->s_io_tab[i].ior_base == ior->ior_base &&
+                       priv->s_io_tab[i].ior_limit == ior->ior_limit)
+                       return OK;
+       }
+
+       i= priv->s_nr_io_range;
+       if (i >= NR_IO_RANGE) {
+               printf("do_privctl: %d already has %d i/o ranges.\n",
+                       rp->p_endpoint, i);
+               return ENOMEM;
+       }
+
+       priv->s_io_tab[i] = *ior;
+       priv->s_nr_io_range++;
+       return OK;
+}
+
+/*===========================================================================*
+ *                             priv_add_mem                                  *
+ *===========================================================================*/
+int priv_add_mem(struct proc *rp, struct minix_mem_range *memr)
+{
+        struct priv *priv = priv(rp);
+        int i;
+
+       priv->s_flags |= CHECK_MEM;     /* Check memory mappings */
+
+       /* When restarting a driver, check if it already has the permission */
+       for (i = 0; i < priv->s_nr_mem_range; i++) {
+               if (priv->s_mem_tab[i].mr_base == memr->mr_base &&
+                       priv->s_mem_tab[i].mr_limit == memr->mr_limit)
+                       return OK;
+       }
+
+       i= priv->s_nr_mem_range;
+       if (i >= NR_MEM_RANGE) {
+               printf("do_privctl: %d already has %d mem ranges.\n",
+                       rp->p_endpoint, i);
+               return ENOMEM;
+       }
+       priv->s_mem_tab[i]= *memr;
+       priv->s_nr_mem_range++;
+       return OK;
+}
+
index 0fc6c3118e20dda206ca30b3ef096b7e81f28018..188cea93913e9cd708f11009741d95fee5fd2821 100644 (file)
@@ -198,26 +198,8 @@ int do_privctl(struct proc * caller, message * m_ptr)
        /* Get the I/O range */
        data_copy(caller->p_endpoint, m_ptr->m_lsys_krn_sys_privctl.arg_ptr,
                KERNEL, (vir_bytes) &io_range, sizeof(io_range));
-       priv(rp)->s_flags |= CHECK_IO_PORT;     /* Check I/O accesses */
-
-       for (i = 0; i < priv(rp)->s_nr_io_range; i++) {
-               if (priv(rp)->s_io_tab[i].ior_base == io_range.ior_base &&
-                       priv(rp)->s_io_tab[i].ior_limit == io_range.ior_limit)
-                       return OK;
-       }
-
-       i= priv(rp)->s_nr_io_range;
-       if (i >= NR_IO_RANGE) {
-               printf("do_privctl: %d already has %d i/o ranges.\n",
-                       rp->p_endpoint, i);
-               return ENOMEM;
-       }
-
-       priv(rp)->s_io_tab[i].ior_base= io_range.ior_base;
-       priv(rp)->s_io_tab[i].ior_limit= io_range.ior_limit;
-       priv(rp)->s_nr_io_range++;
-
-       return OK;
+       /* Add the I/O range */
+       return priv_add_io(rp, &io_range);
 
   case SYS_PRIV_ADD_MEM:
        if (RTS_ISSET(rp, RTS_NO_PRIV))
@@ -228,27 +210,8 @@ int do_privctl(struct proc * caller, message * m_ptr)
                m_ptr->m_lsys_krn_sys_privctl.arg_ptr, KERNEL,
                (vir_bytes) &mem_range, sizeof(mem_range))) != OK)
                return r;
-       priv(rp)->s_flags |= CHECK_MEM; /* Check memory mappings */
-
-       /* When restarting a driver, check if it already has the permission */
-       for (i = 0; i < priv(rp)->s_nr_mem_range; i++) {
-               if (priv(rp)->s_mem_tab[i].mr_base == mem_range.mr_base &&
-                       priv(rp)->s_mem_tab[i].mr_limit == mem_range.mr_limit)
-                       return OK;
-       }
-
-       i= priv(rp)->s_nr_mem_range;
-       if (i >= NR_MEM_RANGE) {
-               printf("do_privctl: %d already has %d mem ranges.\n",
-                       rp->p_endpoint, i);
-               return ENOMEM;
-       }
-
-       priv(rp)->s_mem_tab[i].mr_base= mem_range.mr_base;
-       priv(rp)->s_mem_tab[i].mr_limit= mem_range.mr_limit;
-       priv(rp)->s_nr_mem_range++;
-
-       return OK;
+       /* Add the memory range */
+       return priv_add_mem(rp, &mem_range);
 
   case SYS_PRIV_ADD_IRQ:
        if (RTS_ISSET(rp, RTS_NO_PRIV))
@@ -261,24 +224,9 @@ int do_privctl(struct proc * caller, message * m_ptr)
 #endif
        data_copy(caller->p_endpoint, m_ptr->m_lsys_krn_sys_privctl.arg_ptr,
                KERNEL, (vir_bytes) &irq, sizeof(irq));
-       priv(rp)->s_flags |= CHECK_IRQ; /* Check IRQs */
-
-       /* When restarting a driver, check if it already has the permission */
-       for (i = 0; i < priv(rp)->s_nr_irq; i++) {
-               if (priv(rp)->s_irq_tab[i] == irq)
-                       return OK;
-       }
-
-       i= priv(rp)->s_nr_irq;
-       if (i >= NR_IRQ) {
-               printf("do_privctl: %d already has %d irq's.\n",
-                       rp->p_endpoint, i);
-               return ENOMEM;
-       }
-       priv(rp)->s_irq_tab[i]= irq;
-       priv(rp)->s_nr_irq++;
+       /* Add the IRQ. */
+       return priv_add_irq(rp, irq);
 
-       return OK;
   case SYS_PRIV_QUERY_MEM:
   {
        phys_bytes addr, limit;
index 36559156e2eb175ddae0c4cf0d5c33ac84dd6de9..14792c92eecde6b6c2b748b38bb9874877ed85ac 100644 (file)
@@ -20,6 +20,9 @@
     (RTS_ISSET(p, RTS_NO_PRIV) || RTS_ISSET(p, RTS_SIG_PENDING) \
     || (RTS_ISSET(p, RTS_RECEIVING) && !RTS_ISSET(p, RTS_SENDING)))
 
+static int inherit_priv_irq(struct proc *src_rp, struct proc *dst_rp);
+static int inherit_priv_io(struct proc *src_rp, struct proc *dst_rp);
+static int inherit_priv_mem(struct proc *src_rp, struct proc *dst_rp);
 static void adjust_proc_slot(struct proc *rp, struct proc *from_rp);
 static void adjust_priv_slot(struct priv *privp, struct priv
        *from_privp);
@@ -42,7 +45,7 @@ int do_update(struct proc * caller, message * m_ptr)
   struct proc orig_dst_proc;
   struct priv orig_src_priv;
   struct priv orig_dst_priv;
-  int i;
+  int i, r;
 
   /* Lookup slots for source and destination process. */
   src_e = m_ptr->SYS_UPD_SRC_ENDPT;
@@ -82,6 +85,20 @@ int do_update(struct proc * caller, message * m_ptr)
   printf("do_update: curr ptproc %d\n", get_cpulocal_var(ptproc)->p_endpoint);
 #endif
 
+  /* Let destination inherit allowed IRQ, I/O ranges, and memory ranges. */
+  r = inherit_priv_irq(src_rp, dst_rp);
+  if(r != OK) {
+      return r;
+  }
+  r = inherit_priv_io(src_rp, dst_rp);
+  if(r != OK) {
+      return r;
+  }
+  r = inherit_priv_mem(src_rp, dst_rp);
+  if(r != OK) {
+      return r;
+  }
+
   /* Let destination inherit the target mask from source. */
   for (i=0; i < NR_SYS_PROCS; i++) {
       if (get_sys_bit(priv(src_rp)->s_ipc_to, i)) {
@@ -130,6 +147,54 @@ int do_update(struct proc * caller, message * m_ptr)
   return OK;
 }
 
+/*===========================================================================*
+ *                          inherit_priv_irq                                *
+ *===========================================================================*/
+int inherit_priv_irq(struct proc *src_rp, struct proc *dst_rp)
+{
+  int i, r;
+  for (i= 0; i<priv(src_rp)->s_nr_irq; i++) {
+      r = priv_add_irq(dst_rp, priv(src_rp)->s_irq_tab[i]); 
+      if(r != OK) {
+          return r;
+      }
+  }
+
+  return OK;
+}
+
+/*===========================================================================*
+ *                          inherit_priv_io                                 *
+ *===========================================================================*/
+ int inherit_priv_io(struct proc *src_rp, struct proc *dst_rp)
+{
+  int i, r;
+  for (i= 0; i<priv(src_rp)->s_nr_io_range; i++) {
+      r = priv_add_io(dst_rp, &(priv(src_rp)->s_io_tab[i])); 
+      if(r != OK) {
+          return r;
+      }
+  }
+
+  return OK;
+}
+
+/*===========================================================================*
+ *                          inherit_priv_mem                                *
+ *===========================================================================*/
+int inherit_priv_mem(struct proc *src_rp, struct proc *dst_rp)
+{
+  int i, r;
+  for (i= 0; i<priv(src_rp)->s_nr_mem_range; i++) {
+      r = priv_add_mem(dst_rp, &(priv(src_rp)->s_mem_tab[i])); 
+      if(r != OK) {
+          return r;
+      }
+  }
+
+  return OK;
+}
+
 /*===========================================================================*
  *                          adjust_proc_slot                                *
  *===========================================================================*/