mirror of https://github.com/xqemu/xqemu.git
suppressed page_unprotect_range() - fixed access_ok()
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3641 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
9b0b82037a
commit
dae3270c6e
|
@ -690,7 +690,6 @@ extern unsigned long qemu_host_page_mask;
|
||||||
void page_dump(FILE *f);
|
void page_dump(FILE *f);
|
||||||
int page_get_flags(target_ulong address);
|
int page_get_flags(target_ulong address);
|
||||||
void page_set_flags(target_ulong start, target_ulong end, int flags);
|
void page_set_flags(target_ulong start, target_ulong end, int flags);
|
||||||
void page_unprotect_range(target_ulong data, target_ulong data_size);
|
|
||||||
int page_check_range(target_ulong start, target_ulong len, int flags);
|
int page_check_range(target_ulong start, target_ulong len, int flags);
|
||||||
|
|
||||||
CPUState *cpu_copy(CPUState *env);
|
CPUState *cpu_copy(CPUState *env);
|
||||||
|
|
28
exec.c
28
exec.c
|
@ -1894,10 +1894,19 @@ int page_check_range(target_ulong start, target_ulong len, int flags)
|
||||||
if( !(p->flags & PAGE_VALID) )
|
if( !(p->flags & PAGE_VALID) )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!(p->flags & PAGE_READ) && (flags & PAGE_READ) )
|
if ((flags & PAGE_READ) && !(p->flags & PAGE_READ))
|
||||||
return -1;
|
return -1;
|
||||||
if (!(p->flags & PAGE_WRITE) && (flags & PAGE_WRITE) )
|
if (flags & PAGE_WRITE) {
|
||||||
|
if (!(p->flags & PAGE_WRITE_ORG))
|
||||||
return -1;
|
return -1;
|
||||||
|
/* unprotect the page if it was put read-only because it
|
||||||
|
contains translated code */
|
||||||
|
if (!(p->flags & PAGE_WRITE)) {
|
||||||
|
if (!page_unprotect(addr, 0, NULL))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1942,21 +1951,6 @@ int page_unprotect(target_ulong address, unsigned long pc, void *puc)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* call this function when system calls directly modify a memory area */
|
|
||||||
/* ??? This should be redundant now we have lock_user. */
|
|
||||||
void page_unprotect_range(target_ulong data, target_ulong data_size)
|
|
||||||
{
|
|
||||||
target_ulong start, end, addr;
|
|
||||||
|
|
||||||
start = data;
|
|
||||||
end = start + data_size;
|
|
||||||
start &= TARGET_PAGE_MASK;
|
|
||||||
end = TARGET_PAGE_ALIGN(end);
|
|
||||||
for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
|
|
||||||
page_unprotect(addr, 0, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void tlb_set_dirty(CPUState *env,
|
static inline void tlb_set_dirty(CPUState *env,
|
||||||
unsigned long addr, target_ulong vaddr)
|
unsigned long addr, target_ulong vaddr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -207,8 +207,11 @@ int target_msync(abi_ulong start, abi_ulong len, int flags);
|
||||||
#define VERIFY_READ 0
|
#define VERIFY_READ 0
|
||||||
#define VERIFY_WRITE 1 /* implies read access */
|
#define VERIFY_WRITE 1 /* implies read access */
|
||||||
|
|
||||||
#define access_ok(type,addr,size) \
|
static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
|
||||||
(page_check_range((target_ulong)addr,size,(type==VERIFY_READ)?PAGE_READ:PAGE_WRITE)==0)
|
{
|
||||||
|
return page_check_range((target_ulong)addr, size,
|
||||||
|
(type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* NOTE __get_user and __put_user use host pointers and don't check access. */
|
/* NOTE __get_user and __put_user use host pointers and don't check access. */
|
||||||
/* These are usually used to access struct data members once the
|
/* These are usually used to access struct data members once the
|
||||||
|
|
|
@ -2773,7 +2773,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||||
ret = 0; /* avoid warning */
|
ret = 0; /* avoid warning */
|
||||||
break;
|
break;
|
||||||
case TARGET_NR_read:
|
case TARGET_NR_read:
|
||||||
page_unprotect_range(arg2, arg3);
|
|
||||||
if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
|
if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
|
||||||
goto efault;
|
goto efault;
|
||||||
ret = get_errno(read(arg1, p, arg3));
|
ret = get_errno(read(arg1, p, arg3));
|
||||||
|
@ -4537,7 +4536,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||||
break;
|
break;
|
||||||
#ifdef TARGET_NR_pread
|
#ifdef TARGET_NR_pread
|
||||||
case TARGET_NR_pread:
|
case TARGET_NR_pread:
|
||||||
page_unprotect_range(arg2, arg3);
|
|
||||||
if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
|
if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
|
||||||
goto efault;
|
goto efault;
|
||||||
ret = get_errno(pread(arg1, p, arg3, arg4));
|
ret = get_errno(pread(arg1, p, arg3, arg4));
|
||||||
|
|
Loading…
Reference in New Issue