Commit dae3270c6e25062b9085da0756b68fafedc9bb2c
1 parent
9b0b8203
suppressed page_unprotect_range() - fixed access_ok()
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3641 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
17 additions
and
23 deletions
cpu-all.h
| ... | ... | @@ -690,7 +690,6 @@ extern unsigned long qemu_host_page_mask; |
| 690 | 690 | void page_dump(FILE *f); |
| 691 | 691 | int page_get_flags(target_ulong address); |
| 692 | 692 | void page_set_flags(target_ulong start, target_ulong end, int flags); |
| 693 | -void page_unprotect_range(target_ulong data, target_ulong data_size); | |
| 694 | 693 | int page_check_range(target_ulong start, target_ulong len, int flags); |
| 695 | 694 | |
| 696 | 695 | CPUState *cpu_copy(CPUState *env); | ... | ... |
exec.c
| ... | ... | @@ -1894,10 +1894,19 @@ int page_check_range(target_ulong start, target_ulong len, int flags) |
| 1894 | 1894 | if( !(p->flags & PAGE_VALID) ) |
| 1895 | 1895 | return -1; |
| 1896 | 1896 | |
| 1897 | - if (!(p->flags & PAGE_READ) && (flags & PAGE_READ) ) | |
| 1898 | - return -1; | |
| 1899 | - if (!(p->flags & PAGE_WRITE) && (flags & PAGE_WRITE) ) | |
| 1897 | + if ((flags & PAGE_READ) && !(p->flags & PAGE_READ)) | |
| 1900 | 1898 | return -1; |
| 1899 | + if (flags & PAGE_WRITE) { | |
| 1900 | + if (!(p->flags & PAGE_WRITE_ORG)) | |
| 1901 | + return -1; | |
| 1902 | + /* unprotect the page if it was put read-only because it | |
| 1903 | + contains translated code */ | |
| 1904 | + if (!(p->flags & PAGE_WRITE)) { | |
| 1905 | + if (!page_unprotect(addr, 0, NULL)) | |
| 1906 | + return -1; | |
| 1907 | + } | |
| 1908 | + return 0; | |
| 1909 | + } | |
| 1901 | 1910 | } |
| 1902 | 1911 | return 0; |
| 1903 | 1912 | } |
| ... | ... | @@ -1942,21 +1951,6 @@ int page_unprotect(target_ulong address, unsigned long pc, void *puc) |
| 1942 | 1951 | return 0; |
| 1943 | 1952 | } |
| 1944 | 1953 | |
| 1945 | -/* call this function when system calls directly modify a memory area */ | |
| 1946 | -/* ??? This should be redundant now we have lock_user. */ | |
| 1947 | -void page_unprotect_range(target_ulong data, target_ulong data_size) | |
| 1948 | -{ | |
| 1949 | - target_ulong start, end, addr; | |
| 1950 | - | |
| 1951 | - start = data; | |
| 1952 | - end = start + data_size; | |
| 1953 | - start &= TARGET_PAGE_MASK; | |
| 1954 | - end = TARGET_PAGE_ALIGN(end); | |
| 1955 | - for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) { | |
| 1956 | - page_unprotect(addr, 0, NULL); | |
| 1957 | - } | |
| 1958 | -} | |
| 1959 | - | |
| 1960 | 1954 | static inline void tlb_set_dirty(CPUState *env, |
| 1961 | 1955 | unsigned long addr, target_ulong vaddr) |
| 1962 | 1956 | { | ... | ... |
linux-user/qemu.h
| ... | ... | @@ -207,8 +207,11 @@ int target_msync(abi_ulong start, abi_ulong len, int flags); |
| 207 | 207 | #define VERIFY_READ 0 |
| 208 | 208 | #define VERIFY_WRITE 1 /* implies read access */ |
| 209 | 209 | |
| 210 | -#define access_ok(type,addr,size) \ | |
| 211 | - (page_check_range((target_ulong)addr,size,(type==VERIFY_READ)?PAGE_READ:PAGE_WRITE)==0) | |
| 210 | +static inline int access_ok(int type, abi_ulong addr, abi_ulong size) | |
| 211 | +{ | |
| 212 | + return page_check_range((target_ulong)addr, size, | |
| 213 | + (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0; | |
| 214 | +} | |
| 212 | 215 | |
| 213 | 216 | /* NOTE __get_user and __put_user use host pointers and don't check access. */ |
| 214 | 217 | /* These are usually used to access struct data members once the | ... | ... |
linux-user/syscall.c
| ... | ... | @@ -2773,7 +2773,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, |
| 2773 | 2773 | ret = 0; /* avoid warning */ |
| 2774 | 2774 | break; |
| 2775 | 2775 | case TARGET_NR_read: |
| 2776 | - page_unprotect_range(arg2, arg3); | |
| 2777 | 2776 | if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) |
| 2778 | 2777 | goto efault; |
| 2779 | 2778 | ret = get_errno(read(arg1, p, arg3)); |
| ... | ... | @@ -4537,7 +4536,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, |
| 4537 | 4536 | break; |
| 4538 | 4537 | #ifdef TARGET_NR_pread |
| 4539 | 4538 | case TARGET_NR_pread: |
| 4540 | - page_unprotect_range(arg2, arg3); | |
| 4541 | 4539 | if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) |
| 4542 | 4540 | goto efault; |
| 4543 | 4541 | ret = get_errno(pread(arg1, p, arg3, arg4)); | ... | ... |