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 667 /* XXX: save x87 state */
668 668 static int
669 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 672 int err = 0;
673 673 uint16_t magic;
... ... @@ -693,11 +693,11 @@ setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
693 693 err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
694 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 697 fpstate->status = fpstate->sw;
698 698 magic = 0xffff;
699 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 702 /* non-iBCS2 extensions.. */
703 703 err |= __put_user(mask, &sc->oldmask);
... ... @@ -754,7 +754,8 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
754 754 if (err)
755 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 759 if (err)
759 760 goto give_sigsegv;
760 761  
... ... @@ -769,7 +770,9 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
769 770 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
770 771 } else {
771 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 776 /* This is popl %eax ; movl $,%eax ; int $0x80 */
774 777 val16 = 0xb858;
775 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 785 goto give_sigsegv;
783 786  
784 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 791 cpu_x86_load_seg(env, R_DS, __USER_DS);
789 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 810 target_siginfo_t *info,
808 811 target_sigset_t *set, CPUX86State *env)
809 812 {
810   - abi_ulong frame_addr;
  813 + abi_ulong frame_addr, addr;
811 814 struct rt_sigframe *frame;
812 815 int i, err = 0;
813 816  
... ... @@ -822,8 +825,10 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
822 825 ? current->exec_domain->signal_invmap[sig]
823 826 : */sig),
824 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 832 err |= copy_siginfo_to_user(&frame->info, info);
828 833 if (err)
829 834 goto give_sigsegv;
... ... @@ -838,7 +843,8 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
838 843 err |= __put_user(target_sigaltstack_used.ss_size,
839 844 &frame->uc.tuc_stack.ss_size);
840 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 848 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
843 849 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
844 850 goto give_sigsegv;
... ... @@ -850,8 +856,8 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
850 856 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
851 857 } else {
852 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 861 /* This is movl $,%eax ; int $0x80 */
856 862 err |= __put_user(0xb8, (char *)(frame->retcode+0));
857 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 869 goto give_sigsegv;
864 870  
865 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 875 cpu_x86_load_seg(env, R_DS, __USER_DS);
870 876 cpu_x86_load_seg(env, R_ES, __USER_DS);
... ... @@ -887,49 +893,42 @@ static int
887 893 restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
888 894 {
889 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 913 cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
906 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 929 return err;
929   -#if 0
930 930 badframe:
931 931 return 1;
932   -#endif
933 932 }
934 933  
935 934 long do_sigreturn(CPUX86State *env)
... ... @@ -970,27 +969,30 @@ badframe:
970 969  
971 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 974 sigset_t set;
975 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 980 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
982 981 sigprocmask(SIG_SETMASK, &set, NULL);
983 982  
984 983 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
985 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 988 goto badframe;
989 989  
  990 + unlock_user_struct(frame, frame_addr, 0);
990 991 return eax;
991 992  
992 993 badframe:
993   - force_sig(TARGET_SIGSEGV);
  994 + unlock_user_struct(frame, frame_addr, 0);
  995 + force_sig(TARGET_SIGSEGV);
994 996 return 0;
995 997 }
996 998  
... ...