Allow pixelflinger to work when NX (No Execute) is enabled.
Instead of allocating memory from the (non executable) heap, allocate memory using mspace and ensure that we use mprotect to mark it as PROT_EXEC. This allows pixelflinger to continue to work even when NX protections are enabled. Testing: Using the ApiDemos market app, verify that Apidemos -> Graphics -> OpenGL ES -> GLSurfaceView works when "adb shell setprop debug.egl.hw 0" is set. Change-Id: Ib569cd2543c6fa25688ee76325a712bc2347450b
This commit is contained in:
parent
4e226a5006
commit
beeeee705b
2 changed files with 33 additions and 7 deletions
|
|
@ -19,6 +19,8 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include <cutils/atomic.h>
|
||||
|
|
@ -39,15 +41,14 @@ namespace android {
|
|||
Assembly::Assembly(size_t size)
|
||||
: mCount(1), mSize(0)
|
||||
{
|
||||
mBase = (uint32_t*)malloc(size);
|
||||
if (mBase) {
|
||||
mSize = size;
|
||||
}
|
||||
mBase = (uint32_t*)mspace_malloc(getMspace(), size);
|
||||
mSize = size;
|
||||
ensureMbaseExecutable();
|
||||
}
|
||||
|
||||
Assembly::~Assembly()
|
||||
{
|
||||
free(mBase);
|
||||
mspace_free(getMspace(), mBase);
|
||||
}
|
||||
|
||||
void Assembly::incStrong(const void*) const
|
||||
|
|
@ -75,11 +76,32 @@ uint32_t* Assembly::base() const
|
|||
|
||||
ssize_t Assembly::resize(size_t newSize)
|
||||
{
|
||||
mBase = (uint32_t*)realloc(mBase, newSize);
|
||||
mBase = (uint32_t*)mspace_realloc(getMspace(), mBase, newSize);
|
||||
mSize = newSize;
|
||||
ensureMbaseExecutable();
|
||||
return size();
|
||||
}
|
||||
|
||||
mspace Assembly::getMspace()
|
||||
{
|
||||
static mspace msp = create_contiguous_mspace(2 * 1024, 1024 * 1024, /*locked=*/ false);
|
||||
return msp;
|
||||
}
|
||||
|
||||
void Assembly::ensureMbaseExecutable()
|
||||
{
|
||||
long pagesize = sysconf(_SC_PAGESIZE);
|
||||
long pagemask = ~(pagesize - 1); // assumes pagesize is a power of 2
|
||||
|
||||
uint32_t* pageStart = (uint32_t*) (((uintptr_t) mBase) & pagemask);
|
||||
size_t adjustedLength = mBase - pageStart + mSize;
|
||||
|
||||
if (mBase && mprotect(pageStart, adjustedLength, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) {
|
||||
mspace_free(getMspace(), mBase);
|
||||
mBase = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
CodeCache::CodeCache(size_t size)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <cutils/mspace.h>
|
||||
|
||||
#include "tinyutils/KeyedVector.h"
|
||||
#include "tinyutils/smartpointer.h"
|
||||
|
|
@ -67,9 +68,12 @@ public:
|
|||
typedef void weakref_type;
|
||||
|
||||
private:
|
||||
static mspace getMspace();
|
||||
void ensureMbaseExecutable();
|
||||
|
||||
mutable int32_t mCount;
|
||||
uint32_t* mBase;
|
||||
ssize_t mSize;
|
||||
size_t mSize;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue