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