From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id BB81FA0A02; Thu, 25 Mar 2021 12:28:00 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0BD09140D0B; Thu, 25 Mar 2021 12:28:00 +0100 (CET) Received: from mail-wr1-f44.google.com (mail-wr1-f44.google.com [209.85.221.44]) by mails.dpdk.org (Postfix) with ESMTP id 385724067B for ; Thu, 25 Mar 2021 12:27:59 +0100 (CET) Received: by mail-wr1-f44.google.com with SMTP id b9so1891130wrt.8 for ; Thu, 25 Mar 2021 04:27:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=YXhWEOVjm+iIjmHk+03AB+eszrrXseuLzYZ82WDCDXA=; b=ek/g6fvzjz6XAJK/O9nbuqML2eS+18p+y+bsxqp2NpRl/ECoXG8f60oeOGIocHD2vd molZNxkEJrIXbNRKmgqaVouXosK5snKQ3UzjmFio7opfzB8qRnVlPksi6xrsFS83ch5C /ka9FrAbaF0QUf3W4359RoJiukEbqntQjDn5Gq7sSTtj35uGWqwEYzSg93k5ouySdFAx UmaqV7Gtjp+2MhCqqPBO6PoO/doKzJMW+E56VAf6xSbEC3BRf4AX7ZQEhrfkr6Ld6/zI sdg5Elj4BlMnas6PwMZX/jW+lO8czbG8G5wobqXT9Z2Nvp6/Ni/RgHWE53Il4CHzY2mP e3lg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=YXhWEOVjm+iIjmHk+03AB+eszrrXseuLzYZ82WDCDXA=; b=ZFK+Q2A+EKr9aWAB3YCBsysdU3mxmOSzRxv40YntICzvF4WWrYgcqTIo4427RArGDH Q1P64MZPQSZlGtFget8EjkFao0VHYqsHtbKafnxHtyog/EJyFZeQHINp6wgvsNVpRCCy Y44G7giVSJ4f9qC0m80Q3qhcE8a8M4d4UFPwiwAZJRYLJ+QRHQJPNFKQnlx9qbZzzVS0 dVwhcXjiLPN2XJIUqy1/5n9/mYKBj9/lRbQAxzYjlw6nQvKMXCtKQhOXTB3wZbpMJ6PP m6sdv4rgiuo/x9rjawsWJpd6xtxmyR4GAREtEmVPtDOqr4juavRmapweNWFrSG30pyQW SRGw== X-Gm-Message-State: AOAM532K7as7FO2fP7hu1ekH/P+VIKAv+rzD1bV+7FXXcxnkubUYlkNx cU0bwB8P0MsBjkYeLbV1zKvQjQ== X-Google-Smtp-Source: ABdhPJzCM5jeyuJklvT1msKauNTBAjusWFC9h3KJw6uSTN0ZfPpMx+N0ycAxp3ukuTZTLXWHES2Udw== X-Received: by 2002:a5d:638a:: with SMTP id p10mr8708953wru.286.1616671678925; Thu, 25 Mar 2021 04:27:58 -0700 (PDT) Received: from gojira.dev.6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id s3sm5951518wmd.21.2021.03.25.04.27.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Mar 2021 04:27:58 -0700 (PDT) From: Olivier Matz To: lucp.at.work@gmail.com Cc: dev@dpdk.org, jianfeng.tan@intel.com, david.marchand@redhat.com, stable@dpdk.org Date: Thu, 25 Mar 2021 12:27:31 +0100 Message-Id: <20210325112731.16324-1-olivier.matz@6wind.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210324130422.92357-1-lucp.at.work@gmail.com> References: <20210324130422.92357-1-lucp.at.work@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dpdk-dev] [PATCH v2] eal: fix race in ctrl thread creation 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 Sender: "dev" As reported by Luc, there is a race where the barrier is destroyed by one thread, while the other thread did not yet leave pthread_barrier_wait. This patch fixes the race condition by adding an atomic counter to ensure that the barrier is destroyed only it is not used by any thread. Fixes: 3a0d465d4c53 ("eal: fix use-after-free on control thread creation") Cc: jianfeng.tan@intel.com Cc: stable@dpdk.org Reported-by: Luc Pelletier Signed-off-by: David Marchand Signed-off-by: Olivier Matz --- Hi Luc, Thank you for reporting this problem and submitting the patch. I think the issue can be fixed without any loop, like in this patch. What do you think? Regards, Olivier lib/librte_eal/common/eal_common_thread.c | 38 +++++++++++++---------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/lib/librte_eal/common/eal_common_thread.c b/lib/librte_eal/common/eal_common_thread.c index 73a055902a..891f825e87 100644 --- a/lib/librte_eal/common/eal_common_thread.c +++ b/lib/librte_eal/common/eal_common_thread.c @@ -170,11 +170,11 @@ struct rte_thread_ctrl_params { void *(*start_routine)(void *); void *arg; pthread_barrier_t configured; + unsigned int barrier_refcnt; }; static void *ctrl_thread_init(void *arg) { - int ret; struct internal_config *internal_conf = eal_get_internal_configuration(); rte_cpuset_t *cpuset = &internal_conf->ctrl_cpuset; @@ -184,8 +184,9 @@ static void *ctrl_thread_init(void *arg) __rte_thread_init(rte_lcore_id(), cpuset); - ret = pthread_barrier_wait(¶ms->configured); - if (ret == PTHREAD_BARRIER_SERIAL_THREAD) { + pthread_barrier_wait(¶ms->configured); + if (__atomic_sub_fetch(¶ms->barrier_refcnt, 1, + __ATOMIC_ACQ_REL) == 0) { pthread_barrier_destroy(¶ms->configured); free(params); } @@ -210,15 +211,17 @@ rte_ctrl_thread_create(pthread_t *thread, const char *name, params->start_routine = start_routine; params->arg = arg; - - pthread_barrier_init(¶ms->configured, NULL, 2); - - ret = pthread_create(thread, attr, ctrl_thread_init, (void *)params); + __atomic_store_n(¶ms->barrier_refcnt, 2, __ATOMIC_RELEASE); + ret = pthread_barrier_init(¶ms->configured, NULL, 2); if (ret != 0) { free(params); return -ret; } + ret = pthread_create(thread, attr, ctrl_thread_init, (void *)params); + if (ret != 0) + goto fail; + if (name != NULL) { ret = rte_thread_setname(*thread, name); if (ret < 0) @@ -227,25 +230,26 @@ rte_ctrl_thread_create(pthread_t *thread, const char *name, } ret = pthread_setaffinity_np(*thread, sizeof(*cpuset), cpuset); - if (ret) - goto fail; + if (ret != 0) + goto fail_cancel; - ret = pthread_barrier_wait(¶ms->configured); - if (ret == PTHREAD_BARRIER_SERIAL_THREAD) { + pthread_barrier_wait(¶ms->configured); + if (__atomic_sub_fetch(¶ms->barrier_refcnt, 1, + __ATOMIC_ACQ_REL) == 0) { pthread_barrier_destroy(¶ms->configured); free(params); } return 0; -fail: - if (PTHREAD_BARRIER_SERIAL_THREAD == - pthread_barrier_wait(¶ms->configured)) { - pthread_barrier_destroy(¶ms->configured); - free(params); - } +fail_cancel: pthread_cancel(*thread); pthread_join(*thread, NULL); + +fail: + pthread_barrier_destroy(¶ms->configured); + free(params); + return -ret; } -- 2.29.2