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' ? > default: > unimplemented: > gemu_log("getsockopt level=%d optname=%d not yet supported\n", > -- > 2.21.0 thanks -- PMM