Commit 28be6234fc968a42e835da1e39f7f5da74823b8c

Authored by bellard
1 parent 1455bf48

user access fixes


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3623 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 57 additions and 55 deletions
linux-user/signal.c
@@ -667,7 +667,7 @@ struct rt_sigframe @@ -667,7 +667,7 @@ struct rt_sigframe
667 /* XXX: save x87 state */ 667 /* XXX: save x87 state */
668 static int 668 static int
669 setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate, 669 setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
670 - CPUX86State *env, unsigned long mask) 670 + CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
671 { 671 {
672 int err = 0; 672 int err = 0;
673 uint16_t magic; 673 uint16_t magic;
@@ -693,11 +693,11 @@ setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate, @@ -693,11 +693,11 @@ setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
693 err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal); 693 err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
694 err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss); 694 err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
695 695
696 - cpu_x86_fsave(env, (void *)fpstate, 1); 696 + cpu_x86_fsave(env, fpstate_addr, 1);
697 fpstate->status = fpstate->sw; 697 fpstate->status = fpstate->sw;
698 magic = 0xffff; 698 magic = 0xffff;
699 err |= __put_user(magic, &fpstate->magic); 699 err |= __put_user(magic, &fpstate->magic);
700 - err |= __put_user(fpstate, &sc->fpstate); 700 + err |= __put_user(fpstate_addr, &sc->fpstate);
701 701
702 /* non-iBCS2 extensions.. */ 702 /* non-iBCS2 extensions.. */
703 err |= __put_user(mask, &sc->oldmask); 703 err |= __put_user(mask, &sc->oldmask);
@@ -754,7 +754,8 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, @@ -754,7 +754,8 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
754 if (err) 754 if (err)
755 goto give_sigsegv; 755 goto give_sigsegv;
756 756
757 - setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0]); 757 + setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
  758 + frame_addr + offsetof(struct sigframe, fpstate));
758 if (err) 759 if (err)
759 goto give_sigsegv; 760 goto give_sigsegv;
760 761
@@ -769,7 +770,9 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, @@ -769,7 +770,9 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
769 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); 770 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
770 } else { 771 } else {
771 uint16_t val16; 772 uint16_t val16;
772 - err |= __put_user(frame->retcode, &frame->pretcode); 773 + abi_ulong retcode_addr;
  774 + retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
  775 + err |= __put_user(retcode_addr, &frame->pretcode);
773 /* This is popl %eax ; movl $,%eax ; int $0x80 */ 776 /* This is popl %eax ; movl $,%eax ; int $0x80 */
774 val16 = 0xb858; 777 val16 = 0xb858;
775 err |= __put_user(val16, (uint16_t *)(frame->retcode+0)); 778 err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
@@ -782,8 +785,8 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, @@ -782,8 +785,8 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
782 goto give_sigsegv; 785 goto give_sigsegv;
783 786
784 /* Set up registers for signal handler */ 787 /* Set up registers for signal handler */
785 - env->regs[R_ESP] = h2g(frame);  
786 - env->eip = (unsigned long) ka->sa._sa_handler; 788 + env->regs[R_ESP] = frame_addr;
  789 + env->eip = ka->sa._sa_handler;
787 790
788 cpu_x86_load_seg(env, R_DS, __USER_DS); 791 cpu_x86_load_seg(env, R_DS, __USER_DS);
789 cpu_x86_load_seg(env, R_ES, __USER_DS); 792 cpu_x86_load_seg(env, R_ES, __USER_DS);
@@ -807,7 +810,7 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, @@ -807,7 +810,7 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
807 target_siginfo_t *info, 810 target_siginfo_t *info,
808 target_sigset_t *set, CPUX86State *env) 811 target_sigset_t *set, CPUX86State *env)
809 { 812 {
810 - abi_ulong frame_addr; 813 + abi_ulong frame_addr, addr;
811 struct rt_sigframe *frame; 814 struct rt_sigframe *frame;
812 int i, err = 0; 815 int i, err = 0;
813 816
@@ -822,8 +825,10 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, @@ -822,8 +825,10 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
822 ? current->exec_domain->signal_invmap[sig] 825 ? current->exec_domain->signal_invmap[sig]
823 : */sig), 826 : */sig),
824 &frame->sig); 827 &frame->sig);
825 - err |= __put_user((abi_ulong)&frame->info, &frame->pinfo);  
826 - err |= __put_user((abi_ulong)&frame->uc, &frame->puc); 828 + addr = frame_addr + offsetof(struct rt_sigframe, info);
  829 + err |= __put_user(addr, &frame->pinfo);
  830 + addr = frame_addr + offsetof(struct rt_sigframe, uc);
  831 + err |= __put_user(addr, &frame->puc);
