Revision 579a97f7 linux-user/syscall.c
b/linux-user/syscall.c | ||
---|---|---|
504 | 504 |
#endif |
505 | 505 |
} |
506 | 506 |
|
507 |
static inline void host_to_target_rusage(abi_ulong target_addr,
|
|
508 |
const struct rusage *rusage) |
|
507 |
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
|
|
508 |
const struct rusage *rusage)
|
|
509 | 509 |
{ |
510 | 510 |
struct target_rusage *target_rusage; |
511 | 511 |
|
512 |
lock_user_struct(target_rusage, target_addr, 0); |
|
512 |
if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0)) |
|
513 |
return -TARGET_EFAULT; |
|
513 | 514 |
target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec); |
514 | 515 |
target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec); |
515 | 516 |
target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec); |
... | ... | |
529 | 530 |
target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw); |
530 | 531 |
target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw); |
531 | 532 |
unlock_user_struct(target_rusage, target_addr, 1); |
533 |
|
|
534 |
return 0; |
|
532 | 535 |
} |
533 | 536 |
|
534 |
static inline void target_to_host_timeval(struct timeval *tv,
|
|
535 |
abi_ulong target_addr) |
|
537 |
static inline abi_long target_to_host_timeval(struct timeval *tv,
|
|
538 |
abi_ulong target_addr)
|
|
536 | 539 |
{ |
537 | 540 |
struct target_timeval *target_tv; |
538 | 541 |
|
539 |
lock_user_struct(target_tv, target_addr, 1); |
|
542 |
if (!lock_user_struct(VERIFY_READ, target_tv, target_addr, 1)) |
|
543 |
return -TARGET_EFAULT; |
|
540 | 544 |
tv->tv_sec = tswapl(target_tv->tv_sec); |
541 | 545 |
tv->tv_usec = tswapl(target_tv->tv_usec); |
542 | 546 |
unlock_user_struct(target_tv, target_addr, 0); |
547 |
|
|
548 |
return 0; |
|
543 | 549 |
} |
544 | 550 |
|
545 |
static inline void host_to_target_timeval(abi_ulong target_addr,
|
|
546 |
const struct timeval *tv) |
|
551 |
static inline abi_long host_to_target_timeval(abi_ulong target_addr,
|
|
552 |
const struct timeval *tv)
|
|
547 | 553 |
{ |
548 | 554 |
struct target_timeval *target_tv; |
549 | 555 |
|
550 |
lock_user_struct(target_tv, target_addr, 0); |
|
556 |
if (!lock_user_struct(VERIFY_WRITE, target_tv, target_addr, 0)) |
|
557 |
return -TARGET_EFAULT; |
|
551 | 558 |
target_tv->tv_sec = tswapl(tv->tv_sec); |
552 | 559 |
target_tv->tv_usec = tswapl(tv->tv_usec); |
553 | 560 |
unlock_user_struct(target_tv, target_addr, 1); |
561 |
|
|
562 |
return 0; |
|
554 | 563 |
} |
555 | 564 |
|
556 | 565 |
|
... | ... | |
567 | 576 |
int ok; |
568 | 577 |
|
569 | 578 |
if (rfd_p) { |
570 |
target_rfds = lock_user(rfd_p, sizeof(abi_long) * n, 1); |
|
579 |
target_rfds = lock_user(VERIFY_WRITE, rfd_p, sizeof(abi_long) * n, 1); |
|
580 |
if (!target_rfds) { |
|
581 |
ret = -TARGET_EFAULT; |
|
582 |
goto end; |
|
583 |
} |
|
571 | 584 |
rfds_ptr = target_to_host_fds(&rfds, target_rfds, n); |
572 | 585 |
} else { |
573 | 586 |
target_rfds = NULL; |
574 | 587 |
rfds_ptr = NULL; |
575 | 588 |
} |
576 | 589 |
if (wfd_p) { |
577 |
target_wfds = lock_user(wfd_p, sizeof(abi_long) * n, 1); |
|
590 |
target_wfds = lock_user(VERIFY_WRITE, wfd_p, sizeof(abi_long) * n, 1); |
|
591 |
if (!target_wfds) { |
|
592 |
ret = -TARGET_EFAULT; |
|
593 |
goto end; |
|
594 |
} |
|
578 | 595 |
wfds_ptr = target_to_host_fds(&wfds, target_wfds, n); |
579 | 596 |
} else { |
580 | 597 |
target_wfds = NULL; |
581 | 598 |
wfds_ptr = NULL; |
582 | 599 |
} |
583 | 600 |
if (efd_p) { |
584 |
target_efds = lock_user(efd_p, sizeof(abi_long) * n, 1); |
|
601 |
target_efds = lock_user(VERIFY_WRITE, efd_p, sizeof(abi_long) * n, 1); |
|
602 |
if (!target_efds) { |
|
603 |
ret = -TARGET_EFAULT; |
|
604 |
goto end; |
|
605 |
} |
|
585 | 606 |
efds_ptr = target_to_host_fds(&efds, target_efds, n); |
586 | 607 |
} else { |
587 | 608 |
target_efds = NULL; |
... | ... | |
606 | 627 |
host_to_target_timeval(target_tv, &tv); |
607 | 628 |
} |
608 | 629 |
} |
609 |
if (target_rfds) |
|
610 |
unlock_user(target_rfds, rfd_p, ok ? sizeof(abi_long) * n : 0); |
|
611 |
if (target_wfds) |
|
612 |
unlock_user(target_wfds, wfd_p, ok ? sizeof(abi_long) * n : 0); |
|
613 |
if (target_efds) |
|
614 |
unlock_user(target_efds, efd_p, ok ? sizeof(abi_long) * n : 0); |
|
630 |
|
|
631 |
end: |
|
632 |
unlock_user(target_rfds, rfd_p, ok ? sizeof(abi_long) * n : 0); |
|
633 |
unlock_user(target_wfds, wfd_p, ok ? sizeof(abi_long) * n : 0); |
|
634 |
unlock_user(target_efds, efd_p, ok ? sizeof(abi_long) * n : 0); |
|
615 | 635 |
|
616 | 636 |
return ret; |
617 | 637 |
} |
618 | 638 |
|
619 |
static inline void target_to_host_sockaddr(struct sockaddr *addr,
|
|
620 |
abi_ulong target_addr, |
|
621 |
socklen_t len) |
|
639 |
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
|
|
640 |
abi_ulong target_addr,
|
|
641 |
socklen_t len)
|
|
622 | 642 |
{ |
623 | 643 |
struct target_sockaddr *target_saddr; |
624 | 644 |
|
625 |
target_saddr = lock_user(target_addr, len, 1); |
|
645 |
target_saddr = lock_user(VERIFY_READ, target_addr, len, 1); |
|
646 |
if (!target_saddr) |
|
647 |
return -TARGET_EFAULT; |
|
626 | 648 |
memcpy(addr, target_saddr, len); |
627 | 649 |
addr->sa_family = tswap16(target_saddr->sa_family); |
628 | 650 |
unlock_user(target_saddr, target_addr, 0); |
651 |
|
|
652 |
return 0; |
|
629 | 653 |
} |
630 | 654 |
|
631 |
static inline void host_to_target_sockaddr(abi_ulong target_addr,
|
|
632 |
struct sockaddr *addr, |
|
633 |
socklen_t len) |
|
655 |
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
|
|
656 |
struct sockaddr *addr,
|
|
657 |
socklen_t len)
|
|
634 | 658 |
{ |
635 | 659 |
struct target_sockaddr *target_saddr; |
636 | 660 |
|
637 |
target_saddr = lock_user(target_addr, len, 0); |
|
661 |
target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0); |
|
662 |
if (!target_saddr) |
|
663 |
return -TARGET_EFAULT; |
|
638 | 664 |
memcpy(target_saddr, addr, len); |
639 | 665 |
target_saddr->sa_family = tswap16(addr->sa_family); |
640 | 666 |
unlock_user(target_saddr, target_addr, len); |
667 |
|
|
668 |
return 0; |
|
641 | 669 |
} |
642 | 670 |
|
643 | 671 |
/* ??? Should this also swap msgh->name? */ |
... | ... | |
941 | 969 |
return ret; |
942 | 970 |
} |
943 | 971 |
|
944 |
static void lock_iovec(struct iovec *vec, abi_ulong target_addr, |
|
945 |
int count, int copy) |
|
972 |
/* FIXME |
|
973 |
* lock_iovec()/unlock_iovec() have a return code of 0 for success where |
|
974 |
* other lock functions have a return code of 0 for failure. |
|
975 |
*/ |
|
976 |
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr, |
|
977 |
int count, int copy) |
|
946 | 978 |
{ |
947 | 979 |
struct target_iovec *target_vec; |
948 | 980 |
abi_ulong base; |
949 |
int i; |
|
981 |
int i, j;
|
|
950 | 982 |
|
951 |
target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1); |
|
983 |
target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1); |
|
984 |
if (!target_vec) |
|
985 |
return -TARGET_EFAULT; |
|
952 | 986 |
for(i = 0;i < count; i++) { |
953 | 987 |
base = tswapl(target_vec[i].iov_base); |
954 | 988 |
vec[i].iov_len = tswapl(target_vec[i].iov_len); |
955 |
vec[i].iov_base = lock_user(base, vec[i].iov_len, copy); |
|
989 |
vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy); |
|
990 |
if (!vec[i].iov_base) |
|
991 |
goto fail; |
|
992 |
} |
|
993 |
unlock_user (target_vec, target_addr, 0); |
|
994 |
return 0; |
|
995 |
fail: |
|
996 |
/* failure - unwind locks */ |
|
997 |
for (j = 0; j < i; j++) { |
|
998 |
base = tswapl(target_vec[j].iov_base); |
|
999 |
unlock_user(vec[j].iov_base, base, 0); |
|
956 | 1000 |
} |
957 | 1001 |
unlock_user (target_vec, target_addr, 0); |
1002 |
return -TARGET_EFAULT; |
|
958 | 1003 |
} |
959 | 1004 |
|
960 |
static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
|
|
961 |
int count, int copy) |
|
1005 |
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
|
|
1006 |
int count, int copy)
|
|
962 | 1007 |
{ |
963 | 1008 |
struct target_iovec *target_vec; |
964 | 1009 |
abi_ulong base; |
965 | 1010 |
int i; |
966 | 1011 |
|
967 |
target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1); |
|
1012 |
target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1); |
|
1013 |
if (!target_vec) |
|
1014 |
return -TARGET_EFAULT; |
|
968 | 1015 |
for(i = 0;i < count; i++) { |
969 | 1016 |
base = tswapl(target_vec[i].iov_base); |
970 | 1017 |
unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0); |
971 | 1018 |
} |
972 | 1019 |
unlock_user (target_vec, target_addr, 0); |
1020 |
|
|
1021 |
return 0; |
|
973 | 1022 |
} |
974 | 1023 |
|
975 | 1024 |
/* do_socket() Must return target values and target errnos. */ |
... | ... | |
1033 | 1082 |
struct iovec *vec; |
1034 | 1083 |
abi_ulong target_vec; |
1035 | 1084 |
|
1036 |
lock_user_struct(msgp, target_msg, 1); |
|
1085 |
/* FIXME */ |
|
1086 |
if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE, |
|
1087 |
msgp, |
|
1088 |
target_msg, |
|
1089 |
send ? 1 : 0)) |
|
1090 |
return -TARGET_EFAULT; |
|
1037 | 1091 |
if (msgp->msg_name) { |
1038 | 1092 |
msg.msg_namelen = tswap32(msgp->msg_namelen); |
1039 | 1093 |
msg.msg_name = alloca(msg.msg_namelen); |
... | ... | |
1050 | 1104 |
count = tswapl(msgp->msg_iovlen); |
1051 | 1105 |
vec = alloca(count * sizeof(struct iovec)); |
1052 | 1106 |
target_vec = tswapl(msgp->msg_iov); |
1053 |
lock_iovec(vec, target_vec, count, send); |
|
1107 |
lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
|
|
1054 | 1108 |
msg.msg_iovlen = count; |
1055 | 1109 |
msg.msg_iov = vec; |
1056 | 1110 |
|
... | ... | |
1063 | 1117 |
host_to_target_cmsg(msgp, &msg); |
1064 | 1118 |
} |
1065 | 1119 |
unlock_iovec(vec, target_vec, count, !send); |
1120 |
unlock_user_struct(msgp, target_msg, send ? 0 : 1); |
|
1066 | 1121 |
return ret; |
1067 | 1122 |
} |
1068 | 1123 |
|
... | ... | |
1137 | 1192 |
void *host_msg; |
1138 | 1193 |
abi_long ret; |
1139 | 1194 |
|
1140 |
host_msg = lock_user(msg, len, 1); |
|
1195 |
host_msg = lock_user(VERIFY_READ, msg, len, 1); |
|
1196 |
if (!host_msg) |
|
1197 |
return -TARGET_EFAULT; |
|
1141 | 1198 |
if (target_addr) { |
1142 | 1199 |
addr = alloca(addrlen); |
1143 | 1200 |
target_to_host_sockaddr(addr, target_addr, addrlen); |
... | ... | |
1159 | 1216 |
void *host_msg; |
1160 | 1217 |
abi_long ret; |
1161 | 1218 |
|
1162 |
host_msg = lock_user(msg, len, 0); |
|
1219 |
host_msg = lock_user(VERIFY_WRITE, msg, len, 0); |
|
1220 |
if (!host_msg) |
|
1221 |
return -TARGET_EFAULT; |
|
1163 | 1222 |
if (target_addr) { |
1164 | 1223 |
addrlen = tget32(target_addrlen); |
1165 | 1224 |
addr = alloca(addrlen); |
... | ... | |
1381 | 1440 |
abi_ulong __unused4; |
1382 | 1441 |
}; |
1383 | 1442 |
|
1384 |
static inline void target_to_host_ipc_perm(struct ipc_perm *host_ip,
|
|
1385 |
abi_ulong target_addr) |
|
1443 |
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
|
|
1444 |
abi_ulong target_addr)
|
|
1386 | 1445 |
{ |
1387 | 1446 |
struct target_ipc_perm *target_ip; |
1388 | 1447 |
struct target_semid_ds *target_sd; |
1389 | 1448 |
|
1390 |
lock_user_struct(target_sd, target_addr, 1); |
|
1449 |
if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) |
|
1450 |
return -TARGET_EFAULT; |
|
1391 | 1451 |
target_ip=&(target_sd->sem_perm); |
1392 | 1452 |
host_ip->__key = tswapl(target_ip->__key); |
1393 | 1453 |
host_ip->uid = tswapl(target_ip->uid); |
... | ... | |
1396 | 1456 |
host_ip->cgid = tswapl(target_ip->cgid); |
1397 | 1457 |
host_ip->mode = tswapl(target_ip->mode); |
1398 | 1458 |
unlock_user_struct(target_sd, target_addr, 0); |
1459 |
return 0; |
|
1399 | 1460 |
} |
1400 | 1461 |
|
1401 |
static inline void host_to_target_ipc_perm(abi_ulong target_addr,
|
|
1402 |
struct ipc_perm *host_ip) |
|
1462 |
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
|
|
1463 |
struct ipc_perm *host_ip)
|
|
1403 | 1464 |
{ |
1404 | 1465 |
struct target_ipc_perm *target_ip; |
1405 | 1466 |
struct target_semid_ds *target_sd; |
1406 | 1467 |
|
1407 |
lock_user_struct(target_sd, target_addr, 0); |
|
1468 |
if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) |
|
1469 |
return -TARGET_EFAULT; |
|
1408 | 1470 |
target_ip = &(target_sd->sem_perm); |
1409 | 1471 |
target_ip->__key = tswapl(host_ip->__key); |
1410 | 1472 |
target_ip->uid = tswapl(host_ip->uid); |
... | ... | |
1413 | 1475 |
target_ip->cgid = tswapl(host_ip->cgid); |
1414 | 1476 |
target_ip->mode = tswapl(host_ip->mode); |
1415 | 1477 |
unlock_user_struct(target_sd, target_addr, 1); |
1478 |
return 0; |
|
1416 | 1479 |
} |
1417 | 1480 |
|
1418 |
static inline void target_to_host_semid_ds(struct semid_ds *host_sd,
|
|
1419 |
abi_ulong target_addr) |
|
1481 |
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
|
|
1482 |
abi_ulong target_addr)
|
|
1420 | 1483 |
{ |
1421 | 1484 |
struct target_semid_ds *target_sd; |
1422 | 1485 |
|
1423 |
lock_user_struct(target_sd, target_addr, 1); |
|
1486 |
if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) |
|
1487 |
return -TARGET_EFAULT; |
|
1424 | 1488 |
target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr); |
1425 | 1489 |
host_sd->sem_nsems = tswapl(target_sd->sem_nsems); |
1426 | 1490 |
host_sd->sem_otime = tswapl(target_sd->sem_otime); |
1427 | 1491 |
host_sd->sem_ctime = tswapl(target_sd->sem_ctime); |
1428 | 1492 |
unlock_user_struct(target_sd, target_addr, 0); |
1493 |
return 0; |
|
1429 | 1494 |
} |
1430 | 1495 |
|
1431 |
static inline void host_to_target_semid_ds(abi_ulong target_addr,
|
|
1432 |
struct semid_ds *host_sd) |
|
1496 |
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
|
|
1497 |
struct semid_ds *host_sd)
|
|
1433 | 1498 |
{ |
1434 | 1499 |
struct target_semid_ds *target_sd; |
1435 | 1500 |
|
1436 |
lock_user_struct(target_sd, target_addr, 0); |
|
1501 |
if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) |
|
1502 |
return -TARGET_EFAULT; |
|
1437 | 1503 |
host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)); |
1438 | 1504 |
target_sd->sem_nsems = tswapl(host_sd->sem_nsems); |
1439 | 1505 |
target_sd->sem_otime = tswapl(host_sd->sem_otime); |
1440 | 1506 |
target_sd->sem_ctime = tswapl(host_sd->sem_ctime); |
1441 | 1507 |
unlock_user_struct(target_sd, target_addr, 1); |
1508 |
return 0; |
|
1442 | 1509 |
} |
1443 | 1510 |
|
1444 | 1511 |
union semun { |
... | ... | |
1453 | 1520 |
unsigned short int *array; |
1454 | 1521 |
}; |
1455 | 1522 |
|
1456 |
static inline void target_to_host_semun(int cmd,
|
|
1457 |
union semun *host_su, |
|
1458 |
abi_ulong target_addr, |
|
1459 |
struct semid_ds *ds) |
|
1523 |
static inline abi_long target_to_host_semun(int cmd,
|
|
1524 |
union semun *host_su,
|
|
1525 |
abi_ulong target_addr,
|
|
1526 |
struct semid_ds *ds)
|
|
1460 | 1527 |
{ |
1461 | 1528 |
union target_semun *target_su; |
1462 | 1529 |
|
1463 | 1530 |
switch( cmd ) { |
1464 | 1531 |
case IPC_STAT: |
1465 | 1532 |
case IPC_SET: |
1466 |
lock_user_struct(target_su, target_addr, 1); |
|
1533 |
if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1)) |
|
1534 |
return -TARGET_EFAULT; |
|
1467 | 1535 |
target_to_host_semid_ds(ds,target_su->buf); |
1468 | 1536 |
host_su->buf = ds; |
1469 | 1537 |
unlock_user_struct(target_su, target_addr, 0); |
1470 | 1538 |
break; |
1471 | 1539 |
case GETVAL: |
1472 | 1540 |
case SETVAL: |
1473 |
lock_user_struct(target_su, target_addr, 1); |
|
1541 |
if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1)) |
|
1542 |
return -TARGET_EFAULT; |
|
1474 | 1543 |
host_su->val = tswapl(target_su->val); |
1475 | 1544 |
unlock_user_struct(target_su, target_addr, 0); |
1476 | 1545 |
break; |
1477 | 1546 |
case GETALL: |
1478 | 1547 |
case SETALL: |
1479 |
lock_user_struct(target_su, target_addr, 1); |
|
1548 |
if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1)) |
|
1549 |
return -TARGET_EFAULT; |
|
1480 | 1550 |
*host_su->array = tswap16(*target_su->array); |
1481 | 1551 |
unlock_user_struct(target_su, target_addr, 0); |
1482 | 1552 |
break; |
1483 | 1553 |
default: |
1484 | 1554 |
gemu_log("semun operation not fully supported: %d\n", (int)cmd); |
1485 | 1555 |
} |
1556 |
return 0; |
|
1486 | 1557 |
} |
1487 | 1558 |
|
1488 |
static inline void host_to_target_semun(int cmd,
|
|
1489 |
abi_ulong target_addr, |
|
1490 |
union semun *host_su, |
|
1491 |
struct semid_ds *ds) |
|
1559 |
static inline abi_long host_to_target_semun(int cmd,
|
|
1560 |
abi_ulong target_addr,
|
|
1561 |
union semun *host_su,
|
|
1562 |
struct semid_ds *ds)
|
|
1492 | 1563 |
{ |
1493 | 1564 |
union target_semun *target_su; |
1494 | 1565 |
|
1495 | 1566 |
switch( cmd ) { |
1496 | 1567 |
case IPC_STAT: |
1497 | 1568 |
case IPC_SET: |
1498 |
lock_user_struct(target_su, target_addr, 0); |
|
1569 |
if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0)) |
|
1570 |
return -TARGET_EFAULT; |
|
1499 | 1571 |
host_to_target_semid_ds(target_su->buf,ds); |
1500 | 1572 |
unlock_user_struct(target_su, target_addr, 1); |
1501 | 1573 |
break; |
1502 | 1574 |
case GETVAL: |
1503 | 1575 |
case SETVAL: |
1504 |
lock_user_struct(target_su, target_addr, 0); |
|
1576 |
if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0)) |
|
1577 |
return -TARGET_EFAULT; |
|
1505 | 1578 |
target_su->val = tswapl(host_su->val); |
1506 | 1579 |
unlock_user_struct(target_su, target_addr, 1); |
1507 | 1580 |
break; |
1508 | 1581 |
case GETALL: |
1509 | 1582 |
case SETALL: |
1510 |
lock_user_struct(target_su, target_addr, 0); |
|
1583 |
if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0)) |
|
1584 |
return -TARGET_EFAULT; |
|
1511 | 1585 |
*target_su->array = tswap16(*host_su->array); |
1512 | 1586 |
unlock_user_struct(target_su, target_addr, 1); |
1513 | 1587 |
break; |
1514 | 1588 |
default: |
1515 | 1589 |
gemu_log("semun operation not fully supported: %d\n", (int)cmd); |
1516 | 1590 |
} |
1591 |
return 0; |
|
1517 | 1592 |
} |
1518 | 1593 |
|
1519 | 1594 |
static inline abi_long do_semctl(int first, int second, int third, |
... | ... | |
1580 | 1655 |
abi_ulong __unused5; |
1581 | 1656 |
}; |
1582 | 1657 |
|
1583 |
static inline void target_to_host_msqid_ds(struct msqid_ds *host_md,
|
|
1584 |
abi_ulong target_addr) |
|
1658 |
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
|
|
1659 |
abi_ulong target_addr)
|
|
1585 | 1660 |
{ |
1586 | 1661 |
struct target_msqid_ds *target_md; |
1587 | 1662 |
|
1588 |
lock_user_struct(target_md, target_addr, 1); |
|
1663 |
if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1)) |
|
1664 |
return -TARGET_EFAULT; |
|
1589 | 1665 |
target_to_host_ipc_perm(&(host_md->msg_perm),target_addr); |
1590 | 1666 |
host_md->msg_stime = tswapl(target_md->msg_stime); |
1591 | 1667 |
host_md->msg_rtime = tswapl(target_md->msg_rtime); |
... | ... | |
1596 | 1672 |
host_md->msg_lspid = tswapl(target_md->msg_lspid); |
1597 | 1673 |
host_md->msg_lrpid = tswapl(target_md->msg_lrpid); |
1598 | 1674 |
unlock_user_struct(target_md, target_addr, 0); |
1675 |
return 0; |
|
1599 | 1676 |
} |
1600 | 1677 |
|
1601 |
static inline void host_to_target_msqid_ds(abi_ulong target_addr,
|
|
1602 |
struct msqid_ds *host_md) |
|
1678 |
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
|
|
1679 |
struct msqid_ds *host_md)
|
|
1603 | 1680 |
{ |
1604 | 1681 |
struct target_msqid_ds *target_md; |
1605 | 1682 |
|
1606 |
lock_user_struct(target_md, target_addr, 0); |
|
1683 |
if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0)) |
|
1684 |
return -TARGET_EFAULT; |
|
1607 | 1685 |
host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)); |
1608 | 1686 |
target_md->msg_stime = tswapl(host_md->msg_stime); |
1609 | 1687 |
target_md->msg_rtime = tswapl(host_md->msg_rtime); |
... | ... | |
1614 | 1692 |
target_md->msg_lspid = tswapl(host_md->msg_lspid); |
1615 | 1693 |
target_md->msg_lrpid = tswapl(host_md->msg_lrpid); |
1616 | 1694 |
unlock_user_struct(target_md, target_addr, 1); |
1695 |
return 0; |
|
1617 | 1696 |
} |
1618 | 1697 |
|
1619 | 1698 |
static inline abi_long do_msgctl(int first, int second, abi_long ptr) |
... | ... | |
1645 | 1724 |
struct msgbuf *host_mb; |
1646 | 1725 |
abi_long ret = 0; |
1647 | 1726 |
|
1648 |
lock_user_struct(target_mb,msgp,0); |
|
1727 |
if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0)) |
|
1728 |
return -TARGET_EFAULT; |
|
1649 | 1729 |
host_mb = malloc(msgsz+sizeof(long)); |
1650 | 1730 |
host_mb->mtype = tswapl(target_mb->mtype); |
1651 | 1731 |
memcpy(host_mb->mtext,target_mb->mtext,msgsz); |
... | ... | |
1661 | 1741 |
int msgflg) |
1662 | 1742 |
{ |
1663 | 1743 |
struct target_msgbuf *target_mb; |
1744 |
char *target_mtext; |
|
1664 | 1745 |
struct msgbuf *host_mb; |
1665 | 1746 |
abi_long ret = 0; |
1666 | 1747 |
|
1667 |
lock_user_struct(target_mb, msgp, 0); |
|
1748 |
if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0)) |
|
1749 |
return -TARGET_EFAULT; |
|
1668 | 1750 |
host_mb = malloc(msgsz+sizeof(long)); |
1669 | 1751 |
ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg)); |
1670 |
if (ret > 0) |
|
1752 |
if (ret > 0) { |
|
1753 |
abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong); |
|
1754 |
target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0); |
|
1755 |
if (!target_mtext) { |
|
1756 |
ret = -TARGET_EFAULT; |
|
1757 |
goto end; |
|
1758 |
} |
|
1671 | 1759 |
memcpy(target_mb->mtext, host_mb->mtext, ret); |
1760 |
unlock_user(target_mtext, target_mtext_addr, ret); |
|
1761 |
} |
|
1672 | 1762 |
target_mb->mtype = tswapl(host_mb->mtype); |
1673 | 1763 |
free(host_mb); |
1674 |
unlock_user_struct(target_mb, msgp, 0); |
|
1675 | 1764 |
|
1765 |
end: |
|
1766 |
if (target_mb) |
|
1767 |
unlock_user_struct(target_mb, msgp, 1); |
|
1676 | 1768 |
return ret; |
1677 | 1769 |
} |
1678 | 1770 |
|
... | ... | |
1693 | 1785 |
|
1694 | 1786 |
switch (call) { |
1695 | 1787 |
case IPCOP_semop: |
1696 |
ret = get_errno(semop(first,(struct sembuf *) ptr, second));
|
|
1788 |
ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
|
|
1697 | 1789 |
break; |
1698 | 1790 |
|
1699 | 1791 |
case IPCOP_semget: |
... | ... | |
1723 | 1815 |
|
1724 | 1816 |
case IPCOP_msgrcv: |
1725 | 1817 |
{ |
1818 |
/* XXX: this code is not correct */ |
|
1726 | 1819 |
struct ipc_kludge |
1727 | 1820 |
{ |
1728 | 1821 |
void *__unbounded msgp; |
1729 | 1822 |
long int msgtyp; |
1730 | 1823 |
}; |
1731 | 1824 |
|
1732 |
struct ipc_kludge *foo = (struct ipc_kludge *) ptr;
|
|
1825 |
struct ipc_kludge *foo = (struct ipc_kludge *)g2h(ptr);
|
|
1733 | 1826 |
struct msgbuf *msgp = (struct msgbuf *) foo->msgp; |
1734 | 1827 |
|
1735 | 1828 |
ret = do_msgrcv(first, (long)msgp, second, 0, third); |
... | ... | |
1761 | 1854 |
break; |
1762 | 1855 |
} |
1763 | 1856 |
} |
1764 |
if (put_user(raddr, (abi_ulong *)third))
|
|
1857 |
if (put_user(raddr, third, abi_ulong))
|
|
1765 | 1858 |
return -TARGET_EFAULT; |
1766 | 1859 |
ret = 0; |
1767 | 1860 |
break; |
... | ... | |
1883 | 1976 |
case IOC_R: |
1884 | 1977 |
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); |
1885 | 1978 |
if (!is_error(ret)) { |
1886 |
argptr = lock_user(arg, target_size, 0); |
|
1979 |
argptr = lock_user(VERIFY_WRITE, arg, target_size, 0); |
|
1980 |
if (!argptr) |
|
1981 |
return -TARGET_EFAULT; |
|
1887 | 1982 |
thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET); |
1888 | 1983 |
unlock_user(argptr, arg, target_size); |
1889 | 1984 |
} |
1890 | 1985 |
break; |
1891 | 1986 |
case IOC_W: |
1892 |
argptr = lock_user(arg, target_size, 1); |
|
1987 |
argptr = lock_user(VERIFY_READ, arg, target_size, 1); |
|
1988 |
if (!argptr) |
|
1989 |
return -TARGET_EFAULT; |
|
1893 | 1990 |
thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); |
1894 | 1991 |
unlock_user(argptr, arg, 0); |
1895 | 1992 |
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); |
1896 | 1993 |
break; |
1897 | 1994 |
default: |
1898 | 1995 |
case IOC_RW: |
1899 |
argptr = lock_user(arg, target_size, 1); |
|
1996 |
argptr = lock_user(VERIFY_READ, arg, target_size, 1); |
|
1997 |
if (!argptr) |
|
1998 |
return -TARGET_EFAULT; |
|
1900 | 1999 |
thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); |
1901 | 2000 |
unlock_user(argptr, arg, 0); |
1902 | 2001 |
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); |
1903 | 2002 |
if (!is_error(ret)) { |
1904 |
argptr = lock_user(arg, target_size, 0); |
|
2003 |
argptr = lock_user(VERIFY_WRITE, arg, target_size, 0); |
|
2004 |
if (!argptr) |
|
2005 |
return -TARGET_EFAULT; |
|
1905 | 2006 |
thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET); |
1906 | 2007 |
unlock_user(argptr, arg, target_size); |
1907 | 2008 |
} |
... | ... | |
2138 | 2239 |
size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE; |
2139 | 2240 |
if (size > bytecount) |
2140 | 2241 |
size = bytecount; |
2141 |
p = lock_user(ptr, size, 0); |
|
2142 |
/* ??? Shoudl this by byteswapped? */ |
|
2242 |
p = lock_user(VERIFY_WRITE, ptr, size, 0); |
|
2243 |
if (!p) |
|
2244 |
return -EFAULT; |
|
2245 |
/* ??? Should this by byteswapped? */ |
|
2143 | 2246 |
memcpy(p, ldt_table, size); |
2144 | 2247 |
unlock_user(p, ptr, size); |
2145 | 2248 |
return size; |
... | ... | |
2158 | 2261 |
|
2159 | 2262 |
if (bytecount != sizeof(ldt_info)) |
2160 | 2263 |
return -EINVAL; |
2161 |
lock_user_struct(target_ldt_info, ptr, 1); |
|
2264 |
if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1)) |
|
2265 |
return -EFAULT; |
|
2162 | 2266 |
ldt_info.entry_number = tswap32(target_ldt_info->entry_number); |
2163 | 2267 |
ldt_info.base_addr = tswapl(target_ldt_info->base_addr); |
2164 | 2268 |
ldt_info.limit = tswap32(target_ldt_info->limit); |
... | ... | |
2365 | 2469 |
|
2366 | 2470 |
switch(cmd) { |
2367 | 2471 |
case TARGET_F_GETLK: |
2368 |
lock_user_struct(target_fl, arg, 1); |
|
2472 |
if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1)) |
|
2473 |
return -TARGET_EFAULT; |
|
2369 | 2474 |
fl.l_type = tswap16(target_fl->l_type); |
2370 | 2475 |
fl.l_whence = tswap16(target_fl->l_whence); |
2371 | 2476 |
fl.l_start = tswapl(target_fl->l_start); |
... | ... | |
2374 | 2479 |
unlock_user_struct(target_fl, arg, 0); |
2375 | 2480 |
ret = fcntl(fd, cmd, &fl); |
2376 | 2481 |
if (ret == 0) { |
2377 |
lock_user_struct(target_fl, arg, 0); |
|
2482 |
if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0)) |
|
2483 |
return -TARGET_EFAULT; |
|
2378 | 2484 |
target_fl->l_type = tswap16(fl.l_type); |
2379 | 2485 |
target_fl->l_whence = tswap16(fl.l_whence); |
2380 | 2486 |
target_fl->l_start = tswapl(fl.l_start); |
... | ... | |
2386 | 2492 |
|
2387 | 2493 |
case TARGET_F_SETLK: |
2388 | 2494 |
case TARGET_F_SETLKW: |
2389 |
lock_user_struct(target_fl, arg, 1); |
|
2495 |
if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1)) |
|
2496 |
return -TARGET_EFAULT; |
|
2390 | 2497 |
fl.l_type = tswap16(target_fl->l_type); |
2391 | 2498 |
fl.l_whence = tswap16(target_fl->l_whence); |
2392 | 2499 |
fl.l_start = tswapl(target_fl->l_start); |
... | ... | |
2397 | 2504 |
break; |
2398 | 2505 |
|
2399 | 2506 |
case TARGET_F_GETLK64: |
2400 |
lock_user_struct(target_fl64, arg, 1); |
|
2507 |
if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1)) |
|
2508 |
return -TARGET_EFAULT; |
|
2401 | 2509 |
fl64.l_type = tswap16(target_fl64->l_type) >> 1; |
2402 | 2510 |
fl64.l_whence = tswap16(target_fl64->l_whence); |
2403 | 2511 |
fl64.l_start = tswapl(target_fl64->l_start); |
... | ... | |
2406 | 2514 |
unlock_user_struct(target_fl64, arg, 0); |
2407 | 2515 |
ret = fcntl(fd, cmd >> 1, &fl64); |
2408 | 2516 |
if (ret == 0) { |
2409 |
lock_user_struct(target_fl64, arg, 0); |
|
2517 |
if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0)) |
|
2518 |
return -TARGET_EFAULT; |
|
2410 | 2519 |
target_fl64->l_type = tswap16(fl64.l_type) >> 1; |
2411 | 2520 |
target_fl64->l_whence = tswap16(fl64.l_whence); |
2412 | 2521 |
target_fl64->l_start = tswapl(fl64.l_start); |
... | ... | |
2417 | 2526 |
break; |
2418 | 2527 |
case TARGET_F_SETLK64: |
2419 | 2528 |
case TARGET_F_SETLKW64: |
2420 |
lock_user_struct(target_fl64, arg, 1); |
|
2529 |
if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1)) |
|
2530 |
return -TARGET_EFAULT; |
|
2421 | 2531 |
fl64.l_type = tswap16(target_fl64->l_type) >> 1; |
2422 | 2532 |
fl64.l_whence = tswap16(target_fl64->l_whence); |
2423 | 2533 |
fl64.l_start = tswapl(target_fl64->l_start); |
2424 | 2534 |
fl64.l_len = tswapl(target_fl64->l_len); |
2425 | 2535 |
fl64.l_pid = tswap16(target_fl64->l_pid); |
2426 | 2536 |
unlock_user_struct(target_fl64, arg, 0); |
2427 |
ret = fcntl(fd, cmd >> 1, &fl64);
|
|
2537 |
ret = fcntl(fd, cmd >> 1, &fl64);
|
|
2428 | 2538 |
break; |
2429 | 2539 |
|
2430 | 2540 |
case F_GETFL: |
... | ... | |
2577 | 2687 |
} |
2578 | 2688 |
#endif |
2579 | 2689 |
|
2580 |
static inline void target_to_host_timespec(struct timespec *host_ts,
|
|
2581 |
abi_ulong target_addr) |
|
2690 |
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
|
|
2691 |
abi_ulong target_addr)
|
|
2582 | 2692 |
{ |
2583 | 2693 |
struct target_timespec *target_ts; |
2584 | 2694 |
|
2585 |
lock_user_struct(target_ts, target_addr, 1); |
|
2695 |
if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1)) |
|
2696 |
return -TARGET_EFAULT; |
|
2586 | 2697 |
host_ts->tv_sec = tswapl(target_ts->tv_sec); |
2587 | 2698 |
host_ts->tv_nsec = tswapl(target_ts->tv_nsec); |
2588 | 2699 |
unlock_user_struct(target_ts, target_addr, 0); |
2589 | 2700 |
} |
2590 | 2701 |
|
2591 |
static inline void host_to_target_timespec(abi_ulong target_addr,
|
|
2592 |
struct timespec *host_ts) |
|
2702 |
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
|
|
2703 |
struct timespec *host_ts)
|
|
2593 | 2704 |
{ |
2594 | 2705 |
struct target_timespec *target_ts; |
2595 | 2706 |
|
2596 |
lock_user_struct(target_ts, target_addr, 0); |
|
2707 |
if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0)) |
|
2708 |
return -TARGET_EFAULT; |
|
2597 | 2709 |
target_ts->tv_sec = tswapl(host_ts->tv_sec); |
2598 | 2710 |
target_ts->tv_nsec = tswapl(host_ts->tv_nsec); |
2599 | 2711 |
unlock_user_struct(target_ts, target_addr, 1); |
... | ... | |
2629 | 2741 |
break; |
2630 | 2742 |
case TARGET_NR_read: |
2631 | 2743 |
page_unprotect_range(arg2, arg3); |
2632 |
p = lock_user(arg2, arg3, 0); |
|
2744 |
if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) |
|
2745 |
goto efault; |
|
2633 | 2746 |
ret = get_errno(read(arg1, p, arg3)); |
2634 | 2747 |
unlock_user(p, arg2, ret); |
2635 | 2748 |
break; |
2636 | 2749 |
case TARGET_NR_write: |
2637 |
p = lock_user(arg2, arg3, 1); |
|
2750 |
if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) |
|
2751 |
goto efault; |
|
2638 | 2752 |
ret = get_errno(write(arg1, p, arg3)); |
2639 | 2753 |
unlock_user(p, arg2, 0); |
2640 | 2754 |
break; |
2641 | 2755 |
case TARGET_NR_open: |
2642 |
p = lock_user_string(arg1); |
|
2756 |
if (!(p = lock_user_string(arg1))) { |
|
2757 |
return -TARGET_EFAULT; |
|
2758 |
goto fail; |
|
2759 |
} |
|
2643 | 2760 |
ret = get_errno(open(path(p), |
2644 | 2761 |
target_to_host_bitmask(arg2, fcntl_flags_tbl), |
2645 | 2762 |
arg3)); |
... | ... | |
2647 | 2764 |
break; |
2648 | 2765 |
#if defined(TARGET_NR_openat) && defined(__NR_openat) |
2649 | 2766 |
case TARGET_NR_openat: |
2650 |
if (!arg2) { |
|
2651 |
ret = -TARGET_EFAULT; |
|
2652 |
goto fail; |
|
2653 |
} |
|
2654 |
p = lock_user_string(arg2); |
|
2655 |
if (!access_ok(VERIFY_READ, p, 1)) |
|
2656 |
/* Don't "goto fail" so that cleanup can happen. */ |
|
2657 |
ret = -TARGET_EFAULT; |
|
2658 |
else |
|
2659 |
ret = get_errno(sys_openat(arg1, |
|
2660 |
path(p), |
|
2661 |
target_to_host_bitmask(arg3, fcntl_flags_tbl), |
|
2662 |
arg4)); |
|
2663 |
if (p) |
|
2664 |
unlock_user(p, arg2, 0); |
|
2767 |
if (!(p = lock_user_string(arg2))) |
|
2768 |
goto efault; |
|
2769 |
ret = get_errno(sys_openat(arg1, |
|
2770 |
path(p), |
|
2771 |
target_to_host_bitmask(arg3, fcntl_flags_tbl), |
|
2772 |
arg4)); |
|
2773 |
unlock_user(p, arg2, 0); |
|
2665 | 2774 |
break; |
2666 | 2775 |
#endif |
2667 | 2776 |
case TARGET_NR_close: |
... | ... | |
2685 | 2794 |
#endif |
2686 | 2795 |
#ifdef TARGET_NR_creat /* not on alpha */ |
2687 | 2796 |
case TARGET_NR_creat: |
2688 |
p = lock_user_string(arg1); |
|
2797 |
if (!(p = lock_user_string(arg1))) |
|
2798 |
goto efault; |
|
2689 | 2799 |
ret = get_errno(creat(p, arg2)); |
2690 | 2800 |
unlock_user(p, arg1, 0); |
2691 | 2801 |
break; |
... | ... | |
2695 | 2805 |
void * p2; |
2696 | 2806 |
p = lock_user_string(arg1); |
2697 | 2807 |
p2 = lock_user_string(arg2); |
2698 |
ret = get_errno(link(p, p2)); |
|
2808 |
if (!p || !p2) |
|
2809 |
ret = -TARGET_EFAULT; |
|
2810 |
else |
|
2811 |
ret = get_errno(link(p, p2)); |
|
2699 | 2812 |
unlock_user(p2, arg2, 0); |
2700 | 2813 |
unlock_user(p, arg1, 0); |
2701 | 2814 |
} |
2702 | 2815 |
break; |
2703 | 2816 |
#if defined(TARGET_NR_linkat) && defined(__NR_linkat) |
2704 | 2817 |
case TARGET_NR_linkat: |
2705 |
if (!arg2 || !arg4) { |
|
2706 |
ret = -TARGET_EFAULT; |
|
2707 |
goto fail; |
|
2708 |
} |
|
2709 | 2818 |
{ |
2710 | 2819 |
void * p2 = NULL; |
2820 |
if (!arg2 || !arg4) |
|
2821 |
goto efault; |
|
2711 | 2822 |
p = lock_user_string(arg2); |
2712 | 2823 |
p2 = lock_user_string(arg4); |
2713 |
if (!access_ok(VERIFY_READ, p, 1) |
|
2714 |
|| !access_ok(VERIFY_READ, p2, 1)) |
|
2715 |
/* Don't "goto fail" so that cleanup can happen. */ |
|
2824 |
if (!p || !p2) |
|
2716 | 2825 |
ret = -TARGET_EFAULT; |
2717 | 2826 |
else |
2718 | 2827 |
ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5)); |
2719 |
if (p2) |
|
2720 |
unlock_user(p, arg2, 0); |
|
2721 |
if (p) |
|
2722 |
unlock_user(p2, arg4, 0); |
|
2828 |
unlock_user(p, arg2, 0); |
|
2829 |
unlock_user(p2, arg4, 0); |
|
2723 | 2830 |
} |
2724 | 2831 |
break; |
2725 | 2832 |
#endif |
2726 | 2833 |
case TARGET_NR_unlink: |
2727 |
p = lock_user_string(arg1); |
|
2834 |
if (!(p = lock_user_string(arg1))) |
|
2835 |
goto efault; |
|
2728 | 2836 |
ret = get_errno(unlink(p)); |
2729 | 2837 |
unlock_user(p, arg1, 0); |
2730 | 2838 |
break; |
2731 | 2839 |
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat) |
2732 | 2840 |
case TARGET_NR_unlinkat: |
2733 |
if (!arg2) { |
|
2734 |
ret = -TARGET_EFAULT; |
|
2735 |
goto fail; |
|
2736 |
} |
|
2737 |
p = lock_user_string(arg2); |
|
2738 |
if (!access_ok(VERIFY_READ, p, 1)) |
|
2739 |
/* Don't "goto fail" so that cleanup can happen. */ |
|
2740 |
ret = -TARGET_EFAULT; |
|
2741 |
else |
|
2742 |
ret = get_errno(sys_unlinkat(arg1, p, arg3)); |
|
2743 |
if (p) |
|
2744 |
unlock_user(p, arg2, 0); |
|
2745 |
break; |
|
2841 |
if (!(p = lock_user_string(arg2))) |
|
2842 |
goto efault; |
|
2843 |
ret = get_errno(sys_unlinkat(arg1, p, arg3)); |
|
2844 |
unlock_user(p, arg2, 0); |
|
2746 | 2845 |
#endif |
2747 | 2846 |
case TARGET_NR_execve: |
2748 | 2847 |
{ |
... | ... | |
2771 | 2870 |
addr = tgetl(gp); |
2772 | 2871 |
if (!addr) |
2773 | 2872 |
break; |
2774 |
*q = lock_user_string(addr); |
|
2873 |
if (!(*q = lock_user_string(addr))) { |
|
2874 |
ret = -TARGET_EFAULT; |
|
2875 |
goto execve_fail; |
|
2876 |
} |
|
2775 | 2877 |
} |
2776 | 2878 |
*q = NULL; |
2777 | 2879 |
|
... | ... | |
2780 | 2882 |
addr = tgetl(gp); |
2781 | 2883 |
if (!addr) |
2782 | 2884 |
break; |
2783 |
*q = lock_user_string(addr); |
|
2885 |
if (!(*q = lock_user_string(addr))) { |
|
2886 |
ret = -TARGET_EFAULT; |
|
2887 |
goto execve_fail; |
|
2888 |
} |
|
2784 | 2889 |
} |
2785 | 2890 |
*q = NULL; |
2786 | 2891 |
|
2787 |
p = lock_user_string(arg1); |
|
2892 |
if (!(p = lock_user_string(arg1))) { |
|
2893 |
ret = -TARGET_EFAULT; |
|
2894 |
goto execve_fail; |
|
2895 |
} |
|
2788 | 2896 |
ret = get_errno(execve(p, argp, envp)); |
2789 | 2897 |
unlock_user(p, arg1, 0); |
2790 | 2898 |
|
2899 |
execve_fail: |
|
2791 | 2900 |
for (gp = guest_argp, q = argp; *q; |
2792 | 2901 |
gp += sizeof(abi_ulong), q++) { |
2793 | 2902 |
addr = tgetl(gp); |
... | ... | |
2801 | 2910 |
} |
2802 | 2911 |
break; |
2803 | 2912 |
case TARGET_NR_chdir: |
2804 |
p = lock_user_string(arg1); |
|
2913 |
if (!(p = lock_user_string(arg1))) |
|
2914 |
goto efault; |
|
2805 | 2915 |
ret = get_errno(chdir(p)); |
2806 | 2916 |
unlock_user(p, arg1, 0); |
2807 | 2917 |
break; |
... | ... | |
2816 | 2926 |
break; |
2817 | 2927 |
#endif |
2818 | 2928 |
case TARGET_NR_mknod: |
2819 |
p = lock_user_string(arg1); |
|
2929 |
if (!(p = lock_user_string(arg1))) |
|
2930 |
goto efault; |
|
2820 | 2931 |
ret = get_errno(mknod(p, arg2, arg3)); |
2821 | 2932 |
unlock_user(p, arg1, 0); |
2822 | 2933 |
break; |
2823 | 2934 |
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat) |
2824 | 2935 |
case TARGET_NR_mknodat: |
2825 |
if (!arg2) { |
|
2826 |
ret = -TARGET_EFAULT; |
|
2827 |
goto fail; |
|
2828 |
} |
|
2829 |
p = lock_user_string(arg2); |
|
2830 |
if (!access_ok(VERIFY_READ, p, 1)) |
|
2831 |
/* Don't "goto fail" so that cleanup can happen. */ |
|
2832 |
ret = -TARGET_EFAULT; |
|
2833 |
else |
|
2834 |
ret = get_errno(sys_mknodat(arg1, p, arg3, arg4)); |
|
2835 |
if (p) |
|
2836 |
unlock_user(p, arg2, 0); |
|
2936 |
if (!(p = lock_user_string(arg2))) |
|
2937 |
goto efault; |
|
2938 |
ret = get_errno(sys_mknodat(arg1, p, arg3, arg4)); |
|
2939 |
unlock_user(p, arg2, 0); |
|
2837 | 2940 |
break; |
2838 | 2941 |
#endif |
2839 | 2942 |
case TARGET_NR_chmod: |
2840 |
p = lock_user_string(arg1); |
|
2943 |
if (!(p = lock_user_string(arg1))) |
|
2944 |
goto efault; |
|
2841 | 2945 |
ret = get_errno(chmod(p, arg2)); |
2842 | 2946 |
unlock_user(p, arg1, 0); |
2843 | 2947 |
break; |
... | ... | |
2866 | 2970 |
p = lock_user_string(arg1); |
2867 | 2971 |
p2 = lock_user_string(arg2); |
2868 | 2972 |
p3 = lock_user_string(arg3); |
2869 |
ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, (const void *)arg5)); |
|
2870 |
unlock_user(p, arg1, 0); |
|
2871 |
unlock_user(p2, arg2, 0); |
|
2872 |
unlock_user(p3, arg3, 0); |
|
2973 |
if (!p || !p2 || !p3) |
|
2974 |
ret = -TARGET_EFAULT; |
|
2975 |
else |
|
2976 |
/* FIXME - arg5 should be locked, but it isn't clear how to |
|
2977 |
* do that since it's not guaranteed to be a NULL-terminated |
|
2978 |
* string. |
|
2979 |
*/ |
|
2980 |
ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5))); |
|
2981 |
unlock_user(p, arg1, 0); |
|
2982 |
unlock_user(p2, arg2, 0); |
|
2983 |
unlock_user(p3, arg3, 0); |
|
2873 | 2984 |
break; |
2874 | 2985 |
} |
2875 | 2986 |
#ifdef TARGET_NR_umount |
2876 | 2987 |
case TARGET_NR_umount: |
2877 |
p = lock_user_string(arg1); |
|
2988 |
if (!(p = lock_user_string(arg1))) |
|
2989 |
goto efault; |
|
2878 | 2990 |
ret = get_errno(umount(p)); |
2879 | 2991 |
unlock_user(p, arg1, 0); |
2880 | 2992 |
break; |
... | ... | |
2910 | 3022 |
struct utimbuf tbuf, *host_tbuf; |
2911 | 3023 |
struct target_utimbuf *target_tbuf; |
2912 | 3024 |
if (arg2) { |
2913 |
lock_user_struct(target_tbuf, arg2, 1); |
|
3025 |
if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1)) |
|
3026 |
goto efault; |
|
2914 | 3027 |
tbuf.actime = tswapl(target_tbuf->actime); |
2915 | 3028 |
tbuf.modtime = tswapl(target_tbuf->modtime); |
2916 | 3029 |
unlock_user_struct(target_tbuf, arg2, 0); |
... | ... | |
2918 | 3031 |
} else { |
2919 | 3032 |
host_tbuf = NULL; |
2920 | 3033 |
} |
2921 |
p = lock_user_string(arg1); |
|
3034 |
if (!(p = lock_user_string(arg1))) |
|
3035 |
goto efault; |
|
2922 | 3036 |
ret = get_errno(utime(p, host_tbuf)); |
2923 | 3037 |
unlock_user(p, arg1, 0); |
2924 | 3038 |
} |
... | ... | |
2935 | 3049 |
} else { |
2936 | 3050 |
tvp = NULL; |
2937 | 3051 |
} |
2938 |
p = lock_user_string(arg1); |
|
3052 |
if (!(p = lock_user_string(arg1))) |
|
3053 |
goto efault; |
|
2939 | 3054 |
ret = get_errno(utimes(p, tvp)); |
2940 | 3055 |
unlock_user(p, arg1, 0); |
2941 | 3056 |
} |
... | ... | |
2949 | 3064 |
goto unimplemented; |
2950 | 3065 |
#endif |
2951 | 3066 |
case TARGET_NR_access: |
2952 |
p = lock_user_string(arg1); |
|
3067 |
if (!(p = lock_user_string(arg1))) |
|
3068 |
goto efault; |
|
2953 | 3069 |
ret = get_errno(access(p, arg2)); |
2954 | 3070 |
unlock_user(p, arg1, 0); |
2955 | 3071 |
break; |
2956 | 3072 |
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat) |
2957 | 3073 |
case TARGET_NR_faccessat: |
2958 |
if (!arg2) { |
|
2959 |
ret = -TARGET_EFAULT; |
|
2960 |
goto fail; |
|
2961 |
} |
|
2962 |
p = lock_user_string(arg2); |
|
2963 |
if (!access_ok(VERIFY_READ, p, 1)) |
|
2964 |
/* Don't "goto fail" so that cleanup can happen. */ |
|
2965 |
ret = -TARGET_EFAULT; |
|
2966 |
else |
|
2967 |
ret = get_errno(sys_faccessat(arg1, p, arg3, arg4)); |
|
2968 |
if (p) |
|
2969 |
unlock_user(p, arg2, 0); |
|
3074 |
if (!(p = lock_user_string(arg2))) |
|
3075 |
goto efault; |
|
3076 |
ret = get_errno(sys_faccessat(arg1, p, arg3, arg4)); |
|
3077 |
unlock_user(p, arg2, 0); |
|
2970 | 3078 |
break; |
2971 | 3079 |
#endif |
2972 | 3080 |
#ifdef TARGET_NR_nice /* not on alpha */ |
... | ... | |
2990 | 3098 |
void *p2; |
2991 | 3099 |
p = lock_user_string(arg1); |
2992 | 3100 |
p2 = lock_user_string(arg2); |
2993 |
ret = get_errno(rename(p, p2)); |
|
3101 |
if (!p || !p2) |
|
3102 |
ret = -TARGET_EFAULT; |
|
3103 |
else |
|
3104 |
ret = get_errno(rename(p, p2)); |
|
2994 | 3105 |
unlock_user(p2, arg2, 0); |
2995 | 3106 |
unlock_user(p, arg1, 0); |
2996 | 3107 |
} |
2997 | 3108 |
break; |
2998 | 3109 |
#if defined(TARGET_NR_renameat) && defined(__NR_renameat) |
2999 | 3110 |
case TARGET_NR_renameat: |
3000 |
if (!arg2 || !arg4) { |
|
3001 |
ret = -TARGET_EFAULT; |
|
3002 |
goto fail; |
|
3003 |
} |
|
3004 | 3111 |
{ |
3005 |
void *p2 = NULL;
|
|
3112 |
void *p2; |
|
3006 | 3113 |
p = lock_user_string(arg2); |
3007 | 3114 |
p2 = lock_user_string(arg4); |
3008 |
if (!access_ok(VERIFY_READ, p, 1) |
|
3009 |
|| !access_ok(VERIFY_READ, p2, 1)) |
|
3010 |
/* Don't "goto fail" so that cleanup can happen. */ |
|
3115 |
if (!p || !p2) |
|
3011 | 3116 |
ret = -TARGET_EFAULT; |
3012 | 3117 |
else |
3013 | 3118 |
ret = get_errno(sys_renameat(arg1, p, arg3, p2)); |
3014 |
if (p2) |
|
3015 |
unlock_user(p2, arg4, 0); |
|
3016 |
if (p) |
|
3017 |
unlock_user(p, arg2, 0); |
|
3119 |
unlock_user(p2, arg4, 0); |
|
3120 |
unlock_user(p, arg2, 0); |
|
3018 | 3121 |
} |
3019 | 3122 |
break; |
3020 | 3123 |
#endif |
3021 | 3124 |
case TARGET_NR_mkdir: |
3022 |
p = lock_user_string(arg1); |
|
3125 |
if (!(p = lock_user_string(arg1))) |
|
3126 |
goto efault; |
|
3023 | 3127 |
ret = get_errno(mkdir(p, arg2)); |
3024 | 3128 |
unlock_user(p, arg1, 0); |
3025 | 3129 |
break; |
3026 | 3130 |
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat) |
3027 | 3131 |
case TARGET_NR_mkdirat: |
3028 |
if (!arg2) { |
|
3029 |
ret = -TARGET_EFAULT; |
|
3030 |
goto fail; |
|
3031 |
} |
|
3032 |
p = lock_user_string(arg2); |
|
3033 |
if (!access_ok(VERIFY_READ, p, 1)) |
|
3034 |
/* Don't "goto fail" so that cleanup can happen. */ |
|
3035 |
ret = -TARGET_EFAULT; |
|
3036 |
else |
|
3037 |
ret = get_errno(sys_mkdirat(arg1, p, arg3)); |
|
3038 |
if (p) |
|
3039 |
unlock_user(p, arg2, 0); |
|
3132 |
if (!(p = lock_user_string(arg2))) |
|
3133 |
goto efault; |
|
3134 |
ret = get_errno(sys_mkdirat(arg1, p, arg3)); |
|
3135 |
unlock_user(p, arg2, 0); |
|
3040 | 3136 |
break; |
3041 | 3137 |
#endif |
3042 | 3138 |
case TARGET_NR_rmdir: |
3043 |
p = lock_user_string(arg1); |
|
3139 |
if (!(p = lock_user_string(arg1))) |
|
3140 |
goto efault; |
|
3044 | 3141 |
ret = get_errno(rmdir(p)); |
3045 | 3142 |
unlock_user(p, arg1, 0); |
3046 | 3143 |
break; |
... | ... | |
3069 | 3166 |
struct tms tms; |
3070 | 3167 |
ret = get_errno(times(&tms)); |
3071 | 3168 |
if (arg1) { |
3072 |
tmsp = lock_user(arg1, sizeof(struct target_tms), 0); |
|
3169 |
tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0); |
|
3170 |
if (!tmsp) |
|
3171 |
goto efault; |
|
3073 | 3172 |
tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime)); |
3074 | 3173 |
tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime)); |
3075 | 3174 |
tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime)); |
... | ... | |
3088 | 3187 |
goto unimplemented; |
3089 | 3188 |
#endif |
3090 | 3189 |
case TARGET_NR_acct: |
3091 |
p = lock_user_string(arg1); |
|
3190 |
if (!(p = lock_user_string(arg1))) |
|
3191 |
goto efault; |
|
3092 | 3192 |
ret = get_errno(acct(path(p))); |
3093 | 3193 |
unlock_user(p, arg1, 0); |
3094 | 3194 |
break; |
3095 | 3195 |
#ifdef TARGET_NR_umount2 /* not on alpha */ |
3096 | 3196 |
case TARGET_NR_umount2: |
3097 |
p = lock_user_string(arg1); |
|
3197 |
if (!(p = lock_user_string(arg1))) |
|
3198 |
goto efault; |
|
3098 | 3199 |
ret = get_errno(umount2(p, arg2)); |
3099 | 3200 |
unlock_user(p, arg1, 0); |
3100 | 3201 |
break; |
... | ... | |
3128 | 3229 |
ret = get_errno(umask(arg1)); |
3129 | 3230 |
break; |
3130 | 3231 |
case TARGET_NR_chroot: |
3131 |
p = lock_user_string(arg1); |
|
3232 |
if (!(p = lock_user_string(arg1))) |
|
3233 |
goto efault; |
|
3132 | 3234 |
ret = get_errno(chroot(p)); |
3133 | 3235 |
unlock_user(p, arg1, 0); |
3134 | 3236 |
break; |
... | ... | |
3155 | 3257 |
struct target_old_sigaction *old_act; |
3156 | 3258 |
struct target_sigaction act, oact, *pact; |
3157 | 3259 |
if (arg2) { |
3158 |
lock_user_struct(old_act, arg2, 1); |
|
3260 |
if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1)) |
|
3261 |
goto efault; |
|
3159 | 3262 |
act._sa_handler = old_act->_sa_handler; |
3160 | 3263 |
target_siginitset(&act.sa_mask, old_act->sa_mask); |
3161 | 3264 |
act.sa_flags = old_act->sa_flags; |
... | ... | |
3167 | 3270 |
} |
3168 | 3271 |
ret = get_errno(do_sigaction(arg1, pact, &oact)); |
3169 | 3272 |
if (!is_error(ret) && arg3) { |
3170 |
lock_user_struct(old_act, arg3, 0); |
|
3273 |
if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0)) |
|
3274 |
goto efault; |
|
3171 | 3275 |
old_act->_sa_handler = oact._sa_handler; |
3172 | 3276 |
old_act->sa_mask = oact.sa_mask.sig[0]; |
3173 | 3277 |
old_act->sa_flags = oact.sa_flags; |
... | ... | |
3178 | 3282 |
struct target_sigaction act, oact, *pact, *old_act; |
3179 | 3283 |
|
3180 | 3284 |
if (arg2) { |
3181 |
lock_user_struct(old_act, arg2, 1); |
|
3285 |
if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1)) |
|
3286 |
goto efault; |
|
3182 | 3287 |
act._sa_handler = old_act->_sa_handler; |
3183 | 3288 |
target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]); |
3184 | 3289 |
act.sa_flags = old_act->sa_flags; |
... | ... | |
3191 | 3296 |
ret = get_errno(do_sigaction(arg1, pact, &oact)); |
3192 | 3297 |
|
3193 | 3298 |
if (!is_error(ret) && arg3) { |
3194 |
lock_user_struct(old_act, arg3, 0); |
|
3299 |
if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0)) |
|
3300 |
goto efault; |
|
3195 | 3301 |
old_act->_sa_handler = oact._sa_handler; |
3196 | 3302 |
old_act->sa_flags = oact.sa_flags; |
3197 | 3303 |
old_act->sa_mask.sig[0] = oact.sa_mask.sig[0]; |
... | ... | |
3209 | 3315 |
struct target_sigaction *act; |
3210 | 3316 |
struct target_sigaction *oact; |
3211 | 3317 |
|
3212 |
if (arg2) |
|
3213 |
lock_user_struct(act, arg2, 1); |
|
3214 |
else |
|
3318 |
if (arg2) { |
|
3319 |
if (!lock_user_struct(VERIFY_READ, act, arg2, 1)) |
|
3320 |
goto efault; |
|
3321 |
} else |
|
3215 | 3322 |
act = NULL; |
3216 |
if (arg3) |
|
3217 |
lock_user_struct(oact, arg3, 0); |
|
3218 |
else |
|
3323 |
if (arg3) { |
|
3324 |
if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) { |
|
3325 |
ret = -TARGET_EFAULT; |
|
3326 |
goto rt_sigaction_fail; |
|
3327 |
} |
|
3328 |
} else |
|
3219 | 3329 |
oact = NULL; |
3220 | 3330 |
ret = get_errno(do_sigaction(arg1, act, oact)); |
3221 |
if (arg2) |
|
3331 |
rt_sigaction_fail: |
|
3332 |
if (act) |
|
3222 | 3333 |
unlock_user_struct(act, arg2, 0); |
3223 |
if (arg3)
|
|
3334 |
if (oact)
|
|
3224 | 3335 |
unlock_user_struct(oact, arg3, 1); |
3225 | 3336 |
} |
3226 | 3337 |
break; |
... | ... | |
3270 | 3381 |
ret = -TARGET_EINVAL; |
3271 | 3382 |
goto fail; |
3272 | 3383 |
} |
3273 |
p = lock_user(arg2, sizeof(target_sigset_t), 1); |
|
3384 |
if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1))) |
|
3385 |
goto efault; |
|
3274 | 3386 |
target_to_host_old_sigset(&set, p); |
3275 | 3387 |
unlock_user(p, arg2, 0); |
3276 | 3388 |
set_ptr = &set; |
... | ... | |
3280 | 3392 |
} |
3281 | 3393 |
ret = get_errno(sigprocmask(arg1, set_ptr, &oldset)); |
3282 | 3394 |
if (!is_error(ret) && arg3) { |
3283 |
p = lock_user(arg3, sizeof(target_sigset_t), 0); |
|
3395 |
if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0))) |
|
3396 |
goto efault; |
|
3284 | 3397 |
host_to_target_old_sigset(p, &oldset); |
3285 | 3398 |
unlock_user(p, arg3, sizeof(target_sigset_t)); |
3286 | 3399 |
} |
... | ... | |
3307 | 3420 |
ret = -TARGET_EINVAL; |
3308 | 3421 |
goto fail; |
3309 | 3422 |
} |
3310 |
p = lock_user(arg2, sizeof(target_sigset_t), 1); |
|
3423 |
if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1))) |
|
3424 |
goto efault; |
|
3311 | 3425 |
target_to_host_sigset(&set, p); |
3312 | 3426 |
unlock_user(p, arg2, 0); |
3313 | 3427 |
set_ptr = &set; |
... | ... | |
3317 | 3431 |
} |
3318 | 3432 |
ret = get_errno(sigprocmask(how, set_ptr, &oldset)); |
3319 | 3433 |
if (!is_error(ret) && arg3) { |
3320 |
p = lock_user(arg3, sizeof(target_sigset_t), 0); |
|
3434 |
if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0))) |
|
3435 |
goto efault; |
|
3321 | 3436 |
host_to_target_sigset(p, &oldset); |
3322 | 3437 |
unlock_user(p, arg3, sizeof(target_sigset_t)); |
3323 | 3438 |
} |
... | ... | |
3329 | 3444 |
sigset_t set; |
3330 | 3445 |
ret = get_errno(sigpending(&set)); |
3331 | 3446 |
if (!is_error(ret)) { |
3332 |
p = lock_user(arg1, sizeof(target_sigset_t), 0); |
|
3447 |
if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0))) |
|
3448 |
goto efault; |
|
3333 | 3449 |
host_to_target_old_sigset(p, &set); |
3334 | 3450 |
unlock_user(p, arg1, sizeof(target_sigset_t)); |
3335 | 3451 |
} |
... | ... | |
3341 | 3457 |
sigset_t set; |
3342 | 3458 |
ret = get_errno(sigpending(&set)); |
3343 | 3459 |
if (!is_error(ret)) { |
3344 |
p = lock_user(arg1, sizeof(target_sigset_t), 0); |
|
3460 |
if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0))) |
|
3461 |
goto efault; |
|
3345 | 3462 |
host_to_target_sigset(p, &set); |
3346 | 3463 |
unlock_user(p, arg1, sizeof(target_sigset_t)); |
3347 | 3464 |
} |
... | ... | |
3351 | 3468 |
case TARGET_NR_sigsuspend: |
3352 | 3469 |
{ |
3353 | 3470 |
sigset_t set; |
3354 |
p = lock_user(arg1, sizeof(target_sigset_t), 1); |
|
3471 |
if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1))) |
|
3472 |
goto efault; |
|
3355 | 3473 |
target_to_host_old_sigset(&set, p); |
3356 | 3474 |
unlock_user(p, arg1, 0); |
3357 | 3475 |
ret = get_errno(sigsuspend(&set)); |
... | ... | |
3361 | 3479 |
case TARGET_NR_rt_sigsuspend: |
3362 | 3480 |
{ |
3363 | 3481 |
sigset_t set; |
3364 |
p = lock_user(arg1, sizeof(target_sigset_t), 1); |
|
3482 |
if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1))) |
|
3483 |
goto efault; |
|
3365 | 3484 |
target_to_host_sigset(&set, p); |
3366 | 3485 |
unlock_user(p, arg1, 0); |
3367 | 3486 |
ret = get_errno(sigsuspend(&set)); |
... | ... | |
3373 | 3492 |
struct timespec uts, *puts; |
3374 | 3493 |
siginfo_t uinfo; |
3375 | 3494 |
|
3376 |
p = lock_user(arg1, sizeof(target_sigset_t), 1); |
|
3495 |
if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1))) |
|
3496 |
goto efault; |
|
3377 | 3497 |
target_to_host_sigset(&set, p); |
3378 | 3498 |
unlock_user(p, arg1, 0); |
3379 | 3499 |
if (arg3) { |
... | ... | |
3384 | 3504 |
} |
3385 | 3505 |
ret = get_errno(sigtimedwait(&set, &uinfo, puts)); |
3386 | 3506 |
if (!is_error(ret) && arg2) { |
3387 |
p = lock_user(arg2, sizeof(target_sigset_t), 0); |
|
3507 |
if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_sigset_t), 0))) |
|
3508 |
goto efault; |
|
3388 | 3509 |
host_to_target_siginfo(p, &uinfo); |
3389 | 3510 |
unlock_user(p, arg2, sizeof(target_sigset_t)); |
3390 | 3511 |
} |
... | ... | |
3393 | 3514 |
case TARGET_NR_rt_sigqueueinfo: |
3394 | 3515 |
{ |
3395 | 3516 |
siginfo_t uinfo; |
3396 |
p = lock_user(arg3, sizeof(target_sigset_t), 1); |
|
3517 |
if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1))) |
|
3518 |
goto efault; |
|
3397 | 3519 |
target_to_host_siginfo(&uinfo, p); |
3398 | 3520 |
unlock_user(p, arg1, 0); |
3399 | 3521 |
ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo)); |
... | ... | |
3410 | 3532 |
ret = do_rt_sigreturn(cpu_env); |
3411 | 3533 |
break; |
3412 | 3534 |
case TARGET_NR_sethostname: |
3413 |
p = lock_user_string(arg1); |
|
3535 |
if (!(p = lock_user_string(arg1))) |
|
3536 |
goto efault; |
|
3414 | 3537 |
ret = get_errno(sethostname(p, arg2)); |
3415 | 3538 |
unlock_user(p, arg1, 0); |
3416 | 3539 |
break; |
... | ... | |
3420 | 3543 |
int resource = arg1; |
3421 | 3544 |
struct target_rlimit *target_rlim; |
3422 | 3545 |
struct rlimit rlim; |
3423 |
lock_user_struct(target_rlim, arg2, 1); |
|
3546 |
if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1)) |
|
3547 |
goto efault; |
|
3424 | 3548 |
rlim.rlim_cur = tswapl(target_rlim->rlim_cur); |
3425 | 3549 |
rlim.rlim_max = tswapl(target_rlim->rlim_max); |
3426 | 3550 |
unlock_user_struct(target_rlim, arg2, 0); |
... | ... | |
3436 | 3560 |
|
3437 | 3561 |
ret = get_errno(getrlimit(resource, &rlim)); |
3438 | 3562 |
if (!is_error(ret)) { |
3439 |
lock_user_struct(target_rlim, arg2, 0); |
|
3563 |
if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0)) |
|
3564 |
goto efault; |
|
3440 | 3565 |
rlim.rlim_cur = tswapl(target_rlim->rlim_cur); |
3441 | 3566 |
rlim.rlim_max = tswapl(target_rlim->rlim_max); |
3442 | 3567 |
unlock_user_struct(target_rlim, arg2, 1); |
... | ... | |
3475 | 3600 |
abi_ulong inp, outp, exp, tvp; |
3476 | 3601 |
long nsel; |
3477 | 3602 |
|
3478 |
lock_user_struct(sel, arg1, 1); |
|
3603 |
if (!lock_user_struct(VERIFY_READ, sel, arg1, 1)) |
|
3604 |
goto efault; |
|
3479 | 3605 |
nsel = tswapl(sel->n); |
3480 | 3606 |
inp = tswapl(sel->inp); |
3481 | 3607 |
outp = tswapl(sel->outp); |
... | ... | |
3491 | 3617 |
void *p2; |
3492 | 3618 |
p = lock_user_string(arg1); |
3493 | 3619 |
p2 = lock_user_string(arg2); |
3494 |
ret = get_errno(symlink(p, p2)); |
|
3620 |
if (!p || !p2) |
|
3621 |
ret = -TARGET_EFAULT; |
|
3622 |
else |
|
3623 |
ret = get_errno(symlink(p, p2)); |
|
3495 | 3624 |
unlock_user(p2, arg2, 0); |
3496 | 3625 |
unlock_user(p, arg1, 0); |
3497 | 3626 |
} |
3498 | 3627 |
break; |
3499 | 3628 |
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat) |
3500 | 3629 |
case TARGET_NR_symlinkat: |
3501 |
if (!arg1 || !arg3) { |
|
3502 |
ret = -TARGET_EFAULT; |
|
3503 |
goto fail; |
|
3504 |
} |
|
3505 | 3630 |
{ |
3506 |
void *p2 = NULL;
|
|
3631 |
void *p2; |
|
3507 | 3632 |
p = lock_user_string(arg1); |
3508 | 3633 |
p2 = lock_user_string(arg3); |
3509 |
if (!access_ok(VERIFY_READ, p, 1) |
|
3510 |
|| !access_ok(VERIFY_READ, p2, 1)) |
|
3511 |
/* Don't "goto fail" so that cleanup can happen. */ |
|
3634 |
if (!p || !p2) |
|
3512 | 3635 |
ret = -TARGET_EFAULT; |
3513 | 3636 |
else |
3514 | 3637 |
ret = get_errno(sys_symlinkat(p, arg2, p2)); |
3515 |
if (p2) |
|
3516 |
unlock_user(p2, arg3, 0); |
|
3517 |
if (p) |
|
3518 |
unlock_user(p, arg1, 0); |
|
3638 |
unlock_user(p2, arg3, 0); |
|
3639 |
unlock_user(p, arg1, 0); |
|
3519 | 3640 |
} |
3520 | 3641 |
break; |
3521 | 3642 |
#endif |
... | ... | |
3527 | 3648 |
{ |
3528 | 3649 |
void *p2; |
3529 | 3650 |
p = lock_user_string(arg1); |
3530 |
p2 = lock_user(arg2, arg3, 0); |
|
3531 |
ret = get_errno(readlink(path(p), p2, arg3)); |
|
3651 |
p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0); |
|
3652 |
if (!p || !p2) |
|
3653 |
ret = -TARGET_EFAULT; |
|
3654 |
else |
|
3655 |
ret = get_errno(readlink(path(p), p2, arg3)); |
|
3532 | 3656 |
unlock_user(p2, arg2, ret); |
3533 | 3657 |
unlock_user(p, arg1, 0); |
3534 | 3658 |
} |
3535 | 3659 |
break; |
3536 | 3660 |
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat) |
3537 | 3661 |
case TARGET_NR_readlinkat: |
3538 |
if (!arg2 || !arg3) { |
|
3539 |
ret = -TARGET_EFAULT; |
|
3540 |
goto fail; |
|
3541 |
} |
|
3542 | 3662 |
{ |
3543 |
void *p2 = NULL;
|
|
3663 |
void *p2; |
|
3544 | 3664 |
p = lock_user_string(arg2); |
3545 |
p2 = lock_user(arg3, arg4, 0); |
|
3546 |
if (!access_ok(VERIFY_READ, p, 1) |
|
3547 |
|| !access_ok(VERIFY_READ, p2, 1)) |
|
3548 |
/* Don't "goto fail" so that cleanup can happen. */ |
|
3665 |
p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0); |
|
3666 |
if (!p || !p2) |
|
3549 | 3667 |
ret = -TARGET_EFAULT; |
3550 | 3668 |
else |
3551 | 3669 |
ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4)); |
3552 |
if (p2) |
|
3553 |
unlock_user(p2, arg3, ret); |
|
3554 |
if (p) |
|
3555 |
unlock_user(p, arg2, 0); |
|
3670 |
unlock_user(p2, arg3, ret); |
|
3671 |
unlock_user(p, arg2, 0); |
|
3556 | 3672 |
} |
3557 | 3673 |
break; |
3558 | 3674 |
#endif |
... | ... | |
3562 | 3678 |
#endif |
3563 | 3679 |
#ifdef TARGET_NR_swapon |
3564 | 3680 |
case TARGET_NR_swapon: |
3565 |
p = lock_user_string(arg1); |
|
3681 |
if (!(p = lock_user_string(arg1))) |
|
3682 |
goto efault; |
|
3566 | 3683 |
ret = get_errno(swapon(p, arg2)); |
3567 | 3684 |
unlock_user(p, arg1, 0); |
3568 | 3685 |
break; |
... | ... | |
3579 | 3696 |
{ |
3580 | 3697 |
abi_ulong *v; |
3581 | 3698 |
abi_ulong v1, v2, v3, v4, v5, v6; |
3582 |
v = lock_user(arg1, 6 * sizeof(abi_ulong), 1); |
|
3699 |
if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1))) |
|
3700 |
goto efault; |
|
3583 | 3701 |
v1 = tswapl(v[0]); |
3584 | 3702 |
v2 = tswapl(v[1]); |
3585 | 3703 |
v3 = tswapl(v[2]); |
... | ... | |
3650 | 3768 |
break; |
3651 | 3769 |
#endif |
3652 | 3770 |
case TARGET_NR_truncate: |
3653 |
p = lock_user_string(arg1); |
|
3771 |
if (!(p = lock_user_string(arg1))) |
|
3772 |
goto efault; |
|
3654 | 3773 |
ret = get_errno(truncate(p, arg2)); |
3655 | 3774 |
unlock_user(p, arg1, 0); |
3656 | 3775 |
break; |
Also available in: Unified diff