# 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 */
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 */
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);
do_setgrant.c \
do_privctl.c \
do_safecopy.c \
+ do_safememset.c \
do_safemap.c \
do_sysctl.c \
do_getksig.c \
--- /dev/null
+/* 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);
+}