827 err |= copy_siginfo_to_user(&frame->info, info); 832 err |= copy_siginfo_to_user(&frame->info, info);
828 if (err) 833 if (err)
829 goto give_sigsegv; 834 goto give_sigsegv;
@@ -838,7 +843,8 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, @@ -838,7 +843,8 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
838 err |= __put_user(target_sigaltstack_used.ss_size, 843 err |= __put_user(target_sigaltstack_used.ss_size,
839 &frame->uc.tuc_stack.ss_size); 844 &frame->uc.tuc_stack.ss_size);
840 err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate, 845 err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
841 - env, set->sig[0]); 846 + env, set->sig[0],
  847 + frame_addr + offsetof(struct rt_sigframe, fpstate));
842 for(i = 0; i < TARGET_NSIG_WORDS; i++) { 848 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
843 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i])) 849 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
844 goto give_sigsegv; 850 goto give_sigsegv;
@@ -850,8 +856,8 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, @@ -850,8 +856,8 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
850 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); 856 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
851 } else { 857 } else {
852 uint16_t val16; 858 uint16_t val16;
853 -  
854 - err |= __put_user(frame->retcode, &frame->pretcode); 859 + addr = frame_addr + offsetof(struct rt_sigframe, retcode);
  860 + err |= __put_user(addr, &frame->pretcode);
855 /* This is movl $,%eax ; int $0x80 */ 861 /* This is movl $,%eax ; int $0x80 */
856 err |= __put_user(0xb8, (char *)(frame->retcode+0)); 862 err |= __put_user(0xb8, (char *)(frame->retcode+0));
857 err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1)); 863 err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
@@ -863,8 +869,8 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, @@ -863,8 +869,8 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
863 goto give_sigsegv; 869 goto give_sigsegv;
864 870
865 /* Set up registers for signal handler */ 871 /* Set up registers for signal handler */
866 - env->regs[R_ESP] = (unsigned long) frame;  
867 - env->eip = (unsigned long) ka->sa._sa_handler; 872 + env->regs[R_ESP] = frame_addr;
  873 + env->eip = ka->sa._sa_handler;
868 874
869 cpu_x86_load_seg(env, R_DS, __USER_DS); 875 cpu_x86_load_seg(env, R_DS, __USER_DS);
870 cpu_x86_load_seg(env, R_ES, __USER_DS); 876 cpu_x86_load_seg(env, R_ES, __USER_DS);
@@ -887,49 +893,42 @@ static int @@ -887,49 +893,42 @@ static int
887 restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax) 893 restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
888 { 894 {
889 unsigned int err = 0; 895 unsigned int err = 0;
890 -  
891 - cpu_x86_load_seg(env, R_GS, lduw(&sc->gs));  
892 - cpu_x86_load_seg(env, R_FS, lduw(&sc->fs));  
893 - cpu_x86_load_seg(env, R_ES, lduw(&sc->es));  
894 - cpu_x86_load_seg(env, R_DS, lduw(&sc->ds));  
895 -  
896 - env->regs[R_EDI] = ldl(&sc->edi);  
897 - env->regs[R_ESI] = ldl(&sc->esi);  
898 - env->regs[R_EBP] = ldl(&sc->ebp);  
899 - env->regs[R_ESP] = ldl(&sc->esp);  
900 - env->regs[R_EBX] = ldl(&sc->ebx);  
901 - env->regs[R_EDX] = ldl(&sc->edx);  
902 - env->regs[R_ECX] = ldl(&sc->ecx);  
903 - env->eip = ldl(&sc->eip); 896 + abi_ulong fpstate_addr;
  897 + unsigned int tmpflags;
  898 +
  899 + cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
  900 + cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
  901 + cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
  902 + cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
  903 +
  904 + env->regs[R_EDI] = tswapl(sc->edi);
  905 + env->regs[R_ESI] = tswapl(sc->esi);
  906 + env->regs[R_EBP] = tswapl(sc->ebp);
  907 + env->regs[R_ESP] = tswapl(sc->esp);
  908 + env->regs[R_EBX] = tswapl(sc->ebx);
  909 + env->regs[R_EDX] = tswapl(sc->edx);
  910 + env->regs[R_ECX] = tswapl(sc->ecx);
  911 + env->eip = tswapl(sc->eip);
904 912
905 cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3); 913 cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
906 cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3); 914 cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
907 915
908 - {  
909 - unsigned int tmpflags;  
910 - tmpflags = ldl(&sc->eflags);  
911 - env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);  
912 - // regs->orig_eax = -1; /* disable syscall checks */  
913 - } 916 + tmpflags = tswapl(sc->eflags);
  917 + env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
  918 + // regs->orig_eax = -1; /* disable syscall checks */
