Пример #1
0
/*
 * If we fork with active superpages
 * - the parent should still be able to access the superpages
 * - the child should not be able to access the superpages
 */
boolean_t
test_fork() {
	mach_vm_address_t addr = 0;
	mach_vm_size_t	size = SUPERPAGE_SIZE;
	int kr, ret;
	pid_t pid;
	
	kr = mach_vm_allocate(mach_task_self(), &addr, size, VM_FLAGS_ANYWHERE | VM_FLAGS_SUPERPAGE_SIZE_2MB);
	if (!(ret = check_kr(kr, "mach_vm_allocate"))) return ret;

	fflush(stdout);
	if ((pid=fork())) { /* parent */
		if (!(ret = check_rw(addr, size))) return ret;
		waitpid(pid, &ret, 0);
		if (!ret) {
			sprintf(error, "child could access superpage");
			return ret;
		}
	} else { /* child */
		if (!(ret = check_nr(addr, size, NULL))) exit(ret);
		exit(TRUE);
	}
	
	kr = mach_vm_deallocate(mach_task_self(), addr, size);
	if (!(ret = check_kr(kr, "mach_vm_deallocate"))) return ret;
	return TRUE;
}
Пример #2
0
/*
 * Tests one allocation/deallocaton cycle; used in a loop this tests for leaks
 */
boolean_t
test_alloc_dealloc() {
	mach_vm_address_t addr = 0;
	mach_vm_size_t	size = SUPERPAGE_SIZE;
	int kr, ret;
	
	kr = mach_vm_allocate(mach_task_self(), &addr, size, VM_FLAGS_ANYWHERE | VM_FLAGS_SUPERPAGE_SIZE_2MB);
	if (!(ret = check_kr(kr, "mach_vm_allocate"))) return ret;
	if (!(ret = check_addr0(addr, "mach_vm_allocate"))) return ret;
	if (!(ret = check_align(addr))) return ret;
	if (!(ret = check_rw(addr, size))) return ret;
	kr = mach_vm_deallocate(mach_task_self(), addr, size);
	if (!(ret = check_kr(kr, "mach_vm_deallocate"))) return ret;
	return TRUE;
}
Пример #3
0
/*
 * If we allocate a 2 MB superpage read-write without specifying an address,
 * - the call should succeed
 * - not return 0
 * - return a 2 MB aligned address
 * - the memory should be readable and writable
 */
boolean_t
test_allocate() {
	int kr, ret;

	global_addr = 0;
	global_size = SUPERPAGE_SIZE;
	
	kr = mach_vm_allocate(mach_task_self(), &global_addr, global_size, VM_FLAGS_ANYWHERE | VM_FLAGS_SUPERPAGE_SIZE_2MB);
	if (!(ret = check_kr(kr, "mach_vm_allocate"))) return ret;
	if (!(ret = check_addr0(global_addr, "mach_vm_allocate"))) return ret;
	if (!(ret = check_align(global_addr))) return ret;
	if (!(ret = check_rw(global_addr, global_size))) return ret;

	return TRUE;
}
Пример #4
0
/*
 * If we allocate a 2 MB superpage read-write at a 2 MB aligned address,
 * - the call should succeed
 * - return the address we wished for
 * - the memory should be readable and writable
 * If we deallocate it,
 * - the call should succeed
 * - make the memory inaccessible
 */
boolean_t
test_allocatefixed() {
	int kr;
	int ret;
	mach_vm_address_t addr = FIXED_ADDRESS1;
	mach_vm_size_t	size = SUPERPAGE_SIZE;

	kr = mach_vm_allocate(mach_task_self(), &addr, size, VM_FLAGS_SUPERPAGE_SIZE_2MB);
	if (!(ret = check_kr(kr, "mach_vm_allocate"))) return ret;
	if (!(ret = check_addr(addr, FIXED_ADDRESS1, "mach_vm_allocate"))) return ret;
	if (!(ret = check_rw(addr, size))) return ret;
	kr = mach_vm_deallocate(mach_task_self(), addr, size);
	if (!(ret = check_kr(kr, "mach_vm_deallocate"))) return ret;
	if (!(ret = check_nr(addr, size, NULL))) return ret;
	return TRUE;
}
Пример #5
0
/*
 * If we allocate a superpage of any size read-write without specifying an address
 * - the call should succeed
 * - not return 0
 * - the memory should be readable and writable
 * If we deallocate it,
 * - the call should succeed
 * - make the memory inaccessible
 */
boolean_t
test_allocate_size_any() {
	int kr;
	int ret;
	mach_vm_address_t addr = 0;
	mach_vm_size_t	size = 2*PAGE_SIZE; /* will be rounded up to some superpage size */

	kr = mach_vm_allocate(mach_task_self(), &addr, size, VM_FLAGS_ANYWHERE | VM_FLAGS_SUPERPAGE_SIZE_ANY);
	if (!(ret = check_kr(kr, "mach_vm_allocate"))) return ret;
	if (!(ret = check_addr0(addr, "mach_vm_allocate"))) return ret;
	if (!(ret = check_rw(addr, size))) return ret;
	kr = mach_vm_deallocate(mach_task_self(), addr, size);
	if (!(ret = check_kr(kr, "mach_vm_deallocate"))) return ret;
	if (!(ret = check_nr(addr, size, NULL))) return ret;
	return TRUE;
}
Пример #6
0
/*
 * If we try to wire superpages
 * - the call should succeed
 * - the memory should remain readable and writable
 */
