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,7 +690,6 @@ extern unsigned long qemu_host_page_mask; | ||
690 | void page_dump(FILE *f); | 690 | void page_dump(FILE *f); |
691 | int page_get_flags(target_ulong address); | 691 | int page_get_flags(target_ulong address); |
692 | void page_set_flags(target_ulong start, target_ulong end, int flags); | 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 | int page_check_range(target_ulong start, target_ulong len, int flags); | 693 | int page_check_range(target_ulong start, target_ulong len, int flags); |
695 | 694 | ||
696 | CPUState *cpu_copy(CPUState *env); | 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,10 +1894,19 @@ int page_check_range(target_ulong start, target_ulong len, int flags) | ||
1894 | if( !(p->flags & PAGE_VALID) ) | 1894 | if( !(p->flags & PAGE_VALID) ) |
1895 | return -1; | 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 | return -1; | 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 | return 0; | 1911 | return 0; |
1903 | } | 1912 | } |
@@ -1942,21 +1951,6 @@ int page_unprotect(target_ulong address, unsigned long pc, void *puc) | @@ -1942,21 +1951,6 @@ int page_unprotect(target_ulong address, unsigned long pc, void *puc) | ||
1942 | return 0; | 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 | static inline void tlb_set_dirty(CPUState *env, | 1954 | static inline void tlb_set_dirty(CPUState *env, |
1961 | unsigned long addr, target_ulong vaddr) | 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,8 +207,11 @@ int target_msync(abi_ulong start, abi_ulong len, int flags); | ||
207 | #define VERIFY_READ 0 | 207 | #define VERIFY_READ 0 |
208 | #define VERIFY_WRITE 1 /* implies read access */ | 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 | /* NOTE __get_user and __put_user use host pointers and don't check access. */ | 216 | /* NOTE __get_user and __put_user use host pointers and don't check access. */ |
214 | /* These are usually used to access struct data members once the | 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,7 +2773,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
2773 | ret = 0; /* avoid warning */ | 2773 | ret = 0; /* avoid warning */ |
2774 | break; | 2774 | break; |
2775 | case TARGET_NR_read: | 2775 | case TARGET_NR_read: |
2776 | - page_unprotect_range(arg2, arg3); | ||
2777 | if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) | 2776 | if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) |
2778 | goto efault; | 2777 | goto efault; |
2779 | ret = get_errno(read(arg1, p, arg3)); | 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,7 +4536,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
4537 | break; | 4536 | break; |
4538 | #ifdef TARGET_NR_pread | 4537 | #ifdef TARGET_NR_pread |
4539 | case TARGET_NR_pread: | 4538 | case TARGET_NR_pread: |
4540 | - page_unprotect_range(arg2, arg3); | ||
4541 | if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) | 4539 | if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) |
4542 | goto efault; | 4540 | goto efault; |
4543 | ret = get_errno(pread(arg1, p, arg3, arg4)); | 4541 | ret = get_errno(pread(arg1, p, arg3, arg4)); |