]> Zhao Yanbai Git Server - minix.git/commitdiff
kernel: add safememset() kernel call
authorArne Welzel <arne.welzel@gmail.com>
Sat, 22 Sep 2012 20:01:05 +0000 (20:01 +0000)
committerBen Gras <ben@minix3.org>
Wed, 26 Sep 2012 00:18:00 +0000 (02:18 +0200)
include/minix/com.h
kernel/system.c
kernel/system.h
kernel/system/Makefile.inc
kernel/system/do_safememset.c [new file with mode: 0644]

index 7ff70e30c751913b4cbc260b663566246521026d..b44dccffa2bba066ab5371c03cc30e0aae2acf96 100644 (file)
 #  define SYS_SCHEDCTL (KERNEL_CALL + 54)      /* sys_schedctl() */
 #  define SYS_STATECTL (KERNEL_CALL + 55)      /* sys_statectl() */
 
+#  define SYS_SAFEMEMSET (KERNEL_CALL + 56)    /* sys_safememset() */
+
 /* Total */
-#define NR_SYS_CALLS   56      /* number of kernel calls */
+#define NR_SYS_CALLS   57      /* number of kernel calls */
 
 #define SYS_CALL_MASK_SIZE BITMAP_CHUNKS(NR_SYS_CALLS)
 
 #define SYS_BASIC_CALLS \
     SYS_EXIT, SYS_SAFECOPYFROM, SYS_SAFECOPYTO, SYS_VSAFECOPY, SYS_GETINFO, \
     SYS_TIMES, SYS_SETALARM, SYS_SETGRANT, SYS_SAFEMAP, SYS_SAFEREVMAP, \
-    SYS_SAFEUNMAP, SYS_PROFBUF, SYS_SYSCTL, SYS_STATECTL
+    SYS_SAFEUNMAP, SYS_PROFBUF, SYS_SYSCTL, SYS_STATECTL, SYS_SAFEMEMSET
 
 /* Field names for SYS_MEMSET. */
 #define MEM_PTR                m2_p1   /* base */
 #define        SCP_ADDRESS     m2_p1   /* my own address */
 #define        SCP_BYTES       m2_l2   /* bytes from offset */
 
+/* SYS_SAFEMEMSET */
+#define SMS_DST                m2_i1   /* dst endpoint */
+#define SMS_GID                m2_i3   /* grant id */
+#define SMS_OFFSET     m2_l1   /* offset within grant */
+#define        SMS_BYTES       m2_l2   /* bytes from offset */
+#define SMS_PATTERN     m2_i2  /* memset() pattern */
+
 /* Field names for SYS_VSAFECOPY* */
 #define VSCP_VEC_ADDR  m2_p1   /* start of vector */
 #define VSCP_VEC_SIZE  m2_l2   /* elements in vector */
index e19d8f525fd04fd62743aaf1b071c54b016ad225..cb6ef14e8b33ae4e36de5091d286da3ca708c738 100644 (file)
@@ -226,6 +226,9 @@ void system_init(void)
   map(SYS_SAFECOPYTO, do_safecopy_to); /* copy with pre-granted permission */
   map(SYS_VSAFECOPY, do_vsafecopy);    /* vectored safecopy */
 
+  /* safe memset */
+  map(SYS_SAFEMEMSET, do_safememset);  /* safememset */
+
   /* Mapping. */
   map(SYS_SAFEMAP, do_safemap);                /* map pages from other process */
   map(SYS_SAFEREVMAP, do_saferevmap);  /* grantor revokes the map grant */
index 19285a176d2ff8438d52c2dba9ae2bb373d521e7..91a4368485713cdd54a2e4c80bd69b99c0af8d96 100644 (file)
@@ -178,6 +178,8 @@ int do_vmctl(struct proc * caller, message *m_ptr);
 int do_setgrant(struct proc * caller, message *m_ptr);
 int do_readbios(struct proc * caller, message *m_ptr);
 
+int do_safememset(struct proc * caller, message *m_ptr);
+
 int do_safemap(struct proc * caller, message *m_ptr);
 int do_saferevmap(struct proc * caller, message *m_ptr);
 int do_safeunmap(struct proc * caller, message *m_ptr);
index c4ccc04ed69ebdcf43e8fbf982bf51787d3ed2a5..50f4e41b387ce05d8a09876253bd58bdd1dd307e 100644 (file)
@@ -25,6 +25,7 @@ SRCS+=        \
        do_setgrant.c \
        do_privctl.c \
        do_safecopy.c \
+       do_safememset.c \
        do_safemap.c \
        do_sysctl.c \
        do_getksig.c \
diff --git a/kernel/system/do_safememset.c b/kernel/system/do_safememset.c
new file mode 100644 (file)
index 0000000..cfccec9
--- /dev/null
@@ -0,0 +1,58 @@
+/* The kernel call implemented in this file:
+ *   m_type:   SYS_SAFEMEMSET
+ *
+ * The parameters for this kernel call are:
+ *     SMS_DST         dst endpoint
+ *     SMS_GID         grant id
+ *     SMS_OFFSET      offset within grant
+ *     SMS_PATTERN     memset pattern byte
+ *     SMS_BYTES       bytes from offset
+ */
+#include <assert.h>
+
+#include <minix/safecopies.h>
+
+#include "kernel/system.h"
+#include "kernel.h"
+
+/*===========================================================================*
+ *                              do_safememset                                *
+ *===========================================================================*/
+int do_safememset(struct proc *caller, message *m_ptr) {
+       /* Implementation of the do_safememset() kernel call */
+
+       /* Extract parameters */
+       endpoint_t dst_endpt = m_ptr->SMS_DST;
+       endpoint_t caller_endpt = caller->p_endpoint;
+       cp_grant_id_t grantid = m_ptr->SMS_GID;
+       vir_bytes g_offset = m_ptr->SMS_OFFSET;
+       int pattern = m_ptr->SMS_PATTERN;
+       size_t len = (size_t)m_ptr->SMS_BYTES;
+
+       struct proc *dst_p;
+       endpoint_t new_granter;
+       static vir_bytes v_offset;
+       int r;
+
+       if (dst_endpt == NONE || caller_endpt == NONE)
+               return EFAULT;
+
+       if (!(dst_p = endpoint_lookup(dst_endpt)))
+               return EINVAL;
+
+       if (!(priv(dst_p) && priv(dst_p)->s_grant_table)) {
+               printf("safememset: dst %d has no grant table\n", dst_endpt);
+               return EINVAL;
+       }
+
+       /* Verify permission exists, memset always requires CPF_WRITE */
+       r = verify_grant(dst_endpt, caller_endpt, grantid, len, CPF_WRITE,
+                        g_offset, &v_offset, &new_granter);
+
+       if (r != OK) {
+               printf("safememset: grant %d verify failed %d", grantid, r);
+               return r;
+       }
+
+       return vm_memset(caller, new_granter, v_offset, pattern, len);
+}