boolean_t
test_wire() {
	int kr;
	int ret;
	mach_vm_address_t addr = 0;
	mach_vm_size_t	size = SUPERPAGE_SIZE;

	kr = mach_vm_allocate(mach_task_self(), &addr, size, VM_FLAGS_ANYWHERE | VM_FLAGS_SUPERPAGE_SIZE_2MB);
	if (!(ret = check_kr(kr, "mach_vm_allocate"))) return ret;

	kr = mach_vm_wire(mach_host_self(), mach_task_self(), addr, size, VM_PROT_WRITE | VM_PROT_READ);

	if (!geteuid()) /* may fail as user */
		if (!(ret = check_kr(kr, "mach_vm_wire"))) return ret;

	if (!(ret = check_rw(addr, size))) return ret;

	kr = mach_vm_deallocate(mach_task_self(), addr, size);
	if (!(ret = check_kr(kr, "mach_vm_deallocate"))) return ret;

	return TRUE;
}
Пример #7
0
/*
 * Implement sequence assignment item sub-script for the type.
 */
static int sipVoidPtr_ass_item(PyObject *self, int idx, PyObject *value)
{
    int value_size;
    void *value_ptr;

    if (check_rw(self) < 0 || check_size(self) < 0 || check_index(self, idx) < 0)
        return -1;

    if ((value_size = get_value_data(value, &value_ptr)) < 0)
        return -1;

    if (value_size != 1)
    {
        PyErr_SetString(PyExc_TypeError,
                "right operand must be a single byte");

        return -1;
    }

    ((char *)((sipVoidPtrObject *)self)->voidptr)[idx] = *(char *)value_ptr;

    return 0;
}
Пример #8
0
/*
 * If we try to wire superpages
 * - the call should fail
 * - the memory should remain readable and writable
 * Currently, superpages are always wired.
 */
boolean_t
test_unwire() {
	int kr;
	int ret;
	mach_vm_address_t addr = 0;
	mach_vm_size_t	size = SUPERPAGE_SIZE;

	kr = mach_vm_allocate(mach_task_self(), &addr, size, VM_FLAGS_ANYWHERE | VM_FLAGS_SUPERPAGE_SIZE_2MB);
	if (!(ret = check_kr(kr, "mach_vm_allocate"))) return ret;

	kr = mach_vm_wire(mach_host_self(), mach_task_self(), addr, size, VM_PROT_NONE);
	if ((ret = check_kr(kr, "mach_vm_wire"))) {
		sprintf(error, "could unwire");
		return FALSE;
	}

	if (!(ret = check_rw(addr, size))) return ret;

	kr = mach_vm_deallocate(mach_task_self(), addr, size);
	if (!(ret = check_kr(kr, "mach_vm_deallocate"))) return ret;

	return TRUE;
}
Пример #9
0
/*
 * Implement sequence assignment slice sub-script for the type.
 */
static int sipVoidPtr_ass_slice(PyObject *self, int left, int right,
        PyObject *value)
{
    sipVoidPtrObject *v;
    int value_size;
    void *value_ptr;

    if (check_rw(self) < 0 || check_size(self) < 0)
        return -1;

    if ((value_size = get_value_data(value, &value_ptr)) < 0)
        return -1;

    v = (sipVoidPtrObject *)self;

    fix_bounds(v->size, &left, &right);

    if (check_slice_size(right - left, value_size) < 0)
        return -1;

    memmove((char *)(v->voidptr) + left, value_ptr, right - left);

    return 0;
}
Пример #10
0
/*
 * Implement mapping assignment sub-script for the type.
 */
static int sipVoidPtr_ass_subscript(PyObject *self, PyObject *key,
        PyObject *value)
{
    sipVoidPtrObject *v;
    Py_ssize_t start, size;
#if PY_VERSION_HEX >= 0x02060000
    Py_buffer value_view;
#else
    Py_ssize_t value_size;
    void *value_ptr;
#endif

    if (check_rw(self) < 0 || check_size(self) < 0)
        return -1;

    v = (sipVoidPtrObject *)self;

    if (PyIndex_Check(key))
    {
        start = PyNumber_AsSsize_t(key, PyExc_IndexError);

        if (start == -1 && PyErr_Occurred())
            return -1;

        if (start < 0)
            start += v->size;

        if (check_index(self, start) < 0)
            return -1;

        size = 1;
    }
    else if (PySlice_Check(key))
    {
        Py_ssize_t stop, step;

        if (sipConvertFromSliceObject(key, v->size, &start, &stop, &step, &size) < 0)
            return -1;

        if (step != 1)
        {
            PyErr_SetNone(PyExc_NotImplementedError);
            return -1;
        }
    }
    else
    {
        bad_key(key);

        return -1;
    }

#if PY_VERSION_HEX >= 0x02060000
    if (PyObject_GetBuffer(value, &value_view, PyBUF_CONTIG_RO) < 0)
        return -1;

    /* We could allow any item size... */
    if (value_view.itemsize != 1)
    {
        PyErr_Format(PyExc_TypeError, "'%s' must have an item size of 1",
                Py_TYPE(value_view.obj)->tp_name);

        PyBuffer_Release(&value_view);
        return -1;
    }

    if (check_slice_size(size, value_view.len) < 0)
    {
        PyBuffer_Release(&value_view);
        return -1;
    }

    memmove((char *)v->voidptr + start, value_view.buf, size);

    PyBuffer_Release(&value_view);
#else
    if ((value_size = get_value_data(value, &value_ptr)) < 0)
        return -1;

    if (check_slice_size(size, value_size) < 0)
        return -1;

    memmove((char *)v->voidptr + start, value_ptr, size);
#endif

    return 0;
}