forked from enlightenment/efl
evil: add mprotect() and fix a bit mmap(). Elm_test is working
Test Plan: compilation aand elm_test working Reviewers: raster, cedric, zmike Reviewed By: zmike Subscribers: #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9493
This commit is contained in:
parent
94b05f15e6
commit
fb023ee6d2
|
@ -6,12 +6,42 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <io.h>
|
||||
|
||||
#include "sys/mman.h"
|
||||
#include "evil_private.h"
|
||||
|
||||
/*
|
||||
* Possible values
|
||||
* PAGE_EXECUTE_READ (equivalent to PAGE_EXECUTE_WRITECOPY)
|
||||
* PAGE_EXECUTE_READWRITE
|
||||
* PAGE_READONLY (equivalent to PAGE_WRITECOPY)
|
||||
* PAGE_READWRITE
|
||||
*/
|
||||
static DWORD
|
||||
_evil_mmap_protection_get(int prot)
|
||||
{
|
||||
if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
|
||||
return 0xffffffff;
|
||||
|
||||
if (prot & PROT_WRITE)
|
||||
{
|
||||
if (prot & PROT_EXEC)
|
||||
return PAGE_EXECUTE_READWRITE;
|
||||
else
|
||||
return PAGE_READWRITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (prot & PROT_EXEC)
|
||||
return PAGE_EXECUTE_READ;
|
||||
else
|
||||
return PAGE_READONLY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***** API *****/
|
||||
|
||||
|
@ -25,51 +55,39 @@ mmap(void *addr EVIL_UNUSED,
|
|||
off_t offset)
|
||||
{
|
||||
HANDLE fm;
|
||||
DWORD protect = PAGE_NOACCESS;
|
||||
DWORD protect;
|
||||
DWORD acs = 0;
|
||||
HANDLE handle;
|
||||
void *data;
|
||||
|
||||
/* support only MAP_SHARED */
|
||||
if (!(flags & MAP_SHARED))
|
||||
/* get protection */
|
||||
protect = _evil_mmap_protection_get(prot);
|
||||
if (protect == 0xffffffff)
|
||||
return MAP_FAILED;
|
||||
|
||||
if (prot & PROT_EXEC)
|
||||
/* check if the mapping is backed by a file or not */
|
||||
if (fd == -1)
|
||||
{
|
||||
if (prot & PROT_READ)
|
||||
{
|
||||
if (prot & PROT_WRITE)
|
||||
protect = PAGE_EXECUTE_READWRITE;
|
||||
else
|
||||
protect = PAGE_EXECUTE_READ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (prot & PROT_WRITE)
|
||||
protect = PAGE_EXECUTE_WRITECOPY;
|
||||
else
|
||||
protect = PAGE_EXECUTE;
|
||||
}
|
||||
/* shared memory */
|
||||
if (!(flags & MAP_ANON) || offset)
|
||||
return MAP_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (prot & PROT_READ)
|
||||
{
|
||||
if (prot & PROT_WRITE)
|
||||
protect = PAGE_READWRITE;
|
||||
else
|
||||
protect = PAGE_READONLY;
|
||||
}
|
||||
else if (prot & PROT_WRITE)
|
||||
protect = PAGE_WRITECOPY;
|
||||
if (flags & MAP_ANON)
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
handle = (HANDLE)_get_osfhandle(fd);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
if (fd == -1)
|
||||
handle = INVALID_HANDLE_VALUE;
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "[Evil] [mmap] _get_osfhandle failed\n");
|
||||
|
||||
return MAP_FAILED;
|
||||
handle = (HANDLE)_get_osfhandle(fd);
|
||||
if ((errno == EBADF) && (handle == INVALID_HANDLE_VALUE))
|
||||
{
|
||||
fprintf(stderr, "[Evil] [mmap] _get_osfhandle failed\n");
|
||||
return MAP_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
fm = CreateFileMapping(handle, NULL, protect, 0, 0, NULL);
|
||||
|
@ -80,21 +98,14 @@ mmap(void *addr EVIL_UNUSED,
|
|||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
if ((protect & PAGE_READWRITE) == PAGE_READWRITE)
|
||||
acs = FILE_MAP_ALL_ACCESS;
|
||||
else if ((protect & PAGE_WRITECOPY) == PAGE_WRITECOPY)
|
||||
acs = FILE_MAP_COPY;
|
||||
#if 0
|
||||
if (protect & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_READ))
|
||||
acs = FILE_MAP_EXECUTE;
|
||||
#endif
|
||||
else if (protect & (PAGE_READWRITE | PAGE_READONLY))
|
||||
acs = FILE_MAP_READ;
|
||||
if (prot & PROT_WRITE)
|
||||
acs = FILE_MAP_WRITE;
|
||||
else
|
||||
{
|
||||
if ((protect & PAGE_WRITECOPY) == PAGE_WRITECOPY)
|
||||
acs = FILE_MAP_WRITE;
|
||||
}
|
||||
acs = FILE_MAP_READ;
|
||||
if (prot & PROT_EXEC)
|
||||
acs |= FILE_MAP_EXECUTE;
|
||||
if (prot & MAP_PRIVATE)
|
||||
acs |= FILE_MAP_COPY;
|
||||
|
||||
data = MapViewOfFile(fm,
|
||||
acs,
|
||||
|
@ -126,3 +137,10 @@ munmap(void *addr,
|
|||
|
||||
return (res == 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
mprotect(void *addr, size_t len, int prot)
|
||||
{
|
||||
DWORD old;
|
||||
return VirtualProtect(addr, len, _evil_mmap_protection_get(prot), &old) ? 0 : -1;
|
||||
}
|
||||
|
|
|
@ -71,6 +71,8 @@ extern "C" {
|
|||
#define MAP_SHARED 0x0001
|
||||
#define MAP_PRIVATE 0x0002
|
||||
#define MAP_FIXED 0x0010
|
||||
#define MAP_ANON 0x0020
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
|
||||
#define MAP_FAILED ((void *)-1)
|
||||
|
||||
|
@ -154,6 +156,26 @@ EAPI void *mmap(void *addr,
|
|||
EAPI int munmap(void *addr,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* Changes protection for the calling process' address.
|
||||
*
|
||||
* @param addr Pointer to the base address.
|
||||
* @param len Length of the memory.
|
||||
* @param New protection.
|
||||
* @return 0 on success, -1 otherwise.
|
||||
*
|
||||
* Changes protection for the calling process' memory page.
|
||||
* @p addr must be a valid adress in the user space. @p prot
|
||||
* must be compatible with the old protection.
|
||||
*
|
||||
* Conformity: None.
|
||||
*
|
||||
* Supported OS: Windows Vista
|
||||
*
|
||||
* @ingroup Evil_Mman
|
||||
*/
|
||||
EAPI int mprotect(void *addr, size_t len, int prot);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue