Beispiel #1
0
static int
linux_read_ldt(struct lwp *l, const struct linux_sys_modify_ldt_args *uap,
    register_t *retval)
{
	struct x86_get_ldt_args gl;
	int error;
	union descriptor *ldt_buf;
	size_t sz;

	/*
	 * I've checked the linux code - this function is asymetric with
	 * linux_write_ldt, and returns raw ldt entries.
	 * NB, the code I saw zerod the spare parts of the user buffer.
	 */

	DPRINTF(("linux_read_ldt!"));

	sz = 8192 * sizeof(*ldt_buf);
	ldt_buf = kmem_zalloc(sz, KM_SLEEP);
	gl.start = 0;
	gl.desc = NULL;
	gl.num = SCARG(uap, bytecount) / sizeof(union descriptor);
	error = x86_get_ldt1(l, &gl, ldt_buf);
	/* NB gl.num might have changed */
	if (error == 0) {
		*retval = gl.num * sizeof *ldt;
		error = copyout(ldt_buf, SCARG(uap, ptr),
		    gl.num * sizeof *ldt_buf);
	}
	kmem_free(ldt_buf, sz);

	return error;
}
Beispiel #2
0
static int
linux_read_ldt(struct lwp *l, const struct linux_sys_modify_ldt_args *uap,
    register_t *retval)
{
	struct x86_get_ldt_args gl;
	int error;
	int num_ldt;
	union descriptor *ldt_buf;

	/*
	 * I've checked the linux code - this function is asymetric with
	 * linux_write_ldt, and returns raw ldt entries.
	 * NB, the code I saw zerod the spare parts of the user buffer.
	 */

	DPRINTF(("linux_read_ldt!"));

	num_ldt = x86_get_ldt_len(l);
	if (num_ldt <= 0)
		return EINVAL;

	gl.start = 0;
	gl.desc = NULL;
	gl.num = SCARG(uap, bytecount) / sizeof(union descriptor);

	if (gl.num > num_ldt)
		gl.num = num_ldt;

	ldt_buf = malloc(gl.num * sizeof *ldt, M_TEMP, M_WAITOK);

	error = x86_get_ldt1(l, &gl, ldt_buf);
	/* NB gl.num might have changed */
	if (error == 0) {
		*retval = gl.num * sizeof *ldt;
		error = copyout(ldt_buf, SCARG(uap, ptr),
		    gl.num * sizeof *ldt_buf);
	}
	free(ldt_buf, M_TEMP);

	return error;
}