From nobody Sat May 4 22:06:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=google.com ARC-Seal: i=1; a=rsa-sha256; t=1572389071; cv=none; d=zoho.com; s=zohoarc; b=PXH+TytRbHlD7hPD8umzLCPImwrNFewYtsomD+Uxxe3kKGlzjq2aTuVCdfCEc47cUy2kCw3wyFIXDPmQ4GKp2BvNuuzFa5pKs9g2X2Hzx4lzhQOsjQy+JbIxNfhKhN2bhKJ1fKWzxLxuwf697yuJJC3mlHEbPEqXmkC+haHk7sQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1572389071; h=Content-Type:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=A/zRoxcJ70AtPg9UKjvYmlWZ/iLXm2eSiY11LZdX2fQ=; b=dFT5p0ZDBwLcjmZV0gNOzQlwEbx0iOYdmTC2I3szsTW9bxlfK6eWb0MwhgluWy1oGuvlEe2M8waEL/niOHYoJb7YPSbND+9uhATta1n5kMy4nYMKqC+BgY2Ny6p6Ru8wcWxMijFaID3QfjoJNE4eNG7XUireiW0MILMdcm+kkdc= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 15723890711891013.7618451374315; Tue, 29 Oct 2019 15:44:31 -0700 (PDT) Received: from localhost ([::1]:34670 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iPaE2-0007V7-5T for importer@patchew.org; Tue, 29 Oct 2019 18:44:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56905) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from <3gsC4XQMKCtkEFUBJJBG9.7JHL9HP-89Q9GIJIBIP.JMB@flex--jkz.bounces.google.com>) id 1iPaCs-0006nB-9y for qemu-devel@nongnu.org; Tue, 29 Oct 2019 18:43:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from <3gsC4XQMKCtkEFUBJJBG9.7JHL9HP-89Q9GIJIBIP.JMB@flex--jkz.bounces.google.com>) id 1iPaCq-000814-RG for qemu-devel@nongnu.org; Tue, 29 Oct 2019 18:43:18 -0400 Received: from mail-pf1-x449.google.com ([2607:f8b0:4864:20::449]:38705) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from <3gsC4XQMKCtkEFUBJJBG9.7JHL9HP-89Q9GIJIBIP.JMB@flex--jkz.bounces.google.com>) id 1iPaCq-0007zB-Jf for qemu-devel@nongnu.org; Tue, 29 Oct 2019 18:43:16 -0400 Received: by mail-pf1-x449.google.com with SMTP id d126so105940pfd.5 for ; Tue, 29 Oct 2019 15:43:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to:cc; bh=A/zRoxcJ70AtPg9UKjvYmlWZ/iLXm2eSiY11LZdX2fQ=; b=OADnFkSzM+AaP45sOyfWcn2zrA+FIXo6oGvu1flE0cKhJBbJM3xs6p9K3onLM9YeoQ 4GhIyYtgOUkSqHMlCgRp6Q6hlxr97fXd5Pm18krt+z/hwEl0niyqZIDPIiLuC2JoHNmm ma9Pr9Dh/f3vU6LEGUyqwDXTkS3w0gGtuE4qEqd8ddwrA6b4ndOkYW//8sbjB3DHZMUG xeMxrUCIDDNLV3akAFZ9yeZgm9WBabh6dGQGyBJ1gwt+Xj6WtP/zqNqAykVqMrTj3Kja RHsYwCHs1MX8k3NDH4W8n38gQaf8AM3k23+ut6AAqGdGGrmYjpzjDbe0DS8/WrZ6eEN+ 0emQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc; bh=A/zRoxcJ70AtPg9UKjvYmlWZ/iLXm2eSiY11LZdX2fQ=; b=pR2LOusd6TA0qLID/n5OPjsXIuYXW5MUfQCEJCjA6o0+taAfoGDUc/n4iUGPVA+z0H Z6ZehdWIE9VQM+cnWIjCd9w1G95bwowTqSYDHvbkrYu1yi2XNfJ4WZjCtRRR0zI4wB+1 gbgjx4DS1cXlBFqc+WlULxWdXEDNCDPhqRTygmxnRgrR0zjDzysLqNrVCiH3n9Mo6/EX +abRdA3pGUSTUZQLXonl94xK6z0Y63BY1ANOUxC4kuCgMwMKPAOjKbP/IgWAI+rAPGv4 MSmy8UTGyfdok3Q0I94cVSNnB4G2EvejbV4r3Mb/zXe6N8WhshBuD+vSQtsrnoW4Jv0y v0mg== X-Gm-Message-State: APjAAAVbxPrimB4eY8l2zY23mAAdS3rP2XoKUDHAd5Bv+rMF08vssg7D 4ycjEZbTLGnez91GG7TRleEJHQrO1X1GubxQyvCNQFYYigCe4BmLnWY/ALNkJyK0omXdET9nYVm kSNsFDiaPA1v5yVmKfESRQnYDBKOQd2A3KgfwpdIsncqWuHTazk9n X-Google-Smtp-Source: APXvYqwZmKp434rx2dRdCN78kO8Ia/XAQkIH8AWwDE3Zs6+/0pjiKeL6VIlry/xiNPy2Rx0D8ep96h4= X-Received: by 2002:a63:5d04:: with SMTP id r4mr30143405pgb.22.1572388994492; Tue, 29 Oct 2019 15:43:14 -0700 (PDT) Date: Tue, 29 Oct 2019 15:43:10 -0700 Message-Id: <20191029224310.164025-1-jkz@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.24.0.rc0.303.g954a862665-goog Subject: [PATCH] linux-user: Support for NETLINK socket options From: Josh Kunz To: qemu-devel@nongnu.org Cc: riku.voipio@iki.fi, laurent@vivier.eu, Josh Kunz X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::449 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @google.com) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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. Signed-off-by: Josh Kunz --- linux-user/syscall.c | 98 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 530c843303..cbfb8380a9 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2247,6 +2247,38 @@ set_timeout: return -TARGET_EFAULT; ret =3D get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(va= l))); 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 >=3D KERNEL_VERSION(4, 2, 0) + case NETLINK_LISTEN_ALL_NSID: + case NETLINK_CAP_ACK: +#endif /* LINUX_VERSION_CODE >=3D KERNEL_VERSION(4, 2, 0) */ +#if LINUX_VERSION_CODE >=3D KERNEL_VERSION(4, 12, 0) + case NETLINK_EXT_ACK: +#endif /* LINUX_VERSION_CODE >=3D KERNEL_VERSION(4, 12, 0) */ +#if LINUX_VERSION_CODE >=3D KERNEL_VERSION(4, 20, 0) + case NETLINK_GET_STRICT_CHK: +#endif /* LINUX_VERSION_CODE >=3D KERNEL_VERSION(4, 12, 0) */ + break; + default: + goto unimplemented; + } + val =3D 0; + if (optlen < sizeof(uint32_t)) { + return -TARGET_EINVAL; + } + if (get_user_u32(val, optval_addr)) { + return -TARGET_EFAULT; + } + ret =3D get_errno(setsockopt(sockfd, SOL_NETLINK, optname, &val, s= izeof(val))); + break; +#endif /* SOL_NETLINK */ default: unimplemented: gemu_log("Unsupported setsockopt level=3D%d optname=3D%d\n", level= , optname); @@ -2531,6 +2563,72 @@ 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 >=3D KERNEL_VERSION(4, 2, 0) + case NETLINK_LISTEN_ALL_NSID: + case NETLINK_CAP_ACK: +#endif /* LINUX_VERSION_CODE >=3D KERNEL_VERSION(4, 2, 0) */ +#if LINUX_VERSION_CODE >=3D KERNEL_VERSION(4, 12, 0) + case NETLINK_EXT_ACK: +#endif /* LINUX_VERSION_CODE >=3D KERNEL_VERSION(4, 12, 0) */ +#if LINUX_VERSION_CODE >=3D KERNEL_VERSION(4, 20, 0) + case NETLINK_GET_STRICT_CHK: +#endif /* LINUX_VERSION_CODE >=3D KERNEL_VERSION(4, 12, 0) */ + if (get_user_u32(len, optlen)) { + return -TARGET_EFAULT; + } + if (len !=3D sizeof(val)) { + return -TARGET_EINVAL; + } + lv =3D len; + ret =3D 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 >=3D KERNEL_VERSION(4, 2, 0) + case NETLINK_LIST_MEMBERSHIPS: + { + if (get_user_u32(len, optlen)) { + return -TARGET_EFAULT; + } + if (len < 0) { + return -TARGET_EINVAL; + } + uint32_t *results =3D lock_user(VERIFY_WRITE, optval_addr, len= , 1); + if (!results) { + return -TARGET_EFAULT; + } + lv =3D len; + ret =3D 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 (int i =3D 0; i < (len / sizeof(uint32_t)); i++) { + results[i] =3D tswap32(results[i]); + } + if (put_user_u32(lv, optlen)) { + return -TARGET_EFAULT; + } + unlock_user(results, optval_addr, 0); + break; + } +#endif /* LINUX_VERSION_CODE >=3D KERNEL_VERSION(4, 2, 0) */ + default: + goto unimplemented; + } +#endif /* SOL_NETLINK */ default: unimplemented: gemu_log("getsockopt level=3D%d optname=3D%d not yet supported\n", --=20 2.24.0.rc0.303.g954a862665-goog