Commit f8b0aa25599782eef91edc00ebf620bd14db720c
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 | ... | ... |