From patchwork Mon Jan 9 01:52:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ashish Sadanandan X-Patchwork-Id: 121701 X-Patchwork-Delegate: david.marchand@redhat.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 5F0EA42375; Mon, 9 Jan 2023 02:52:48 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id CD51740F16; Mon, 9 Jan 2023 02:52:47 +0100 (CET) Received: from mail-pj1-f45.google.com (mail-pj1-f45.google.com [209.85.216.45]) by mails.dpdk.org (Postfix) with ESMTP id D69344067C; Mon, 9 Jan 2023 02:52:45 +0100 (CET) Received: by mail-pj1-f45.google.com with SMTP id n12so7289341pjp.1; Sun, 08 Jan 2023 17:52:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=A4wYdD6nZ0KYfJAb1chHbIs09SzFpNQ/ERx5d9j7fqQ=; b=affwxl3USCgeNSoDKC0BBeEcQ5UA7P3E9TZNZ904Wt3Y8oWxRzisCNrlwSwXQDTu3c 1aqsIqz1dLB4yT8Xu8Ef49ZiV/DeKGqONv/u1dBu4pZUv+gw5bS1+igfVDWI7wwnh2+g AgrulSYjtFN7ZuDVxwi1aRVqkMXbYHP7SKjb/FDjGf7YkpZwjvDecuVQecLqBJG1sDbb NN0o5ZBNcy5YhhwN9CTOoFazh3J5pHXCWsu+ZPSzUG/uLxsYX6P7RDKQS+XAuKceNBgm jdQ82D/K0jYzGs4TrdmMqNz60LFZl0XR3SNz+1fh8HobgV/eoh6qkflLygKxRjGrUrBf guxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=A4wYdD6nZ0KYfJAb1chHbIs09SzFpNQ/ERx5d9j7fqQ=; b=45qofYGABgDrKeSEBy31dx/pBADrcYGdBpYmJGxfszrW4+InBihgr6lI0KFjIp8g1i 9z+WPKTQQZlGk5zVrOfuIZFYKFixsh0yo/RsYv1uVoFiZeiXE0cBDMTquOVES1lfYdbK JybJdhGwJ4W6TpmED9sD01WmivCw25fo2RNuNtXh+X4ymO1OjV5D0qGbUWq6FY0BdExc Xx9uzMmHyqAHZr6AaYDExhNvIzLCMqGbnswGDlWvi2oMjIFXeq3Pn/0Zc8AmAOxKJ4Cg Kcrqo22HZdIR1PRRKH50sMJBr+is7Fvr8UQnXZLg9aU8JkbURW6cEWkxvYh/49TgIwai BjCA== X-Gm-Message-State: AFqh2krfvNzvtTJP1Hv90ZVKZTPgzVT7niHQXbL/s92qqoi+KC7tOxGu EUUDC7AV+2GDL9LZTFaoaT1b7HuWZfluhq8F X-Google-Smtp-Source: AMrXdXveSj8b5tGonhNfDdTqnrhMM5YHGMKpPgWuKFU1yvecHBNXu0LwBNHYLab7UoQWGmMTYho5ng== X-Received: by 2002:a17:903:410c:b0:193:3171:542c with SMTP id r12-20020a170903410c00b001933171542cmr2158553pld.2.1673229164452; Sun, 08 Jan 2023 17:52:44 -0800 (PST) Received: from tbs-1052-sim.qualcomm.com (i-global254.qualcomm.com. [199.106.103.254]) by smtp.gmail.com with ESMTPSA id y12-20020a17090322cc00b001896af10ca7sm4742113plg.134.2023.01.08.17.52.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Jan 2023 17:52:43 -0800 (PST) From: Ashish Sadanandan To: dev@dpdk.org Cc: Ashish Sadanandan , john.levon@nutanix.com, stable@dpdk.org Subject: [PATCH v4 1/1] eal/linux: reject mountpt not parent of --huge-dir Date: Sun, 8 Jan 2023 18:52:39 -0700 Message-Id: <20230109015239.3956876-1-ashish.sadanandan@gmail.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20230103185732.2007210-1-ashish.sadanandan@gmail.com> References: <20230103185732.2007210-1-ashish.sadanandan@gmail.com> MIME-Version: 1.0 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 The code added for allowing --huge-dir to specify hugetlbfs sub-directories has a bug where it incorrectly matches mounts that contain a prefix of the specified --huge-dir. Consider --huge-dir=/dev/hugepages1G is passed to rte_eal_init. Given the following hugetlbfs mounts $ mount | grep hugetlbfs hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime,pagesize=2M) hugetlbfs on /dev/hugepages1G type hugetlbfs (rw,relatime,pagesize=1024M) hugetlbfs on /mnt/huge type hugetlbfs (rw,relatime,pagesize=2M) get_hugepage_dir is first called with hugepage_sz=2097152. While iterating over all mount points, /dev/hugepages is incorrectly determined to be a match because it's a prefix of --huge-dir. The caller then obtains an exclusive lock on --huge-dir. In the next call to get_hugepage_dir, hugepage_sz=1073741824. This call correctly determines /dev/hugepages1G is a match. The caller again attempts to obtain an exclusive lock on --huge-dir and deadlocks because it's already holding a lock. This has been corrected by ensuring any matched mount point is either an exact match or a parent path of --huge-dir. Fixes: 24d5a1ce6b85 ("eal/linux: allow hugetlbfs sub-directories") Cc: john.levon@nutanix.com Cc: stable@dpdk.org Signed-off-by: Ashish Sadanandan Reviewed-by: John Levon Reviewed-by: John Levon Tested-by: Julien Meunier --- lib/eal/linux/eal_hugepage_info.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/eal/linux/eal_hugepage_info.c b/lib/eal/linux/eal_hugepage_info.c index a1b6cb31ff..e26e4d7a7a 100644 --- a/lib/eal/linux/eal_hugepage_info.c +++ b/lib/eal/linux/eal_hugepage_info.c @@ -214,6 +214,8 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len) char buf[BUFSIZ]; const struct internal_config *internal_conf = eal_get_internal_configuration(); + const size_t hugepage_dir_len = (internal_conf->hugepage_dir != NULL) ? + strlen(internal_conf->hugepage_dir) : 0; struct stat st; /* @@ -233,6 +235,7 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len) while (fgets(buf, sizeof(buf), fd)){ const char *pagesz_str; + size_t mountpt_len = 0; if (rte_strsplit(buf, sizeof(buf), splitstr, _FIELDNAME_MAX, split_tok) != _FIELDNAME_MAX) { @@ -265,12 +268,16 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len) break; } + mountpt_len = strlen(splitstr[MOUNTPT]); + /* - * Ignore any mount that doesn't contain the --huge-dir - * directory. + * Ignore any mount that doesn't contain the --huge-dir directory + * or where mount point is not a parent path of --huge-dir */ if (strncmp(internal_conf->hugepage_dir, splitstr[MOUNTPT], - strlen(splitstr[MOUNTPT])) != 0) { + mountpt_len) != 0 || + (hugepage_dir_len > mountpt_len && + internal_conf->hugepage_dir[mountpt_len] != '/')) { continue; } @@ -278,7 +285,7 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len) * We found a match, but only prefer it if it's a longer match * (so /mnt/1 is preferred over /mnt for matching /mnt/1/2)). */ - if (strlen(splitstr[MOUNTPT]) > strlen(found)) + if (mountpt_len > strlen(found)) strlcpy(found, splitstr[MOUNTPT], len); } /* end while fgets */