. new mode for sys_memset: include process so memset can be done in physical or virtual address space. . add a mode to mmap() that lets a process allocate uninitialized memory. . this allows an exec()er (RS, VFS, etc.) to request uninitialized memory from VM and selectively clear the ranges that don't come from a file, leaving no uninitialized memory left for the process to see. . use callbacks for clearing the process, clearing memory in the process, and copying into the process; so that the libexec code can be used from rs, vfs, and in the future, kernel (to load vm) and vm (to load boot-time processes)
92 lines
2.4 KiB
C
92 lines
2.4 KiB
C
#define _SYSTEM 1
|
|
|
|
#include <minix/type.h>
|
|
#include <minix/const.h>
|
|
#include <sys/param.h>
|
|
#include <assert.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <libexec.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include <minix/ipc.h>
|
|
#include <minix/com.h>
|
|
#include <minix/callnr.h>
|
|
#include <minix/vm.h>
|
|
#include <minix/syslib.h>
|
|
#include <sys/mman.h>
|
|
#include <machine/elf.h>
|
|
|
|
int libexec_alloc_mmap_prealloc(struct exec_info *execi, off_t vaddr, size_t len)
|
|
{
|
|
if(minix_mmap_for(execi->proc_e, (void *) vaddr, len,
|
|
PROT_READ|PROT_WRITE|PROT_EXEC,
|
|
MAP_ANON|MAP_PREALLOC|MAP_UNINITIALIZED|MAP_FIXED, -1, 0) == MAP_FAILED) {
|
|
return ENOMEM;
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
int libexec_alloc_mmap_ondemand(struct exec_info *execi, off_t vaddr, size_t len)
|
|
{
|
|
if(minix_mmap_for(execi->proc_e, (void *) vaddr, len,
|
|
PROT_READ|PROT_WRITE|PROT_EXEC,
|
|
MAP_ANON|MAP_FIXED, -1, 0) == MAP_FAILED) {
|
|
return ENOMEM;
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
int libexec_clearproc_vm_procctl(struct exec_info *execi)
|
|
{
|
|
return vm_procctl(execi->proc_e, VMPPARAM_CLEAR);
|
|
}
|
|
|
|
int libexec_clear_sys_memset(struct exec_info *execi, off_t vaddr, size_t len)
|
|
{
|
|
return sys_memset(execi->proc_e, 0, vaddr, len);
|
|
}
|
|
|
|
void libexec_patch_ptr(char stack[ARG_MAX], vir_bytes base)
|
|
{
|
|
/* When doing an exec(name, argv, envp) call, the user builds up a stack
|
|
* image with arg and env pointers relative to the start of the stack. Now
|
|
* these pointers must be relocated, since the stack is not positioned at
|
|
* address 0 in the user's address space.
|
|
*/
|
|
|
|
char **ap, flag;
|
|
vir_bytes v;
|
|
|
|
flag = 0; /* counts number of 0-pointers seen */
|
|
ap = (char **) stack; /* points initially to 'nargs' */
|
|
ap++; /* now points to argv[0] */
|
|
while (flag < 2) {
|
|
if (ap >= (char **) &stack[ARG_MAX]) return; /* too bad */
|
|
if (*ap != NULL) {
|
|
v = (vir_bytes) *ap; /* v is relative pointer */
|
|
v += base; /* relocate it */
|
|
*ap = (char *) v; /* put it back */
|
|
} else {
|
|
flag++;
|
|
}
|
|
ap++;
|
|
}
|
|
}
|
|
|
|
int libexec_pm_newexec(endpoint_t proc_e, struct exec_info *e)
|
|
{
|
|
int r;
|
|
message m;
|
|
|
|
m.m_type = PM_NEWEXEC;
|
|
m.EXC_NM_PROC = proc_e;
|
|
m.EXC_NM_PTR = (char *)e;
|
|
if ((r = sendrec(PM_PROC_NR, &m)) != OK) return(r);
|
|
|
|
e->allow_setuid = !!(m.m1_i2 & EXC_NM_RF_ALLOW_SETUID);
|
|
|
|
return(m.m_type);
|
|
}
|