914 919
915 - {  
916 - struct _fpstate * buf;  
917 - buf = (void *)ldl(&sc->fpstate);  
918 - if (buf) {  
919 -#if 0  
920 - if (verify_area(VERIFY_READ, buf, sizeof(*buf)))  
921 - goto badframe;  
922 -#endif  
923 - cpu_x86_frstor(env, (void *)buf, 1);  
924 - } 920 + fpstate_addr = tswapl(sc->fpstate);
  921 + if (fpstate_addr != 0) {
  922 + if (!access_ok(VERIFY_READ, fpstate_addr,
  923 + sizeof(struct target_fpstate)))
  924 + goto badframe;
  925 + cpu_x86_frstor(env, fpstate_addr, 1);
925 } 926 }
926 927
927 - *peax = ldl(&sc->eax); 928 + *peax = tswapl(sc->eax);
928 return err; 929 return err;
929 -#if 0  
930 badframe: 930 badframe:
931 return 1; 931 return 1;
932 -#endif  
933 } 932 }
934 933
935 long do_sigreturn(CPUX86State *env) 934 long do_sigreturn(CPUX86State *env)
@@ -970,27 +969,30 @@ badframe: @@ -970,27 +969,30 @@ badframe:
970 969
971 long do_rt_sigreturn(CPUX86State *env) 970 long do_rt_sigreturn(CPUX86State *env)
972 { 971 {
973 - struct rt_sigframe *frame = (struct rt_sigframe *)g2h(env->regs[R_ESP] - 4); 972 + abi_ulong frame_addr;
  973 + struct rt_sigframe *frame;
974 sigset_t set; 974 sigset_t set;
975 int eax; 975 int eax;
976 976
977 -#if 0  
978 - if (verify_area(VERIFY_READ, frame, sizeof(*frame)))  
979 - goto badframe;  
980 -#endif 977 + frame_addr = env->regs[R_ESP] - 4;
  978 + if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
  979 + goto badframe;
981 target_to_host_sigset(&set, &frame->uc.tuc_sigmask); 980 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
982 sigprocmask(SIG_SETMASK, &set, NULL); 981 sigprocmask(SIG_SETMASK, &set, NULL);
983 982
984 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax)) 983 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
985 goto badframe; 984 goto badframe;
986 985
987 - if (do_sigaltstack(h2g(&frame->uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT) 986 + if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
  987 + get_sp_from_cpustate(env)) == -EFAULT)
988 goto badframe; 988 goto badframe;
989 989
  990 + unlock_user_struct(frame, frame_addr, 0);
990 return eax; 991 return eax;
991 992
992 badframe: 993 badframe:
993 - force_sig(TARGET_SIGSEGV); 994 + unlock_user_struct(frame, frame_addr, 0);
  995 + force_sig(TARGET_SIGSEGV);
994 return 0; 996 return 0;
995 } 997 }
996 998