Revision 2f619698 linux-user/syscall.c
b/linux-user/syscall.c | ||
---|---|---|
783 | 783 |
|
784 | 784 |
/* do_setsockopt() Must return target values and target errnos. */ |
785 | 785 |
static abi_long do_setsockopt(int sockfd, int level, int optname, |
786 |
abi_ulong optval, socklen_t optlen) |
|
786 |
abi_ulong optval_addr, socklen_t optlen)
|
|
787 | 787 |
{ |
788 | 788 |
abi_long ret; |
789 | 789 |
int val; |
... | ... | |
794 | 794 |
if (optlen < sizeof(uint32_t)) |
795 | 795 |
return -TARGET_EINVAL; |
796 | 796 |
|
797 |
val = tget32(optval); |
|
797 |
if (get_user_u32(val, optval_addr)) |
|
798 |
return -TARGET_EFAULT; |
|
798 | 799 |
ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); |
799 | 800 |
break; |
800 | 801 |
case SOL_IP: |
... | ... | |
816 | 817 |
case IP_MULTICAST_LOOP: |
817 | 818 |
val = 0; |
818 | 819 |
if (optlen >= sizeof(uint32_t)) { |
819 |
val = tget32(optval); |
|
820 |
if (get_user_u32(val, optval_addr)) |
|
821 |
return -TARGET_EFAULT; |
|
820 | 822 |
} else if (optlen >= 1) { |
821 |
val = tget8(optval); |
|
823 |
if (get_user_u8(val, optval_addr)) |
|
824 |
return -TARGET_EFAULT; |
|
822 | 825 |
} |
823 | 826 |
ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); |
824 | 827 |
break; |
... | ... | |
890 | 893 |
goto unimplemented; |
891 | 894 |
} |
892 | 895 |
if (optlen < sizeof(uint32_t)) |
893 |
return -TARGET_EINVAL;
|
|
896 |
return -TARGET_EINVAL;
|
|
894 | 897 |
|
895 |
val = tget32(optval); |
|
898 |
if (get_user_u32(val, optval_addr)) |
|
899 |
return -TARGET_EFAULT; |
|
896 | 900 |
ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val))); |
897 | 901 |
break; |
898 | 902 |
default: |
... | ... | |
905 | 909 |
|
906 | 910 |
/* do_getsockopt() Must return target values and target errnos. */ |
907 | 911 |
static abi_long do_getsockopt(int sockfd, int level, int optname, |
908 |
abi_ulong optval, abi_ulong optlen) |
|
912 |
abi_ulong optval_addr, abi_ulong optlen)
|
|
909 | 913 |
{ |
910 | 914 |
abi_long ret; |
911 | 915 |
int len, lv, val; |
... | ... | |
928 | 932 |
case SOL_TCP: |
929 | 933 |
/* TCP options all take an 'int' value. */ |
930 | 934 |
int_case: |
931 |
len = tget32(optlen); |
|
935 |
if (get_user_u32(len, optlen)) |
|
936 |
return -TARGET_EFAULT; |
|
932 | 937 |
if (len < 0) |
933 | 938 |
return -TARGET_EINVAL; |
934 | 939 |
lv = sizeof(int); |
... | ... | |
938 | 943 |
val = tswap32(val); |
939 | 944 |
if (len > lv) |
940 | 945 |
len = lv; |
941 |
if (len == 4) |
|
942 |
tput32(optval, val); |
|
943 |
else |
|
944 |
tput8(optval, val); |
|
945 |
tput32(optlen, len); |
|
946 |
if (len == 4) { |
|
947 |
if (put_user_u32(val, optval_addr)) |
|
948 |
return -TARGET_EFAULT; |
|
949 |
} else { |
|
950 |
if (put_user_u8(val, optval_addr)) |
|
951 |
return -TARGET_EFAULT; |
|
952 |
} |
|
953 |
if (put_user_u32(len, optlen)) |
|
954 |
return -TARGET_EFAULT; |
|
946 | 955 |
break; |
947 | 956 |
case SOL_IP: |
948 | 957 |
switch(optname) { |
... | ... | |
961 | 970 |
#endif |
962 | 971 |
case IP_MULTICAST_TTL: |
963 | 972 |
case IP_MULTICAST_LOOP: |
964 |
len = tget32(optlen); |
|
973 |
if (get_user_u32(len, optlen)) |
|
974 |
return -TARGET_EFAULT; |
|
965 | 975 |
if (len < 0) |
966 | 976 |
return -TARGET_EINVAL; |
967 | 977 |
lv = sizeof(int); |
... | ... | |
970 | 980 |
return ret; |
971 | 981 |
if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) { |
972 | 982 |
len = 1; |
973 |
tput32(optlen, len); |
|
974 |
tput8(optval, val); |
|
983 |
if (put_user_u32(len, optlen) |
|
984 |
|| put_user_u8(val, optval_addr)) |
|
985 |
return -TARGET_EFAULT; |
|
975 | 986 |
} else { |
976 | 987 |
if (len > sizeof(int)) |
977 | 988 |
len = sizeof(int); |
978 |
tput32(optlen, len); |
|
979 |
tput32(optval, val); |
|
989 |
if (put_user_u32(len, optlen) |
|
990 |
|| put_user_u32(val, optval_addr)) |
|
991 |
return -TARGET_EFAULT; |
|
980 | 992 |
} |
981 | 993 |
break; |
982 | 994 |
default: |
... | ... | |
1148 | 1160 |
|
1149 | 1161 |
/* do_accept() Must return target values and target errnos. */ |
1150 | 1162 |
static abi_long do_accept(int fd, abi_ulong target_addr, |
1151 |
abi_ulong target_addrlen) |
|
1163 |
abi_ulong target_addrlen_addr)
|
|
1152 | 1164 |
{ |
1153 |
socklen_t addrlen = tget32(target_addrlen);
|
|
1154 |
void *addr = alloca(addrlen);
|
|
1165 |
socklen_t addrlen; |
|
1166 |
void *addr; |
|
1155 | 1167 |
abi_long ret; |
1156 | 1168 |
|
1169 |
if (get_user_u32(addrlen, target_addrlen_addr)) |
|
1170 |
return -TARGET_EFAULT; |
|
1171 |
|
|
1172 |
addr = alloca(addrlen); |
|
1173 |
|
|
1157 | 1174 |
ret = get_errno(accept(fd, addr, &addrlen)); |
1158 | 1175 |
if (!is_error(ret)) { |
1159 | 1176 |
host_to_target_sockaddr(target_addr, addr, addrlen); |
1160 |
tput32(target_addrlen, addrlen); |
|
1177 |
if (put_user_u32(addrlen, target_addrlen_addr)) |
|
1178 |
ret = -TARGET_EFAULT; |
|
1161 | 1179 |
} |
1162 | 1180 |
return ret; |
1163 | 1181 |
} |
1164 | 1182 |
|
1165 | 1183 |
/* do_getpeername() Must return target values and target errnos. */ |
1166 | 1184 |
static abi_long do_getpeername(int fd, abi_ulong target_addr, |
1167 |
abi_ulong target_addrlen) |
|
1185 |
abi_ulong target_addrlen_addr)
|
|
1168 | 1186 |
{ |
1169 |
socklen_t addrlen = tget32(target_addrlen);
|
|
1170 |
void *addr = alloca(addrlen);
|
|
1187 |
socklen_t addrlen; |
|
1188 |
void *addr; |
|
1171 | 1189 |
abi_long ret; |
1172 | 1190 |
|
1191 |
if (get_user_u32(addrlen, target_addrlen_addr)) |
|
1192 |
return -TARGET_EFAULT; |
|
1193 |
|
|
1194 |
addr = alloca(addrlen); |
|
1195 |
|
|
1173 | 1196 |
ret = get_errno(getpeername(fd, addr, &addrlen)); |
1174 | 1197 |
if (!is_error(ret)) { |
1175 | 1198 |
host_to_target_sockaddr(target_addr, addr, addrlen); |
1176 |
tput32(target_addrlen, addrlen); |
|
1199 |
if (put_user_u32(addrlen, target_addrlen_addr)) |
|
1200 |
ret = -TARGET_EFAULT; |
|
1177 | 1201 |
} |
1178 | 1202 |
return ret; |
1179 | 1203 |
} |
1180 | 1204 |
|
1181 | 1205 |
/* do_getsockname() Must return target values and target errnos. */ |
1182 | 1206 |
static abi_long do_getsockname(int fd, abi_ulong target_addr, |
1183 |
abi_ulong target_addrlen) |
|
1207 |
abi_ulong target_addrlen_addr)
|
|
1184 | 1208 |
{ |
1185 |
socklen_t addrlen = tget32(target_addrlen);
|
|
1186 |
void *addr = alloca(addrlen);
|
|
1209 |
socklen_t addrlen; |
|
1210 |
void *addr; |
|
1187 | 1211 |
abi_long ret; |
1188 | 1212 |
|
1213 |
if (get_user_u32(addrlen, target_addrlen_addr)) |
|
1214 |
return -TARGET_EFAULT; |
|
1215 |
|
|
1216 |
addr = alloca(addrlen); |
|
1217 |
|
|
1189 | 1218 |
ret = get_errno(getsockname(fd, addr, &addrlen)); |
1190 | 1219 |
if (!is_error(ret)) { |
1191 | 1220 |
host_to_target_sockaddr(target_addr, addr, addrlen); |
1192 |
tput32(target_addrlen, addrlen); |
|
1221 |
if (put_user_u32(addrlen, target_addrlen_addr)) |
|
1222 |
ret = -TARGET_EFAULT; |
|
1193 | 1223 |
} |
1194 | 1224 |
return ret; |
1195 | 1225 |
} |
1196 | 1226 |
|
1197 | 1227 |
/* do_socketpair() Must return target values and target errnos. */ |
1198 | 1228 |
static abi_long do_socketpair(int domain, int type, int protocol, |
1199 |
abi_ulong target_tab) |
|
1229 |
abi_ulong target_tab_addr)
|
|
1200 | 1230 |
{ |
1201 | 1231 |
int tab[2]; |
1202 | 1232 |
abi_long ret; |
1203 | 1233 |
|
1204 | 1234 |
ret = get_errno(socketpair(domain, type, protocol, tab)); |
1205 | 1235 |
if (!is_error(ret)) { |
1206 |
tput32(target_tab, tab[0]); |
|
1207 |
tput32(target_tab + 4, tab[1]); |
|
1236 |
if (put_user_s32(tab[0], target_tab_addr) |
|
1237 |
|| put_user_s32(tab[1], target_tab_addr + sizeof(tab[0]))) |
|
1238 |
ret = -TARGET_EFAULT; |
|
1208 | 1239 |
} |
1209 | 1240 |
return ret; |
1210 | 1241 |
} |
... | ... | |
1245 | 1276 |
if (!host_msg) |
1246 | 1277 |
return -TARGET_EFAULT; |
1247 | 1278 |
if (target_addr) { |
1248 |
addrlen = tget32(target_addrlen); |
|
1279 |
if (get_user_u32(addrlen, target_addrlen)) { |
|
1280 |
ret = -TARGET_EFAULT; |
|
1281 |
goto fail; |
|
1282 |
} |
|
1249 | 1283 |
addr = alloca(addrlen); |
1250 | 1284 |
ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen)); |
1251 | 1285 |
} else { |
... | ... | |
1255 | 1289 |
if (!is_error(ret)) { |
1256 | 1290 |
if (target_addr) { |
1257 | 1291 |
host_to_target_sockaddr(target_addr, addr, addrlen); |
1258 |
tput32(target_addrlen, addrlen); |
|
1292 |
if (put_user_u32(addrlen, target_addrlen)) { |
|
1293 |
ret = -TARGET_EFAULT; |
|
1294 |
goto fail; |
|
1295 |
} |
|
1259 | 1296 |
} |
1260 | 1297 |
unlock_user(host_msg, msg, len); |
1261 | 1298 |
} else { |
1299 |
fail: |
|
1262 | 1300 |
unlock_user(host_msg, msg, 0); |
1263 | 1301 |
} |
1264 | 1302 |
return ret; |
... | ... | |
1274 | 1312 |
switch(num) { |
1275 | 1313 |
case SOCKOP_socket: |
1276 | 1314 |
{ |
1277 |
int domain = tgetl(vptr); |
|
1278 |
int type = tgetl(vptr + n); |
|
1279 |
int protocol = tgetl(vptr + 2 * n); |
|
1315 |
int domain, type, protocol; |
|
1316 |
|
|
1317 |
if (get_user_s32(domain, vptr) |
|
1318 |
|| get_user_s32(type, vptr + n) |
|
1319 |
|| get_user_s32(protocol, vptr + 2 * n)) |
|
1320 |
return -TARGET_EFAULT; |
|
1321 |
|
|
1280 | 1322 |
ret = do_socket(domain, type, protocol); |
1281 | 1323 |
} |
1282 | 1324 |
break; |
1283 | 1325 |
case SOCKOP_bind: |
1284 | 1326 |
{ |
1285 |
int sockfd = tgetl(vptr); |
|
1286 |
abi_ulong target_addr = tgetl(vptr + n); |
|
1287 |
socklen_t addrlen = tgetl(vptr + 2 * n); |
|
1327 |
int sockfd; |
|
1328 |
abi_ulong target_addr; |
|
1329 |
socklen_t addrlen; |
|
1330 |
|
|
1331 |
if (get_user_s32(sockfd, vptr) |
|
1332 |
|| get_user_ual(target_addr, vptr + n) |
|
1333 |
|| get_user_u32(addrlen, vptr + 2 * n)) |
|
1334 |
return -TARGET_EFAULT; |
|
1335 |
|
|
1288 | 1336 |
ret = do_bind(sockfd, target_addr, addrlen); |
1289 | 1337 |
} |
1290 | 1338 |
break; |
1291 | 1339 |
case SOCKOP_connect: |
1292 | 1340 |
{ |
1293 |
int sockfd = tgetl(vptr); |
|
1294 |
abi_ulong target_addr = tgetl(vptr + n); |
|
1295 |
socklen_t addrlen = tgetl(vptr + 2 * n); |
|
1341 |
int sockfd; |
|
1342 |
abi_ulong target_addr; |
|
1343 |
socklen_t addrlen; |
|
1344 |
|
|
1345 |
if (get_user_s32(sockfd, vptr) |
|
1346 |
|| get_user_ual(target_addr, vptr + n) |
|
1347 |
|| get_user_u32(addrlen, vptr + 2 * n)) |
|
1348 |
return -TARGET_EFAULT; |
|
1349 |
|
|
1296 | 1350 |
ret = do_connect(sockfd, target_addr, addrlen); |
1297 | 1351 |
} |
1298 | 1352 |
break; |
1299 | 1353 |
case SOCKOP_listen: |
1300 | 1354 |
{ |
1301 |
int sockfd = tgetl(vptr); |
|
1302 |
int backlog = tgetl(vptr + n); |
|
1355 |
int sockfd, backlog; |
|
1356 |
|
|
1357 |
if (get_user_s32(sockfd, vptr) |
|
1358 |
|| get_user_s32(backlog, vptr + n)) |
|
1359 |
return -TARGET_EFAULT; |
|
1360 |
|
|
1303 | 1361 |
ret = get_errno(listen(sockfd, backlog)); |
1304 | 1362 |
} |
1305 | 1363 |
break; |
1306 | 1364 |
case SOCKOP_accept: |
1307 | 1365 |
{ |
1308 |
int sockfd = tgetl(vptr); |
|
1309 |
abi_ulong target_addr = tgetl(vptr + n); |
|
1310 |
abi_ulong target_addrlen = tgetl(vptr + 2 * n); |
|
1366 |
int sockfd; |
|
1367 |
abi_ulong target_addr, target_addrlen; |
|
1368 |
|
|
1369 |
if (get_user_s32(sockfd, vptr) |
|
1370 |
|| get_user_ual(target_addr, vptr + n) |
|
1371 |
|| get_user_u32(target_addrlen, vptr + 2 * n)) |
|
1372 |
return -TARGET_EFAULT; |
|
1373 |
|
|
1311 | 1374 |
ret = do_accept(sockfd, target_addr, target_addrlen); |
1312 | 1375 |
} |
1313 | 1376 |
break; |
1314 | 1377 |
case SOCKOP_getsockname: |
1315 | 1378 |
{ |
1316 |
int sockfd = tgetl(vptr); |
|
1317 |
abi_ulong target_addr = tgetl(vptr + n); |
|
1318 |
abi_ulong target_addrlen = tgetl(vptr + 2 * n); |
|
1379 |
int sockfd; |
|
1380 |
abi_ulong target_addr, target_addrlen; |
|
1381 |
|
|
1382 |
if (get_user_s32(sockfd, vptr) |
|
1383 |
|| get_user_ual(target_addr, vptr + n) |
|
1384 |
|| get_user_u32(target_addrlen, vptr + 2 * n)) |
|
1385 |
return -TARGET_EFAULT; |
|
1386 |
|
|
1319 | 1387 |
ret = do_getsockname(sockfd, target_addr, target_addrlen); |
1320 | 1388 |
} |
1321 | 1389 |
break; |
1322 | 1390 |
case SOCKOP_getpeername: |
1323 | 1391 |
{ |
1324 |
int sockfd = tgetl(vptr); |
|
1325 |
abi_ulong target_addr = tgetl(vptr + n); |
|
1326 |
abi_ulong target_addrlen = tgetl(vptr + 2 * n); |
|
1392 |
int sockfd; |
|
1393 |
abi_ulong target_addr, target_addrlen; |
|
1394 |
|
|
1395 |
if (get_user_s32(sockfd, vptr) |
|
1396 |
|| get_user_ual(target_addr, vptr + n) |
|
1397 |
|| get_user_u32(target_addrlen, vptr + 2 * n)) |
|
1398 |
return -TARGET_EFAULT; |
|
1399 |
|
|
1327 | 1400 |
ret = do_getpeername(sockfd, target_addr, target_addrlen); |
1328 | 1401 |
} |
1329 | 1402 |
break; |
1330 | 1403 |
case SOCKOP_socketpair: |
1331 | 1404 |
{ |
1332 |
int domain = tgetl(vptr); |
|
1333 |
int type = tgetl(vptr + n); |
|
1334 |
int protocol = tgetl(vptr + 2 * n); |
|
1335 |
abi_ulong tab = tgetl(vptr + 3 * n); |
|
1405 |
int domain, type, protocol; |
|
1406 |
abi_ulong tab; |
|
1407 |
|
|
1408 |
if (get_user_s32(domain, vptr) |
|
1409 |
|| get_user_s32(type, vptr + n) |
|
1410 |
|| get_user_s32(protocol, vptr + 2 * n) |
|
1411 |
|| get_user_ual(tab, vptr + 3 * n)) |
|
1412 |
return -TARGET_EFAULT; |
|
1413 |
|
|
1336 | 1414 |
ret = do_socketpair(domain, type, protocol, tab); |
1337 | 1415 |
} |
1338 | 1416 |
break; |
1339 | 1417 |
case SOCKOP_send: |
1340 | 1418 |
{ |
1341 |
int sockfd = tgetl(vptr); |
|
1342 |
abi_ulong msg = tgetl(vptr + n); |
|
1343 |
size_t len = tgetl(vptr + 2 * n); |
|
1344 |
int flags = tgetl(vptr + 3 * n); |
|
1419 |
int sockfd; |
|
1420 |
abi_ulong msg; |
|
1421 |
size_t len; |
|
1422 |
int flags; |
|
1423 |
|
|
1424 |
if (get_user_s32(sockfd, vptr) |
|
1425 |
|| get_user_ual(msg, vptr + n) |
|
1426 |
|| get_user_ual(len, vptr + 2 * n) |
|
1427 |
|| get_user_s32(flags, vptr + 3 * n)) |
|
1428 |
return -TARGET_EFAULT; |
|
1429 |
|
|
1345 | 1430 |
ret = do_sendto(sockfd, msg, len, flags, 0, 0); |
1346 | 1431 |
} |
1347 | 1432 |
break; |
1348 | 1433 |
case SOCKOP_recv: |
1349 | 1434 |
{ |
1350 |
int sockfd = tgetl(vptr); |
|
1351 |
abi_ulong msg = tgetl(vptr + n); |
|
1352 |
size_t len = tgetl(vptr + 2 * n); |
|
1353 |
int flags = tgetl(vptr + 3 * n); |
|
1435 |
int sockfd; |
|
1436 |
abi_ulong msg; |
|
1437 |
size_t len; |
|
1438 |
int flags; |
|
1439 |
|
|
1440 |
if (get_user_s32(sockfd, vptr) |
|
1441 |
|| get_user_ual(msg, vptr + n) |
|
1442 |
|| get_user_ual(len, vptr + 2 * n) |
|
1443 |
|| get_user_s32(flags, vptr + 3 * n)) |
|
1444 |
return -TARGET_EFAULT; |
|
1445 |
|
|
1354 | 1446 |
ret = do_recvfrom(sockfd, msg, len, flags, 0, 0); |
1355 | 1447 |
} |
1356 | 1448 |
break; |
1357 | 1449 |
case SOCKOP_sendto: |
1358 | 1450 |
{ |
1359 |
int sockfd = tgetl(vptr); |
|
1360 |
abi_ulong msg = tgetl(vptr + n); |
|
1361 |
size_t len = tgetl(vptr + 2 * n); |
|
1362 |
int flags = tgetl(vptr + 3 * n); |
|
1363 |
abi_ulong addr = tgetl(vptr + 4 * n); |
|
1364 |
socklen_t addrlen = tgetl(vptr + 5 * n); |
|
1451 |
int sockfd; |
|
1452 |
abi_ulong msg; |
|
1453 |
size_t len; |
|
1454 |
int flags; |
|
1455 |
abi_ulong addr; |
|
1456 |
socklen_t addrlen; |
|
1457 |
|
|
1458 |
if (get_user_s32(sockfd, vptr) |
|
1459 |
|| get_user_ual(msg, vptr + n) |
|
1460 |
|| get_user_ual(len, vptr + 2 * n) |
|
1461 |
|| get_user_s32(flags, vptr + 3 * n) |
|
1462 |
|| get_user_ual(addr, vptr + 4 * n) |
|
1463 |
|| get_user_u32(addrlen, vptr + 5 * n)) |
|
1464 |
return -TARGET_EFAULT; |
|
1465 |
|
|
1365 | 1466 |
ret = do_sendto(sockfd, msg, len, flags, addr, addrlen); |
1366 | 1467 |
} |
1367 | 1468 |
break; |
1368 | 1469 |
case SOCKOP_recvfrom: |
1369 | 1470 |
{ |
1370 |
int sockfd = tgetl(vptr); |
|
1371 |
abi_ulong msg = tgetl(vptr + n); |
|
1372 |
size_t len = tgetl(vptr + 2 * n); |
|
1373 |
int flags = tgetl(vptr + 3 * n); |
|
1374 |
abi_ulong addr = tgetl(vptr + 4 * n); |
|
1375 |
abi_ulong addrlen = tgetl(vptr + 5 * n); |
|
1471 |
int sockfd; |
|
1472 |
abi_ulong msg; |
|
1473 |
size_t len; |
|
1474 |
int flags; |
|
1475 |
abi_ulong addr; |
|
1476 |
socklen_t addrlen; |
|
1477 |
|
|
1478 |
if (get_user_s32(sockfd, vptr) |
|
1479 |
|| get_user_ual(msg, vptr + n) |
|
1480 |
|| get_user_ual(len, vptr + 2 * n) |
|
1481 |
|| get_user_s32(flags, vptr + 3 * n) |
|
1482 |
|| get_user_ual(addr, vptr + 4 * n) |
|
1483 |
|| get_user_u32(addrlen, vptr + 5 * n)) |
|
1484 |
return -TARGET_EFAULT; |
|
1485 |
|
|
1376 | 1486 |
ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen); |
1377 | 1487 |
} |
1378 | 1488 |
break; |
1379 | 1489 |
case SOCKOP_shutdown: |
1380 | 1490 |
{ |
1381 |
int sockfd = tgetl(vptr); |
|
1382 |
int how = tgetl(vptr + n); |
|
1491 |
int sockfd, how; |
|
1492 |
|
|
1493 |
if (get_user_s32(sockfd, vptr) |
|
1494 |
|| get_user_s32(how, vptr + n)) |
|
1495 |
return -TARGET_EFAULT; |
|
1383 | 1496 |
|
1384 | 1497 |
ret = get_errno(shutdown(sockfd, how)); |
1385 | 1498 |
} |
... | ... | |
1391 | 1504 |
abi_ulong target_msg; |
1392 | 1505 |
int flags; |
1393 | 1506 |
|
1394 |
fd = tgetl(vptr); |
|
1395 |
target_msg = tgetl(vptr + n); |
|
1396 |
flags = tgetl(vptr + 2 * n); |
|
1507 |
if (get_user_s32(fd, vptr) |
|
1508 |
|| get_user_ual(target_msg, vptr + n) |
|
1509 |
|| get_user_s32(flags, vptr + 2 * n)) |
|
1510 |
return -TARGET_EFAULT; |
|
1397 | 1511 |
|
1398 | 1512 |
ret = do_sendrecvmsg(fd, target_msg, flags, |
1399 | 1513 |
(num == SOCKOP_sendmsg)); |
... | ... | |
1401 | 1515 |
break; |
1402 | 1516 |
case SOCKOP_setsockopt: |
1403 | 1517 |
{ |
1404 |
int sockfd = tgetl(vptr); |
|
1405 |
int level = tgetl(vptr + n); |
|
1406 |
int optname = tgetl(vptr + 2 * n); |
|
1407 |
abi_ulong optval = tgetl(vptr + 3 * n); |
|
1408 |
socklen_t optlen = tgetl(vptr + 4 * n); |
|
1518 |
int sockfd; |
|
1519 |
int level; |
|
1520 |
int optname; |
|
1521 |
abi_ulong optval; |
|
1522 |
socklen_t optlen; |
|
1523 |
|
|
1524 |
if (get_user_s32(sockfd, vptr) |
|
1525 |
|| get_user_s32(level, vptr + n) |
|
1526 |
|| get_user_s32(optname, vptr + 2 * n) |
|
1527 |
|| get_user_ual(optval, vptr + 3 * n) |
|
1528 |
|| get_user_u32(optlen, vptr + 4 * n)) |
|
1529 |
return -TARGET_EFAULT; |
|
1409 | 1530 |
|
1410 | 1531 |
ret = do_setsockopt(sockfd, level, optname, optval, optlen); |
1411 | 1532 |
} |
1412 | 1533 |
break; |
1413 | 1534 |
case SOCKOP_getsockopt: |
1414 | 1535 |
{ |
1415 |
int sockfd = tgetl(vptr); |
|
1416 |
int level = tgetl(vptr + n); |
|
1417 |
int optname = tgetl(vptr + 2 * n); |
|
1418 |
abi_ulong optval = tgetl(vptr + 3 * n); |
|
1419 |
abi_ulong poptlen = tgetl(vptr + 4 * n); |
|
1536 |
int sockfd; |
|
1537 |
int level; |
|
1538 |
int optname; |
|
1539 |
abi_ulong optval; |
|
1540 |
socklen_t optlen; |
|
1541 |
|
|
1542 |
if (get_user_s32(sockfd, vptr) |
|
1543 |
|| get_user_s32(level, vptr + n) |
|
1544 |
|| get_user_s32(optname, vptr + 2 * n) |
|
1545 |
|| get_user_ual(optval, vptr + 3 * n) |
|
1546 |
|| get_user_u32(optlen, vptr + 4 * n)) |
|
1547 |
return -TARGET_EFAULT; |
|
1420 | 1548 |
|
1421 |
ret = do_getsockopt(sockfd, level, optname, optval, poptlen);
|
|
1549 |
ret = do_getsockopt(sockfd, level, optname, optval, optlen); |
|
1422 | 1550 |
} |
1423 | 1551 |
break; |
1424 | 1552 |
default: |
... | ... | |
1883 | 2011 |
break; |
1884 | 2012 |
} |
1885 | 2013 |
} |
1886 |
if (put_user(raddr, third, abi_ulong))
|
|
2014 |
if (put_user_ual(raddr, third))
|
|
1887 | 2015 |
return -TARGET_EFAULT; |
1888 | 2016 |
ret = 0; |
1889 | 2017 |
} |
... | ... | |
2957 | 3085 |
unlock_user(p, arg2, 0); |
2958 | 3086 |
break; |
2959 | 3087 |
case TARGET_NR_open: |
2960 |
if (!(p = lock_user_string(arg1))) { |
|
2961 |
return -TARGET_EFAULT; |
|
2962 |
goto fail; |
|
2963 |
} |
|
3088 |
if (!(p = lock_user_string(arg1))) |
|
3089 |
goto efault; |
|
2964 | 3090 |
ret = get_errno(open(path(p), |
2965 | 3091 |
target_to_host_bitmask(arg2, fcntl_flags_tbl), |
2966 | 3092 |
arg3)); |
... | ... | |
2991 | 3117 |
{ |
2992 | 3118 |
int status; |
2993 | 3119 |
ret = get_errno(waitpid(arg1, &status, arg3)); |
2994 |
if (!is_error(ret) && arg2) |
|
2995 |
tput32(arg2, status); |
|
3120 |
if (!is_error(ret) && arg2 |
|
3121 |
&& put_user_s32(status, arg2)) |
|
3122 |
goto efault; |
|
2996 | 3123 |
} |
2997 | 3124 |
break; |
2998 | 3125 |
#endif |
... | ... | |
3059 | 3186 |
|
3060 | 3187 |
argc = 0; |
3061 | 3188 |
guest_argp = arg2; |
3062 |
for (gp = guest_argp; tgetl(gp); gp++) |
|
3189 |
for (gp = guest_argp; ; gp++) { |
|
3190 |
if (get_user_ual(guest_argp, gp)) |
|
3191 |
goto efault; |
|
3192 |
if (!guest_argp) |
|
3193 |
break; |
|
3063 | 3194 |
argc++; |
3195 |
} |
|
3064 | 3196 |
envc = 0; |
3065 | 3197 |
guest_envp = arg3; |
3066 |
for (gp = guest_envp; tgetl(gp); gp++) |
|
3198 |
for (gp = guest_envp; ; gp++) { |
|
3199 |
if (get_user_ual(guest_envp, gp)) |
|
3200 |
goto efault; |
|
3201 |
if (!guest_envp) |
|
3202 |
break; |
|
3067 | 3203 |
envc++; |
3204 |
} |
|
3068 | 3205 |
|
3069 | 3206 |
argp = alloca((argc + 1) * sizeof(void *)); |
3070 | 3207 |
envp = alloca((envc + 1) * sizeof(void *)); |
3071 | 3208 |
|
3072 | 3209 |
for (gp = guest_argp, q = argp; ; |
3073 | 3210 |
gp += sizeof(abi_ulong), q++) { |
3074 |
addr = tgetl(gp); |
|
3211 |
if (get_user_ual(addr, gp)) |
|
3212 |
goto execve_efault; |
|
3075 | 3213 |
if (!addr) |
3076 | 3214 |
break; |
3077 |
if (!(*q = lock_user_string(addr))) { |
|
3078 |
ret = -TARGET_EFAULT; |
|
3079 |
goto execve_fail; |
|
3080 |
} |
|
3215 |
if (!(*q = lock_user_string(addr))) |
|
3216 |
goto execve_efault; |
|
3081 | 3217 |
} |
3082 | 3218 |
*q = NULL; |
3083 | 3219 |
|
3084 | 3220 |
for (gp = guest_envp, q = envp; ; |
3085 | 3221 |
gp += sizeof(abi_ulong), q++) { |
3086 |
addr = tgetl(gp); |
|
3222 |
if (get_user_ual(addr, gp)) |
|
3223 |
goto execve_efault; |
|
3087 | 3224 |
if (!addr) |
3088 | 3225 |
break; |
3089 |
if (!(*q = lock_user_string(addr))) { |
|
3090 |
ret = -TARGET_EFAULT; |
|
3091 |
goto execve_fail; |
|
3092 |
} |
|
3226 |
if (!(*q = lock_user_string(addr))) |
|
3227 |
goto execve_efault; |
|
3093 | 3228 |
} |
3094 | 3229 |
*q = NULL; |
3095 | 3230 |
|
3096 |
if (!(p = lock_user_string(arg1))) { |
|
3097 |
ret = -TARGET_EFAULT; |
|
3098 |
goto execve_fail; |
|
3099 |
} |
|
3231 |
if (!(p = lock_user_string(arg1))) |
|
3232 |
goto execve_efault; |
|
3100 | 3233 |
ret = get_errno(execve(p, argp, envp)); |
3101 | 3234 |
unlock_user(p, arg1, 0); |
3102 | 3235 |
|
3103 |
execve_fail: |
|
3236 |
goto execve_end; |
|
3237 |
|
|
3238 |
execve_efault: |
|
3239 |
ret = -TARGET_EFAULT; |
|
3240 |
|
|
3241 |
execve_end: |
|
3104 | 3242 |
for (gp = guest_argp, q = argp; *q; |
3105 | 3243 |
gp += sizeof(abi_ulong), q++) { |
3106 |
addr = tgetl(gp); |
|
3244 |
if (get_user_ual(addr, gp) |
|
3245 |
|| !addr) |
|
3246 |
break; |
|
3107 | 3247 |
unlock_user(*q, addr, 0); |
3108 | 3248 |
} |
3109 | 3249 |
for (gp = guest_envp, q = envp; *q; |
3110 | 3250 |
gp += sizeof(abi_ulong), q++) { |
3111 |
addr = tgetl(gp); |
|
3251 |
if (get_user_ual(addr, gp) |
|
3252 |
|| !addr) |
|
3253 |
break; |
|
3112 | 3254 |
unlock_user(*q, addr, 0); |
3113 | 3255 |
} |
3114 | 3256 |
} |
... | ... | |
3124 | 3266 |
{ |
3125 | 3267 |
time_t host_time; |
3126 | 3268 |
ret = get_errno(time(&host_time)); |
3127 |
if (!is_error(ret) && arg1) |
|
3128 |
tputl(arg1, host_time); |
|
3269 |
if (!is_error(ret) |
|
3270 |
&& arg1 |
|
3271 |
&& put_user_sal(host_time, arg1)) |
|
3272 |
goto efault; |
|
3129 | 3273 |
} |
3130 | 3274 |
break; |
3131 | 3275 |
#endif |
... | ... | |
3199 | 3343 |
case TARGET_NR_stime: |
3200 | 3344 |
{ |
3201 | 3345 |
time_t host_time; |
3202 |
host_time = tgetl(arg1); |
|
3346 |
if (get_user_sal(host_time, arg1)) |
|
3347 |
goto efault; |
|
3203 | 3348 |
ret = get_errno(stime(&host_time)); |
3204 | 3349 |
} |
3205 | 3350 |
break; |
... | ... | |
3358 | 3503 |
env->gpr[3][env->current_tc] = host_pipe[1]; |
3359 | 3504 |
ret = host_pipe[0]; |
3360 | 3505 |
#else |
3361 |
tput32(arg1, host_pipe[0]); |
|
3362 |
tput32(arg1 + 4, host_pipe[1]); |
|
3506 |
if (put_user_s32(host_pipe[0], arg1) |
|
3507 |
|| put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0]))) |
|
3508 |
goto efault; |
|
3363 | 3509 |
#endif |
3364 | 3510 |
} |
3365 | 3511 |
} |
... | ... | |
4267 | 4413 |
rusage_ptr = NULL; |
4268 | 4414 |
ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr)); |
4269 | 4415 |
if (!is_error(ret)) { |
4270 |
if (status_ptr) |
|
4271 |
tputl(status_ptr, status); |
|
4272 |
if (target_rusage) { |
|
4273 |
host_to_target_rusage(target_rusage, &rusage); |
|
4416 |
if (status_ptr) { |
|
4417 |
if (put_user_s32(status, status_ptr)) |
|
4418 |
goto efault; |
|
4274 | 4419 |
} |
4420 |
if (target_rusage) |
|
4421 |
host_to_target_rusage(target_rusage, &rusage); |
|
4275 | 4422 |
} |
4276 | 4423 |
} |
4277 | 4424 |
break; |
... | ... | |
4404 | 4551 |
{ |
4405 | 4552 |
#if defined (__x86_64__) |
4406 | 4553 |
ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5)); |
4407 |
tput64(arg4, ret); |
|
4554 |
if (put_user_s64(ret, arg4)) |
|
4555 |
goto efault; |
|
4408 | 4556 |
#else |
4409 | 4557 |
int64_t res; |
4410 | 4558 |
ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5)); |
4411 |
tput64(arg4, res); |
|
4559 |
if (put_user_s64(res, arg4)) |
|
4560 |
goto efault; |
|
4412 | 4561 |
#endif |
4413 | 4562 |
} |
4414 | 4563 |
break; |
... | ... | |
4674 | 4823 |
{ |
4675 | 4824 |
int deathsig; |
4676 | 4825 |
ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5)); |
4677 |
if (!is_error(ret) && arg2) |
|
4678 |
tput32(arg2, deathsig); |
|
4826 |
if (!is_error(ret) && arg2 |
|
4827 |
&& put_user_ual(deathsig, arg2)) |
|
4828 |
goto efault; |
|
4679 | 4829 |
} |
4680 | 4830 |
break; |
4681 | 4831 |
default: |
... | ... | |
4932 | 5082 |
uid_t ruid, euid, suid; |
4933 | 5083 |
ret = get_errno(getresuid(&ruid, &euid, &suid)); |
4934 | 5084 |
if (!is_error(ret)) { |
4935 |
tput16(arg1, tswap16(high2lowuid(ruid))); |
|
4936 |
tput16(arg2, tswap16(high2lowuid(euid))); |
|
4937 |
tput16(arg3, tswap16(high2lowuid(suid))); |
|
5085 |
if (put_user_u16(high2lowuid(ruid), arg1) |
|
5086 |
|| put_user_u16(high2lowuid(euid), arg2) |
|
5087 |
|| put_user_u16(high2lowuid(suid), arg3)) |
|
5088 |
goto efault; |
|
4938 | 5089 |
} |
4939 | 5090 |
} |
4940 | 5091 |
break; |
... | ... | |
4952 | 5103 |
gid_t rgid, egid, sgid; |
4953 | 5104 |
ret = get_errno(getresgid(&rgid, &egid, &sgid)); |
4954 | 5105 |
if (!is_error(ret)) { |
4955 |
tput16(arg1, tswap16(high2lowgid(rgid))); |
|
4956 |
tput16(arg2, tswap16(high2lowgid(egid))); |
|
4957 |
tput16(arg3, tswap16(high2lowgid(sgid))); |
|
5106 |
if (put_user_u16(high2lowgid(rgid), arg1) |
|
5107 |
|| put_user_u16(high2lowgid(egid), arg2) |
|
5108 |
|| put_user_u16(high2lowgid(sgid), arg3)) |
|
5109 |
goto efault; |
|
4958 | 5110 |
} |
4959 | 5111 |
} |
4960 | 5112 |
break; |
... | ... | |
5077 | 5229 |
uid_t ruid, euid, suid; |
5078 | 5230 |
ret = get_errno(getresuid(&ruid, &euid, &suid)); |
5079 | 5231 |
if (!is_error(ret)) { |
5080 |
tput32(arg1, tswap32(ruid)); |
|
5081 |
tput32(arg2, tswap32(euid)); |
|
5082 |
tput32(arg3, tswap32(suid)); |
|
5232 |
if (put_user_u32(ruid, arg1) |
|
5233 |
|| put_user_u32(euid, arg2) |
|
5234 |
|| put_user_u32(suid, arg3)) |
|
5235 |
goto efault; |
|
5083 | 5236 |
} |
5084 | 5237 |
} |
5085 | 5238 |
break; |
... | ... | |
5095 | 5248 |
gid_t rgid, egid, sgid; |
5096 | 5249 |
ret = get_errno(getresgid(&rgid, &egid, &sgid)); |
5097 | 5250 |
if (!is_error(ret)) { |
5098 |
tput32(arg1, tswap32(rgid)); |
|
5099 |
tput32(arg2, tswap32(egid)); |
|
5100 |
tput32(arg3, tswap32(sgid)); |
|
5251 |
if (put_user_u32(rgid, arg1) |
|
5252 |
|| put_user_u32(egid, arg2) |
|
5253 |
|| put_user_u32(sgid, arg3)) |
|
5254 |
goto efault; |
|
5101 | 5255 |
} |
5102 | 5256 |
} |
5103 | 5257 |
break; |
Also available in: Unified diff