Commit f8b0aa25599782eef91edc00ebf620bd14db720c

Authored by bellard
1 parent 28be6234

fixed more invalid pointer usage


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3624 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 55 additions and 48 deletions
linux-user/signal.c
... ... @@ -1039,8 +1039,8 @@ struct sigframe
1039 1039  
1040 1040 struct rt_sigframe
1041 1041 {
1042   - struct target_siginfo *pinfo;
1043   - void *puc;
  1042 + abi_ulong pinfo;
  1043 + abi_ulong puc;
1044 1044 struct target_siginfo info;
1045 1045 struct target_ucontext uc;
1046 1046 abi_ulong retcode;
... ... @@ -1077,7 +1077,7 @@ static inline int valid_user_regs(CPUState *regs)
1077 1077  
1078 1078 static int
1079 1079 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1080   - CPUState *env, unsigned long mask)
  1080 + CPUState *env, abi_ulong mask)
1081 1081 {
1082 1082 int err = 0;
1083 1083  
... ... @@ -1127,9 +1127,9 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize)
1127 1127  
1128 1128 static int
1129 1129 setup_return(CPUState *env, struct emulated_sigaction *ka,
1130   - abi_ulong *rc, void *frame, int usig)
  1130 + abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1131 1131 {
1132   - abi_ulong handler = (abi_ulong)ka->sa._sa_handler;
  1132 + abi_ulong handler = ka->sa._sa_handler;
1133 1133 abi_ulong retcode;
1134 1134 int thumb = 0;
1135 1135 #if defined(TARGET_CONFIG_CPU_32)
... ... @@ -1160,7 +1160,7 @@ setup_return(CPUState *env, struct emulated_sigaction *ka,
1160 1160 #endif /* TARGET_CONFIG_CPU_32 */
1161 1161  
1162 1162 if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
1163   - retcode = (abi_ulong)ka->sa.sa_restorer;
  1163 + retcode = ka->sa.sa_restorer;
1164 1164 } else {
1165 1165 unsigned int idx = thumb;
1166 1166  
... ... @@ -1173,11 +1173,11 @@ setup_return(CPUState *env, struct emulated_sigaction *ka,
1173 1173 flush_icache_range((abi_ulong)rc,
1174 1174 (abi_ulong)(rc + 1));
1175 1175 #endif
1176   - retcode = ((abi_ulong)rc) + thumb;
  1176 + retcode = rc_addr + thumb;
1177 1177 }
1178 1178  
1179 1179 env->regs[0] = usig;
1180   - env->regs[13] = h2g(frame);
  1180 + env->regs[13] = frame_addr;
1181 1181 env->regs[14] = retcode;
1182 1182 env->regs[15] = handler & (thumb ? ~1 : ~3);
1183 1183  
... ... @@ -1209,7 +1209,8 @@ static void setup_frame(int usig, struct emulated_sigaction *ka,
1209 1209 }
1210 1210  
1211 1211 if (err == 0)
1212   - err = setup_return(regs, ka, &frame->retcode, frame, usig);
  1212 + err = setup_return(regs, ka, &frame->retcode, frame_addr, usig,
  1213 + frame_addr + offsetof(struct sigframe, retcode));
1213 1214  
1214 1215 end:
1215 1216 unlock_user_struct(frame, frame_addr, 1);
... ... @@ -1225,12 +1226,15 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
1225 1226 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1226 1227 struct target_sigaltstack stack;
1227 1228 int i, err = 0;
  1229 + abi_ulong info_addr, uc_addr;
1228 1230  
1229 1231 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1230 1232 return /* 1 */;
1231 1233  
1232   - __put_user_error(&frame->info, (abi_ulong *)&frame->pinfo, err);
1233   - __put_user_error(&frame->uc, (abi_ulong *)&frame->puc, err);
  1234 + info_addr = frame_addr + offsetof(struct rt_sigframe, info);
  1235 + __put_user_error(info_addr, &frame->pinfo, err);
  1236 + uc_addr = frame_addr + offsetof(struct rt_sigframe, uc);
  1237 + __put_user_error(uc_addr, &frame->puc, err);
1234 1238 err |= copy_siginfo_to_user(&frame->info, info);
1235 1239  
1236 1240 /* Clear all the bits of the ucontext we don't use. */
... ... @@ -1250,7 +1254,8 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
1250 1254 }
1251 1255  
1252 1256 if (err == 0)
1253   - err = setup_return(env, ka, &frame->retcode, frame, usig);
  1257 + err = setup_return(env, ka, &frame->retcode, frame_addr, usig,
  1258 + frame_addr + offsetof(struct rt_sigframe, retcode));
1254 1259  
1255 1260 if (err == 0) {
1256 1261 /*
... ... @@ -1258,8 +1263,8 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
1258 1263 * arguments for the signal handler.
1259 1264 * -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
1260 1265 */
1261   - env->regs[1] = (abi_ulong)frame->pinfo;
1262   - env->regs[2] = (abi_ulong)frame->puc;
  1266 + env->regs[1] = info_addr;
  1267 + env->regs[2] = uc_addr;
1263 1268 }
1264 1269  
1265 1270 end:
... ... @@ -1302,6 +1307,7 @@ restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
1302 1307  
1303 1308 long do_sigreturn(CPUState *env)
1304 1309 {
  1310 + abi_ulong frame_addr;
1305 1311 struct sigframe *frame;
1306 1312 target_sigset_t set;
1307 1313 sigset_t host_set;
... ... @@ -1315,12 +1321,10 @@ long do_sigreturn(CPUState *env)
1315 1321 if (env->regs[13] & 7)
1316 1322 goto badframe;
1317 1323  
1318   - frame = (struct sigframe *)g2h(env->regs[13]);
  1324 + frame_addr = env->regs[13];
  1325 + if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
  1326 + goto badframe;
1319 1327  
1320   -#if 0
1321   - if (verify_area(VERIFY_READ, frame, sizeof (*frame)))
1322   - goto badframe;
1323   -#endif
1324 1328 if (__get_user(set.sig[0], &frame->sc.oldmask))
1325 1329 goto badframe;
1326 1330 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
... ... @@ -1339,15 +1343,18 @@ long do_sigreturn(CPUState *env)
1339 1343 if (ptrace_cancel_bpt(current))
1340 1344 send_sig(SIGTRAP, current, 1);
1341 1345 #endif
1342   - return env->regs[0];
  1346 + unlock_user_struct(frame, frame_addr, 0);
  1347 + return env->regs[0];
1343 1348  
1344 1349 badframe:
  1350 + unlock_user_struct(frame, frame_addr, 0);
1345 1351 force_sig(SIGSEGV /* , current */);
1346 1352 return 0;
1347 1353 }
1348 1354  
1349 1355 long do_rt_sigreturn(CPUState *env)
1350 1356 {
  1357 + abi_ulong frame_addr;
1351 1358 struct rt_sigframe *frame;
1352 1359 sigset_t host_set;
1353 1360  
... ... @@ -1359,19 +1366,17 @@ long do_rt_sigreturn(CPUState *env)
1359 1366 if (env->regs[13] & 7)
1360 1367 goto badframe;
1361 1368  
1362   - frame = (struct rt_sigframe *)env->regs[13];
  1369 + frame_addr = env->regs[13];
  1370 + if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
  1371 + goto badframe;
1363 1372  
1364   -#if 0
1365   - if (verify_area(VERIFY_READ, frame, sizeof (*frame)))
1366   - goto badframe;
1367   -#endif
1368 1373 target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
1369 1374 sigprocmask(SIG_SETMASK, &host_set, NULL);
1370 1375  
1371 1376 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1372 1377 goto badframe;
1373 1378  
1374   - if (do_sigaltstack(h2g(&frame->uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
  1379 + if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1375 1380 goto badframe;
1376 1381  
1377 1382 #if 0
... ... @@ -1379,9 +1384,11 @@ long do_rt_sigreturn(CPUState *env)
1379 1384 if (ptrace_cancel_bpt(current))
1380 1385 send_sig(SIGTRAP, current, 1);
1381 1386 #endif
  1387 + unlock_user_struct(frame, frame_addr, 0);
1382 1388 return env->regs[0];
1383 1389  
1384 1390 badframe:
  1391 + unlock_user_struct(frame, frame_addr, 0);
1385 1392 force_sig(SIGSEGV /* , current */);
1386 1393 return 0;
1387 1394 }
... ... @@ -1452,7 +1459,7 @@ typedef struct {
1452 1459 struct target_signal_frame {
1453 1460 struct sparc_stackf ss;
1454 1461 __siginfo_t info;
1455   - qemu_siginfo_fpu_t *fpu_save;
  1462 + abi_ulong fpu_save;
1456 1463 abi_ulong insns[2] __attribute__ ((aligned (8)));
1457 1464 abi_ulong extramask[TARGET_NSIG_WORDS - 1];
1458 1465 abi_ulong extra_size; /* Should be 0 */
... ... @@ -1463,7 +1470,7 @@ struct target_rt_signal_frame {
1463 1470 siginfo_t info;
1464 1471 abi_ulong regs[20];
1465 1472 sigset_t mask;
1466   - qemu_siginfo_fpu_t *fpu_save;
  1473 + abi_ulong fpu_save;
1467 1474 unsigned int insns[2];
1468 1475 stack_t stack;
1469 1476 unsigned int extra_size; /* Should be 0 */
... ... @@ -1677,14 +1684,17 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
1677 1684  
1678 1685 long do_sigreturn(CPUState *env)
1679 1686 {
  1687 + abi_ulong sf_addr;
1680 1688 struct target_signal_frame *sf;
1681 1689 uint32_t up_psr, pc, npc;
1682 1690 target_sigset_t set;
1683 1691 sigset_t host_set;
1684   - abi_ulong fpu_save;
  1692 + abi_ulong fpu_save_addr;
1685 1693 int err, i;
1686 1694  
1687   - sf = (struct target_signal_frame *)g2h(env->regwptr[UREG_FP]);
  1695 + sf_addr = env->regwptr[UREG_FP];
  1696 + if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
  1697 + goto segv_and_exit;
1688 1698 #if 0
1689 1699 fprintf(stderr, "sigreturn\n");
1690 1700 fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
... ... @@ -1692,12 +1702,8 @@ long do_sigreturn(CPUState *env)
1692 1702 //cpu_dump_state(env, stderr, fprintf, 0);
1693 1703  
1694 1704 /* 1. Make sure we are not getting garbage from the user */
1695   -#if 0
1696   - if (verify_area (VERIFY_READ, sf, sizeof (*sf)))
1697   - goto segv_and_exit;
1698   -#endif
1699 1705  
1700   - if (((uint) sf) & 3)
  1706 + if (sf_addr & 3)
1701 1707 goto segv_and_exit;
1702 1708  
1703 1709 err = __get_user(pc, &sf->info.si_regs.pc);
... ... @@ -1723,7 +1729,7 @@ long do_sigreturn(CPUState *env)
1723 1729 err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
1724 1730 }
1725 1731  
1726   - err |= __get_user(fpu_save, (abi_ulong *)&sf->fpu_save);
  1732 + err |= __get_user(fpu_save_addr, &sf->fpu_save);
1727 1733  
1728 1734 //if (fpu_save)
1729 1735 // err |= restore_fpu_state(env, fpu_save);
... ... @@ -1741,17 +1747,18 @@ long do_sigreturn(CPUState *env)
1741 1747  
1742 1748 if (err)
1743 1749 goto segv_and_exit;
1744   -
  1750 + unlock_user_struct(sf, sf_addr, 0);
1745 1751 return env->regwptr[0];
1746 1752  
1747 1753 segv_and_exit:
  1754 + unlock_user_struct(sf, sf_addr, 0);
1748 1755 force_sig(TARGET_SIGSEGV);
1749 1756 }
1750 1757  
1751 1758 long do_rt_sigreturn(CPUState *env)
1752 1759 {
1753 1760 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
1754   - return -ENOSYS;
  1761 + return -TARGET_ENOSYS;
1755 1762 }
1756 1763  
1757 1764 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
... ... @@ -2032,13 +2039,13 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
2032 2039 long do_sigreturn(CPUState *env)
2033 2040 {
2034 2041 fprintf(stderr, "do_sigreturn: not implemented\n");
2035   - return -ENOSYS;
  2042 + return -TARGET_ENOSYS;
2036 2043 }
2037 2044  
2038 2045 long do_rt_sigreturn(CPUState *env)
2039 2046 {
2040 2047 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2041   - return -ENOSYS;
  2048 + return -TARGET_ENOSYS;
2042 2049 }
2043 2050  
2044 2051 #elif defined(TARGET_ABI_MIPSN32)
... ... @@ -2061,13 +2068,13 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
2061 2068 long do_sigreturn(CPUState *env)
2062 2069 {
2063 2070 fprintf(stderr, "do_sigreturn: not implemented\n");
2064   - return -ENOSYS;
  2071 + return -TARGET_ENOSYS;
2065 2072 }
2066 2073  
2067 2074 long do_rt_sigreturn(CPUState *env)
2068 2075 {
2069 2076 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2070   - return -ENOSYS;
  2077 + return -TARGET_ENOSYS;
2071 2078 }
2072 2079  
2073 2080 #elif defined(TARGET_ABI_MIPSO32)
... ... @@ -2321,9 +2328,9 @@ static void setup_frame(int sig, struct emulated_sigaction * ka,
2321 2328 */
2322 2329 regs->gpr[ 4][regs->current_tc] = sig;
2323 2330 regs->gpr[ 5][regs->current_tc] = 0;
2324   - regs->gpr[ 6][regs->current_tc] = h2g(&frame->sf_sc);
2325   - regs->gpr[29][regs->current_tc] = h2g(frame);
2326   - regs->gpr[31][regs->current_tc] = h2g(frame->sf_code);
  2331 + regs->gpr[ 6][regs->current_tc] = frame_addr + offsetof(struct sigframe, sf_sc);
  2332 + regs->gpr[29][regs->current_tc] = frame_addr;
  2333 + regs->gpr[31][regs->current_tc] = frame_addr + offsetof(struct sigframe, sf_code);
2327 2334 /* The original kernel code sets CP0_EPC to the handler
2328 2335 * since it returns to userland using eret
2329 2336 * we cannot do this here, and we must set PC directly */
... ... @@ -2396,7 +2403,7 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
2396 2403 long do_rt_sigreturn(CPUState *env)
2397 2404 {
2398 2405 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2399   - return -ENOSYS;
  2406 + return -TARGET_ENOSYS;
2400 2407 }
2401 2408  
2402 2409 #else
... ... @@ -2417,13 +2424,13 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
2417 2424 long do_sigreturn(CPUState *env)
2418 2425 {
2419 2426 fprintf(stderr, "do_sigreturn: not implemented\n");
2420   - return -ENOSYS;
  2427 + return -TARGET_ENOSYS;
2421 2428 }
2422 2429  
2423 2430 long do_rt_sigreturn(CPUState *env)
2424 2431 {
2425 2432 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2426   - return -ENOSYS;
  2433 + return -TARGET_ENOSYS;
2427 2434 }
2428 2435  
2429 2436 #endif
... ...