linux-user branch 20200714
Fix strace errno management Fix Coverity erros in ioctl straces Fix some netlinks errors Fix semtimedop -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEEzS913cjjpNwuT1Fz8ww4vT8vvjwFAl8NX2wSHGxhdXJlbnRA dml2aWVyLmV1AAoJEPMMOL0/L748v4YP+wZB0y354A6/wdXS+zHy2ErMsjXM9Whv f03klKvMPOK1BbNsdqDiEh1qzDZ96/yX2NshZPrsmCfNnAdWX93zINPvZaTKOIqk aNkQ2heQ4buA1/h2JZYZX2vEXE+2Ke4nHBNbE9/Q/T5KwlW7Z28e2x02lff+X0g3 /Ag6BVXHmnGb4T4WaB5PpCPNzb0EjXTWx5OTobbZOBLLmkOAB9ASDhHpPCmRqZVN pvHXhTZh2JkT0husLk58hpOc+ZDpOUsgV+8B58RHfQCb8Peu2dNIb6W/2qWOXVtb +TBxGhmzhDiVRJS4+pv94ATEwJsewyKmin4c043CVWDpQkn32YUHYoLIZjy4ShVh ZJW0QFsAwqpsFHuisiiRME87OKa4xnxpurTlCUWcq7nmmb9z5P50QCg74bD60EB5 BqNK2ypYRGQEKVVRa4317aP9MsZ2QXeCr0N8S6gX+RkIftc6YaLxYVNiZkspr1QR EMWlhqVGjNUGupQoHpsmb239GWHwyh2ZvXmxh/PT0XYA/3N1YLgOeLE6uPy0Gxxi MNhUJrtd0vOoXoxPnziNRlgkTpXeAzTvS1EtY/ssEisgLN9oSvOphwZrCbQlXhAu b8rnWwOjyU8qIjHOUEFuflsptn5Hob75pRUJhgt5EvqTlHqLp8Zt7R4aiQV/U71b 7QVxGPFjff8O =Zw5f -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-5.1-pull-request' into staging linux-user branch 20200714 Fix strace errno management Fix Coverity erros in ioctl straces Fix some netlinks errors Fix semtimedop # gpg: Signature made Tue 14 Jul 2020 08:31:56 BST # gpg: using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C # gpg: issuer "laurent@vivier.eu" # gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full] # gpg: aka "Laurent Vivier <laurent@vivier.eu>" [full] # gpg: aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full] # Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F 5173 F30C 38BD 3F2F BE3C * remotes/vivier2/tags/linux-user-for-5.1-pull-request: linux-user: fix print_syscall_err() when syscall returned value is negative linux-user: fix the errno value in print_syscall_err() linux-user: add netlink RTM_SETLINK command linux-user: add new netlink types linux-user: Fix Coverity CID 1430271 / CID 1430272 linux-user: refactor ipc syscall and support of semtimedop syscall linux-user: Use EPROTONOSUPPORT for unimplemented netlink protocols Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
8bfa25a46f
@ -133,6 +133,9 @@ enum {
|
||||
QEMU_IFLA_NEW_IFINDEX,
|
||||
QEMU_IFLA_MIN_MTU,
|
||||
QEMU_IFLA_MAX_MTU,
|
||||
QEMU_IFLA_PROP_LIST,
|
||||
QEMU_IFLA_ALT_IFNAME,
|
||||
QEMU_IFLA_PERM_ADDRESS,
|
||||
QEMU___IFLA_MAX
|
||||
};
|
||||
|
||||
@ -807,6 +810,7 @@ static abi_long host_to_target_data_link_rtattr(struct rtattr *rtattr)
|
||||
/* binary stream */
|
||||
case QEMU_IFLA_ADDRESS:
|
||||
case QEMU_IFLA_BROADCAST:
|
||||
case QEMU_IFLA_PERM_ADDRESS:
|
||||
/* string */
|
||||
case QEMU_IFLA_IFNAME:
|
||||
case QEMU_IFLA_QDISC:
|
||||
@ -1200,6 +1204,7 @@ static abi_long target_to_host_data_route(struct nlmsghdr *nlh)
|
||||
break;
|
||||
case RTM_NEWLINK:
|
||||
case RTM_DELLINK:
|
||||
case RTM_SETLINK:
|
||||
if (nlh->nlmsg_len >= NLMSG_LENGTH(sizeof(*ifi))) {
|
||||
ifi = NLMSG_DATA(nlh);
|
||||
ifi->ifi_type = tswap16(ifi->ifi_type);
|
||||
|
@ -724,19 +724,20 @@ print_ipc(const struct syscallname *name,
|
||||
* Variants for the return value output function
|
||||
*/
|
||||
|
||||
static void
|
||||
static bool
|
||||
print_syscall_err(abi_long ret)
|
||||
{
|
||||
const char *errstr = NULL;
|
||||
const char *errstr;
|
||||
|
||||
qemu_log(" = ");
|
||||
if (ret < 0) {
|
||||
qemu_log("-1 errno=%d", errno);
|
||||
errstr = target_strerror(-ret);
|
||||
if (errstr) {
|
||||
qemu_log(" (%s)", errstr);
|
||||
qemu_log("-1 errno=%d (%s)", (int)-ret, errstr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -744,11 +745,10 @@ print_syscall_ret_addr(const struct syscallname *name, abi_long ret,
|
||||
abi_long arg0, abi_long arg1, abi_long arg2,
|
||||
abi_long arg3, abi_long arg4, abi_long arg5)
|
||||
{
|
||||
print_syscall_err(ret);
|
||||
|
||||
if (ret >= 0) {
|
||||
qemu_log("0x" TARGET_ABI_FMT_lx "\n", ret);
|
||||
if (!print_syscall_err(ret)) {
|
||||
qemu_log("0x" TARGET_ABI_FMT_lx, ret);
|
||||
}
|
||||
qemu_log("\n");
|
||||
}
|
||||
|
||||
#if 0 /* currently unused */
|
||||
@ -765,9 +765,7 @@ print_syscall_ret_newselect(const struct syscallname *name, abi_long ret,
|
||||
abi_long arg0, abi_long arg1, abi_long arg2,
|
||||
abi_long arg3, abi_long arg4, abi_long arg5)
|
||||
{
|
||||
print_syscall_err(ret);
|
||||
|
||||
if (ret >= 0) {
|
||||
if (!print_syscall_err(ret)) {
|
||||
qemu_log(" = 0x" TARGET_ABI_FMT_lx " (", ret);
|
||||
print_fdset(arg0, arg1);
|
||||
qemu_log(",");
|
||||
@ -796,9 +794,7 @@ print_syscall_ret_adjtimex(const struct syscallname *name, abi_long ret,
|
||||
abi_long arg0, abi_long arg1, abi_long arg2,
|
||||
abi_long arg3, abi_long arg4, abi_long arg5)
|
||||
{
|
||||
print_syscall_err(ret);
|
||||
|
||||
if (ret >= 0) {
|
||||
if (!print_syscall_err(ret)) {
|
||||
qemu_log(TARGET_ABI_FMT_ld, ret);
|
||||
switch (ret) {
|
||||
case TARGET_TIME_OK:
|
||||
@ -833,9 +829,7 @@ print_syscall_ret_listxattr(const struct syscallname *name, abi_long ret,
|
||||
abi_long arg0, abi_long arg1, abi_long arg2,
|
||||
abi_long arg3, abi_long arg4, abi_long arg5)
|
||||
{
|
||||
print_syscall_err(ret);
|
||||
|
||||
if (ret >= 0) {
|
||||
if (!print_syscall_err(ret)) {
|
||||
qemu_log(TARGET_ABI_FMT_ld, ret);
|
||||
qemu_log(" (list = ");
|
||||
if (arg1 != 0) {
|
||||
@ -866,9 +860,7 @@ print_syscall_ret_ioctl(const struct syscallname *name, abi_long ret,
|
||||
abi_long arg0, abi_long arg1, abi_long arg2,
|
||||
abi_long arg3, abi_long arg4, abi_long arg5)
|
||||
{
|
||||
print_syscall_err(ret);
|
||||
|
||||
if (ret >= 0) {
|
||||
if (!print_syscall_err(ret)) {
|
||||
qemu_log(TARGET_ABI_FMT_ld, ret);
|
||||
|
||||
const IOCTLEntry *ie;
|
||||
@ -889,8 +881,12 @@ print_syscall_ret_ioctl(const struct syscallname *name, abi_long ret,
|
||||
arg_type++;
|
||||
target_size = thunk_type_size(arg_type, 0);
|
||||
argptr = lock_user(VERIFY_READ, arg2, target_size, 1);
|
||||
thunk_print(argptr, arg_type);
|
||||
unlock_user(argptr, arg2, target_size);
|
||||
if (argptr) {
|
||||
thunk_print(argptr, arg_type);
|
||||
unlock_user(argptr, arg2, target_size);
|
||||
} else {
|
||||
print_pointer(arg2, 1);
|
||||
}
|
||||
qemu_log(")");
|
||||
}
|
||||
}
|
||||
@ -3119,8 +3115,12 @@ print_ioctl(const struct syscallname *name,
|
||||
arg_type++;
|
||||
target_size = thunk_type_size(arg_type, 0);
|
||||
argptr = lock_user(VERIFY_READ, arg2, target_size, 1);
|
||||
thunk_print(argptr, arg_type);
|
||||
unlock_user(argptr, arg2, target_size);
|
||||
if (argptr) {
|
||||
thunk_print(argptr, arg_type);
|
||||
unlock_user(argptr, arg2, target_size);
|
||||
} else {
|
||||
print_pointer(arg2, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -3189,9 +3189,7 @@ print_syscall_ret(int num, abi_long ret,
|
||||
arg1, arg2, arg3,
|
||||
arg4, arg5, arg6);
|
||||
} else {
|
||||
print_syscall_err(ret);
|
||||
|
||||
if (ret >= 0) {
|
||||
if (!print_syscall_err(ret)) {
|
||||
qemu_log(TARGET_ABI_FMT_ld, ret);
|
||||
}
|
||||
qemu_log("\n");
|
||||
|
@ -817,9 +817,14 @@ safe_syscall4(int, clock_nanosleep, const clockid_t, clock, int, flags,
|
||||
const struct timespec *, req, struct timespec *, rem)
|
||||
#endif
|
||||
#ifdef __NR_ipc
|
||||
#ifdef __s390x__
|
||||
safe_syscall5(int, ipc, int, call, long, first, long, second, long, third,
|
||||
void *, ptr)
|
||||
#else
|
||||
safe_syscall6(int, ipc, int, call, long, first, long, second, long, third,
|
||||
void *, ptr, long, fifth)
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __NR_msgsnd
|
||||
safe_syscall4(int, msgsnd, int, msgid, const void *, msgp, size_t, sz,
|
||||
int, flags)
|
||||
@ -1230,7 +1235,8 @@ static inline abi_long copy_to_user_timeval64(abi_ulong target_tv_addr,
|
||||
defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6) || \
|
||||
defined(TARGET_NR_nanosleep) || defined(TARGET_NR_clock_settime) || \
|
||||
defined(TARGET_NR_utimensat) || defined(TARGET_NR_mq_timedsend) || \
|
||||
defined(TARGET_NR_mq_timedreceive)
|
||||
defined(TARGET_NR_mq_timedreceive) || defined(TARGET_NR_ipc) || \
|
||||
defined(TARGET_NR_semop) || defined(TARGET_NR_semtimedop)
|
||||
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
|
||||
abi_ulong target_addr)
|
||||
{
|
||||
@ -2990,7 +2996,7 @@ static abi_long do_socket(int domain, int type, int protocol)
|
||||
#endif
|
||||
protocol == NETLINK_KOBJECT_UEVENT ||
|
||||
protocol == NETLINK_AUDIT)) {
|
||||
return -TARGET_EPFNOSUPPORT;
|
||||
return -TARGET_EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
if (domain == AF_PACKET ||
|
||||
@ -3878,25 +3884,53 @@ static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
|
||||
#if defined(TARGET_NR_ipc) || defined(TARGET_NR_semop) || \
|
||||
defined(TARGET_NR_semtimedop)
|
||||
|
||||
/*
|
||||
* This macro is required to handle the s390 variants, which passes the
|
||||
* arguments in a different order than default.
|
||||
*/
|
||||
#ifdef __s390x__
|
||||
#define SEMTIMEDOP_IPC_ARGS(__nsops, __sops, __timeout) \
|
||||
(__nsops), (__timeout), (__sops)
|
||||
#else
|
||||
#define SEMTIMEDOP_IPC_ARGS(__nsops, __sops, __timeout) \
|
||||
(__nsops), 0, (__sops), (__timeout)
|
||||
#endif
|
||||
|
||||
static inline abi_long do_semtimedop(int semid,
|
||||
abi_long ptr,
|
||||
unsigned nsops,
|
||||
abi_long timeout)
|
||||
{
|
||||
struct sembuf sops[nsops];
|
||||
struct timespec ts, *pts = NULL;
|
||||
abi_long ret;
|
||||
|
||||
if (timeout) {
|
||||
pts = &ts;
|
||||
if (target_to_host_timespec(pts, timeout)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
if (target_to_host_sembuf(sops, ptr, nsops))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
ret = -TARGET_ENOSYS;
|
||||
#ifdef __NR_semtimedop
|
||||
ret = get_errno(safe_semtimedop(semid, sops, nsops, NULL));
|
||||
ret = get_errno(safe_semtimedop(semid, sops, nsops, pts));
|
||||
#endif
|
||||
#ifdef __NR_ipc
|
||||
if (ret == -TARGET_ENOSYS) {
|
||||
ret = get_errno(safe_ipc(IPCOP_semtimedop, semid, nsops, 0, sops, 0));
|
||||
ret = get_errno(safe_ipc(IPCOP_semtimedop, semid,
|
||||
SEMTIMEDOP_IPC_ARGS(nsops, sops, (long)pts)));
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct target_msqid_ds
|
||||
{
|
||||
@ -4056,8 +4090,13 @@ static inline abi_long do_msgsnd(int msqid, abi_long msgp,
|
||||
#endif
|
||||
#ifdef __NR_ipc
|
||||
if (ret == -TARGET_ENOSYS) {
|
||||
#ifdef __s390x__
|
||||
ret = get_errno(safe_ipc(IPCOP_msgsnd, msqid, msgsz, msgflg,
|
||||
host_mb));
|
||||
#else
|
||||
ret = get_errno(safe_ipc(IPCOP_msgsnd, msqid, msgsz, msgflg,
|
||||
host_mb, 0));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
g_free(host_mb);
|
||||
@ -4066,6 +4105,20 @@ static inline abi_long do_msgsnd(int msqid, abi_long msgp,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef __NR_ipc
|
||||
#if defined(__sparc__)
|
||||
/* SPARC for msgrcv it does not use the kludge on final 2 arguments. */
|
||||
#define MSGRCV_ARGS(__msgp, __msgtyp) __msgp, __msgtyp
|
||||
#elif defined(__s390x__)
|
||||
/* The s390 sys_ipc variant has only five parameters. */
|
||||
#define MSGRCV_ARGS(__msgp, __msgtyp) \
|
||||
((long int[]){(long int)__msgp, __msgtyp})
|
||||
#else
|
||||
#define MSGRCV_ARGS(__msgp, __msgtyp) \
|
||||
((long int[]){(long int)__msgp, __msgtyp}), 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
|
||||
ssize_t msgsz, abi_long msgtyp,
|
||||
int msgflg)
|
||||
@ -4094,7 +4147,7 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp,
|
||||
#ifdef __NR_ipc
|
||||
if (ret == -TARGET_ENOSYS) {
|
||||
ret = get_errno(safe_ipc(IPCOP_CALL(1, IPCOP_msgrcv), msqid, msgsz,
|
||||
msgflg, host_mb, msgtyp));
|
||||
msgflg, MSGRCV_ARGS(host_mb, msgtyp)));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -4372,7 +4425,20 @@ static abi_long do_ipc(CPUArchState *cpu_env,
|
||||
|
||||
switch (call) {
|
||||
case IPCOP_semop:
|
||||
ret = do_semop(first, ptr, second);
|
||||
ret = do_semtimedop(first, ptr, second, 0);
|
||||
break;
|
||||
case IPCOP_semtimedop:
|
||||
/*
|
||||
* The s390 sys_ipc variant has only five parameters instead of six
|
||||
* (as for default variant) and the only difference is the handling of
|
||||
* SEMTIMEDOP where on s390 the third parameter is used as a pointer
|
||||
* to a struct timespec where the generic variant uses fifth parameter.
|
||||
*/
|
||||
#if defined(TARGET_S390X)
|
||||
ret = do_semtimedop(first, ptr, second, third);
|
||||
#else
|
||||
ret = do_semtimedop(first, ptr, second, fifth);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case IPCOP_semget:
|
||||
@ -9684,7 +9750,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
|
||||
#endif
|
||||
#ifdef TARGET_NR_semop
|
||||
case TARGET_NR_semop:
|
||||
return do_semop(arg1, arg2, arg3);
|
||||
return do_semtimedop(arg1, arg2, arg3, 0);
|
||||
#endif
|
||||
#ifdef TARGET_NR_semtimedop
|
||||
case TARGET_NR_semtimedop:
|
||||
return do_semtimedop(arg1, arg2, arg3, arg4);
|
||||
#endif
|
||||
#ifdef TARGET_NR_semctl
|
||||
case TARGET_NR_semctl:
|
||||
|
Loading…
Reference in New Issue
Block a user