From patchwork Wed Dec 7 15:53:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Junxiao Shi X-Patchwork-Id: 120534 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id BD781A00C3; Wed, 7 Dec 2022 18:49:00 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 881E342D1D; Wed, 7 Dec 2022 18:48:57 +0100 (CET) Received: from mail-oi1-f228.google.com (mail-oi1-f228.google.com [209.85.167.228]) by mails.dpdk.org (Postfix) with ESMTP id A0C6C410D7 for ; Wed, 7 Dec 2022 18:48:55 +0100 (CET) Received: by mail-oi1-f228.google.com with SMTP id t62so21516115oib.12 for ; Wed, 07 Dec 2022 09:48:55 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=message-id:to:subject:date:from:references:in-reply-to :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Rp54y+jRnrks1I9wT80iy7BiWruWTwuDDXwWZvzDb1Y=; b=M2CkChCkqe/X0jk18gVIVfEbG3Hqagojch6Iz9iVreq+CsqiBbRe9Ufqpvou0BSZ2A 8RZDxjbgD+HoO9ba+/L77/eP9w+T3F45j7+IAyfh/LSNGwvTzX0/xejJnH/h7IYOPb95 TxQdjRWpH3bxNaWlgO+90HNY/ixtgxqWyUbYGYCv0m4ohrQ2xmaC28lzi7+1OvhK1p3v R28CVEw6yxBDbM1sWFSdln1m18drgTMBJkXCcEYyk9bJBPOYOCMr+KKZNMR3A/Txs+Aa WLA/XhcCxxcJhZMKifeDJDW/V/ki6uiu3urw79mZMqr17gQ70gjDsW2kf5udA8p/HFE/ lb5A== X-Gm-Message-State: ANoB5plA9Axna/bhTmOW5N2tZa7TrXKu2YurbbLR97NVHq7115N9Xtg+ cg/qfWiShDxxc1EmM1pvq1Kbe/v5YFvEvbp8GwTEnR2wq5EmYQ== X-Google-Smtp-Source: AA0mqf5UuaMVpOp0GV6F89QuAdsuaVn3nk/3ZSQT7+HMZzSJ8/sZ98Eqs+Oie9M8lIoR8yvOLkIE7I28+XDm X-Received: by 2002:a05:6808:604:b0:35c:4d13:fbd with SMTP id y4-20020a056808060400b0035c4d130fbdmr6109016oih.19.1670435334726; Wed, 07 Dec 2022 09:48:54 -0800 (PST) Received: from enviro1.cs.arizona.edu (enviro1.cs.arizona.edu. [192.12.69.240]) by smtp-relay.gmail.com with ESMTPS id z1-20020a9d62c1000000b00670583602c9sm378187otk.3.2022.12.07.09.48.54 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Dec 2022 09:48:54 -0800 (PST) X-Relaying-Domain: cs.arizona.edu Received: from cs.arizona.edu (lectura.cs.arizona.edu [192.12.69.186]) by enviro1.cs.arizona.edu (Postfix) with ESMTPS id F2F37801C5 for ; Wed, 7 Dec 2022 10:48:53 -0700 (MST) Received: from localhost (cs.arizona.edu [local]) by cs.arizona.edu (OpenSMTPD) with ESMTPA id c21aaae6 for ; Wed, 7 Dec 2022 17:48:53 +0000 (UTC) In-Reply-To: References: From: Junxiao Shi Date: Wed, 7 Dec 2022 15:53:27 +0000 Subject: [PATCH v3] net/memif: change socket listener owner uid/gid To: dev@dpdk.org Message-ID: X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org This allows a DPDK application running with root privilege to create a memif socket listener with non-root owner uid and gid, which can be connected from client applications running without root privilege. Signed-off-by: Junxiao Shi Acked-by: Stephen Hemminger Acked-by: Ferruh Yigit Acked-by: Stephen Hemminger Acked-by: Ferruh Yigit --- doc/guides/nics/memif.rst | 2 ++ drivers/net/memif/memif_socket.c | 13 +++++++-- drivers/net/memif/rte_eth_memif.c | 48 +++++++++++++++++++++++++++++-- drivers/net/memif/rte_eth_memif.h | 2 ++ 4 files changed, 60 insertions(+), 5 deletions(-) diff --git a/doc/guides/nics/memif.rst b/doc/guides/nics/memif.rst index aca843640b..afc574fdaa 100644 --- a/doc/guides/nics/memif.rst +++ b/doc/guides/nics/memif.rst @@ -44,6 +44,8 @@ client. "rsize=11", "Log2 of ring size. If rsize is 10, actual ring size is 1024", "10", "1-14" "socket=/tmp/memif.sock", "Socket filename", "/tmp/memif.sock", "string len 108" "socket-abstract=no", "Set usage of abstract socket address", "yes", "yes|no" + "owner-uid=1000", "Set socket listener owner uid. Only relevant to server with socket-abstract=no", "unchanged", "uid_t" + "owner-gid=1000", "Set socket listener owner gid. Only relevant to server with socket-abstract=no", "unchanged", "gid_t" "mac=01:23:45:ab:cd:ef", "Mac address", "01:ab:23:cd:45:ef", "" "secret=abc123", "Secret is an optional security option, which if specified, must be matched by peer", "", "string len 24" "zero-copy=yes", "Enable/disable zero-copy client mode. Only relevant to client, requires '--single-file-segments' eal argument", "no", "yes|no" diff --git a/drivers/net/memif/memif_socket.c b/drivers/net/memif/memif_socket.c index 4700ce2e77..649f8d0e61 100644 --- a/drivers/net/memif/memif_socket.c +++ b/drivers/net/memif/memif_socket.c @@ -889,7 +889,7 @@ memif_listener_handler(void *arg) } static struct memif_socket * -memif_socket_create(char *key, uint8_t listener, bool is_abstract) +memif_socket_create(char *key, uint8_t listener, bool is_abstract, uid_t owner_uid, gid_t owner_gid) { struct memif_socket *sock; struct sockaddr_un un = { 0 }; @@ -941,6 +941,14 @@ memif_socket_create(char *key, uint8_t listener, bool is_abstract) MIF_LOG(DEBUG, "Memif listener socket %s created.", sock->filename); + if (!is_abstract && (owner_uid != (uid_t)-1 || owner_gid != (gid_t)-1)) { + ret = chown(sock->filename, owner_uid, owner_gid); + if (ret < 0) { + MIF_LOG(ERR, "Failed to change listener socket owner"); + goto error; + } + } + /* Allocate interrupt instance */ sock->intr_handle = rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_SHARED); @@ -1017,7 +1025,8 @@ memif_socket_init(struct rte_eth_dev *dev, const char *socket_filename) if (ret < 0) { socket = memif_socket_create(key, (pmd->role == MEMIF_ROLE_CLIENT) ? 0 : 1, - pmd->flags & ETH_MEMIF_FLAG_SOCKET_ABSTRACT); + pmd->flags & ETH_MEMIF_FLAG_SOCKET_ABSTRACT, + pmd->owner_uid, pmd->owner_gid); if (socket == NULL) return -1; ret = rte_hash_add_key_data(hash, key, socket); diff --git a/drivers/net/memif/rte_eth_memif.c b/drivers/net/memif/rte_eth_memif.c index 1b1c1a652b..f82f4bccb8 100644 --- a/drivers/net/memif/rte_eth_memif.c +++ b/drivers/net/memif/rte_eth_memif.c @@ -37,6 +37,8 @@ #define ETH_MEMIF_RING_SIZE_ARG "rsize" #define ETH_MEMIF_SOCKET_ARG "socket" #define ETH_MEMIF_SOCKET_ABSTRACT_ARG "socket-abstract" +#define ETH_MEMIF_OWNER_UID_ARG "owner-uid" +#define ETH_MEMIF_OWNER_GID_ARG "owner-gid" #define ETH_MEMIF_MAC_ARG "mac" #define ETH_MEMIF_ZC_ARG "zero-copy" #define ETH_MEMIF_SECRET_ARG "secret" @@ -48,6 +50,8 @@ static const char * const valid_arguments[] = { ETH_MEMIF_RING_SIZE_ARG, ETH_MEMIF_SOCKET_ARG, ETH_MEMIF_SOCKET_ABSTRACT_ARG, + ETH_MEMIF_OWNER_UID_ARG, + ETH_MEMIF_OWNER_GID_ARG, ETH_MEMIF_MAC_ARG, ETH_MEMIF_ZC_ARG, ETH_MEMIF_SECRET_ARG, @@ -1515,7 +1519,7 @@ static const struct eth_dev_ops ops = { static int memif_create(struct rte_vdev_device *vdev, enum memif_role_t role, memif_interface_id_t id, uint32_t flags, - const char *socket_filename, + const char *socket_filename, uid_t owner_uid, gid_t owner_gid, memif_log2_ring_size_t log2_ring_size, uint16_t pkt_buffer_size, const char *secret, struct rte_ether_addr *ether_addr) @@ -1554,6 +1558,8 @@ memif_create(struct rte_vdev_device *vdev, enum memif_role_t role, /* Zero-copy flag irelevant to server. */ if (pmd->role == MEMIF_ROLE_SERVER) pmd->flags &= ~ETH_MEMIF_FLAG_ZERO_COPY; + pmd->owner_uid = owner_uid; + pmd->owner_gid = owner_gid; ret = memif_socket_init(eth_dev, socket_filename); if (ret < 0) @@ -1740,6 +1746,30 @@ memif_set_is_socket_abstract(const char *key __rte_unused, const char *value, vo return 0; } +static int +memif_set_owner(const char *key, const char *value, void *extra_args) +{ + RTE_ASSERT(sizeof(uid_t) == sizeof(uint32_t)); + RTE_ASSERT(sizeof(gid_t) == sizeof(uint32_t)); + + unsigned long val; + char *end = NULL; + uint32_t *id = (uint32_t *)extra_args; + + val = strtoul(value, &end, 10); + if (*value == '\0' || *end != '\0') { + MIF_LOG(ERR, "Failed to parse %s: %s.", key, value); + return -EINVAL; + } + if (val >= UINT32_MAX) { + MIF_LOG(ERR, "Invalid %s: %s.", key, value); + return -ERANGE; + } + + *id = val; + return 0; +} + static int memif_set_mac(const char *key __rte_unused, const char *value, void *extra_args) { @@ -1772,6 +1802,8 @@ rte_pmd_memif_probe(struct rte_vdev_device *vdev) uint16_t pkt_buffer_size = ETH_MEMIF_DEFAULT_PKT_BUFFER_SIZE; memif_log2_ring_size_t log2_ring_size = ETH_MEMIF_DEFAULT_RING_SIZE; const char *socket_filename = ETH_MEMIF_DEFAULT_SOCKET_FILENAME; + uid_t owner_uid = -1; + gid_t owner_gid = -1; uint32_t flags = 0; const char *secret = NULL; struct rte_ether_addr *ether_addr = rte_zmalloc("", @@ -1855,6 +1887,14 @@ rte_pmd_memif_probe(struct rte_vdev_device *vdev) &memif_set_is_socket_abstract, &flags); if (ret < 0) goto exit; + ret = rte_kvargs_process(kvlist, ETH_MEMIF_OWNER_UID_ARG, + &memif_set_owner, &owner_uid); + if (ret < 0) + goto exit; + ret = rte_kvargs_process(kvlist, ETH_MEMIF_OWNER_GID_ARG, + &memif_set_owner, &owner_gid); + if (ret < 0) + goto exit; ret = rte_kvargs_process(kvlist, ETH_MEMIF_MAC_ARG, &memif_set_mac, ether_addr); if (ret < 0) @@ -1876,7 +1916,7 @@ rte_pmd_memif_probe(struct rte_vdev_device *vdev) } /* create interface */ - ret = memif_create(vdev, role, id, flags, socket_filename, + ret = memif_create(vdev, role, id, flags, socket_filename, owner_uid, owner_gid, log2_ring_size, pkt_buffer_size, secret, ether_addr); exit: @@ -1909,7 +1949,9 @@ RTE_PMD_REGISTER_PARAM_STRING(net_memif, ETH_MEMIF_PKT_BUFFER_SIZE_ARG "=" ETH_MEMIF_RING_SIZE_ARG "=" ETH_MEMIF_SOCKET_ARG "=" - ETH_MEMIF_SOCKET_ABSTRACT_ARG "=yes|no" + ETH_MEMIF_SOCKET_ABSTRACT_ARG "=yes|no" + ETH_MEMIF_OWNER_UID_ARG "=" + ETH_MEMIF_OWNER_GID_ARG "=" ETH_MEMIF_MAC_ARG "=xx:xx:xx:xx:xx:xx" ETH_MEMIF_ZC_ARG "=yes|no" ETH_MEMIF_SECRET_ARG "="); diff --git a/drivers/net/memif/rte_eth_memif.h b/drivers/net/memif/rte_eth_memif.h index eb692aee68..6ab7b967a5 100644 --- a/drivers/net/memif/rte_eth_memif.h +++ b/drivers/net/memif/rte_eth_memif.h @@ -89,6 +89,8 @@ struct pmd_internals { /**< use abstract socket address */ char *socket_filename; /**< pointer to socket filename */ + uid_t owner_uid; /**< socket owner uid */ + gid_t owner_gid; /**< socket owner gid */ char secret[ETH_MEMIF_SECRET_SIZE]; /**< secret (optional security parameter) */ struct memif_control_channel *cc; /**< control channel */