Le 12/11/2019 à 11:11, Peter Maydell a écrit : > On Wed, 6 Nov 2019 at 13:07, Laurent Vivier <laur...@vivier.eu> wrote: >> >> From: Josh Kunz <j...@google.com> >> >> This change includes support for all AF_NETLINK socket options up to about >> kernel version 5.4 (5.4 is not formally released at the time of writing). >> Socket options that were introduced in kernel versions before the oldest >> currently stable kernel version are guarded by kernel version macros. >> >> This change has been built under gcc 8.3, and clang 9.0, and it passes >> `make check`. The netlink options have been tested by emulating some >> non-trival software that uses NETLINK socket options, but they have >> not been exaustively verified. > > Hi; Coverity reports a missing-break-in-switch error for > this commit (CID 1407221): > >> diff --git a/linux-user/syscall.c b/linux-user/syscall.c >> index f6751eecb78c..247883292ce5 100644 >> --- a/linux-user/syscall.c >> +++ b/linux-user/syscall.c >> @@ -2248,6 +2248,39 @@ set_timeout: >> return -TARGET_EFAULT; >> ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, >> sizeof(val))); >> break; >> +#ifdef SOL_NETLINK >> + case SOL_NETLINK: >> + switch (optname) { >> + case NETLINK_PKTINFO: >> + case NETLINK_ADD_MEMBERSHIP: >> + case NETLINK_DROP_MEMBERSHIP: >> + case NETLINK_BROADCAST_ERROR: >> + case NETLINK_NO_ENOBUFS: >> +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) >> + case NETLINK_LISTEN_ALL_NSID: >> + case NETLINK_CAP_ACK: >> +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) */ >> +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) >> + case NETLINK_EXT_ACK: >> +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) */ >> +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) >> + case NETLINK_GET_STRICT_CHK: >> +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) */ >> + break; >> + default: >> + goto unimplemented; >> + } >> + val = 0; >> + if (optlen < sizeof(uint32_t)) { >> + return -TARGET_EINVAL; >> + } >> + if (get_user_u32(val, optval_addr)) { >> + return -TARGET_EFAULT; >> + } >> + ret = get_errno(setsockopt(sockfd, SOL_NETLINK, optname, &val, >> + sizeof(val))); >> + break; >> +#endif /* SOL_NETLINK */ >> default: >> unimplemented: >> gemu_log("Unsupported setsockopt level=%d optname=%d\n", level, >> optname); >> @@ -2532,6 +2565,74 @@ static abi_long do_getsockopt(int sockfd, int level, >> int optname, >> break; >> } >> break; >> +#ifdef SOL_NETLINK >> + case SOL_NETLINK: >> + switch (optname) { >> + case NETLINK_PKTINFO: >> + case NETLINK_BROADCAST_ERROR: >> + case NETLINK_NO_ENOBUFS: >> +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) >> + case NETLINK_LISTEN_ALL_NSID: >> + case NETLINK_CAP_ACK: >> +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) */ >> +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) >> + case NETLINK_EXT_ACK: >> +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) */ >> +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) >> + case NETLINK_GET_STRICT_CHK: >> +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) */ >> + if (get_user_u32(len, optlen)) { >> + return -TARGET_EFAULT; >> + } >> + if (len != sizeof(val)) { >> + return -TARGET_EINVAL; >> + } >> + lv = len; >> + ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv)); >> + if (ret < 0) { >> + return ret; >> + } >> + if (put_user_u32(lv, optlen) >> + || put_user_u32(val, optval_addr)) { >> + return -TARGET_EFAULT; >> + } >> + break; >> +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) >> + case NETLINK_LIST_MEMBERSHIPS: >> + { >> + uint32_t *results; >> + int i; >> + if (get_user_u32(len, optlen)) { >> + return -TARGET_EFAULT; >> + } >> + if (len < 0) { >> + return -TARGET_EINVAL; >> + } >> + results = lock_user(VERIFY_WRITE, optval_addr, len, 1); >> + if (!results) { >> + return -TARGET_EFAULT; >> + } >> + lv = len; >> + ret = get_errno(getsockopt(sockfd, level, optname, results, >> &lv)); >> + if (ret < 0) { >> + unlock_user(results, optval_addr, 0); >> + return ret; >> + } >> + /* swap host endianess to target endianess. */ >> + for (i = 0; i < (len / sizeof(uint32_t)); i++) { >> + results[i] = tswap32(results[i]); >> + } >> + if (put_user_u32(lv, optlen)) { >> + return -TARGET_EFAULT; >> + } >> + unlock_user(results, optval_addr, 0); >> + break; >> + } >> +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) */ >> + default: >> + goto unimplemented; >> + } >> +#endif /* SOL_NETLINK */ > > Here at the end of the 'case SOL_NETLINK' we will just > fall straight through into 'default:'. Missing 'break' ?
Yes, missing 'break'. I'm going to send a patch to fix that. Thanks, Laurent