From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <stable-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id 211C7A0A02
	for <public@inbox.dpdk.org>; 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 DEEFA40147;
	Thu, 25 Mar 2021 12:27:59 +0100 (CET)
Received: from mail-wr1-f54.google.com (mail-wr1-f54.google.com
 [209.85.221.54]) by mails.dpdk.org (Postfix) with ESMTP id 36BA840147
 for <stable@dpdk.org>; Thu, 25 Mar 2021 12:27:59 +0100 (CET)
Received: by mail-wr1-f54.google.com with SMTP id o16so1963234wrn.0
 for <stable@dpdk.org>; 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=EfEqTCQNpA3yZfSVDQMhqXsOPCQj4TH66Q2CRNpOYNmLRP9tzEkdhndSf3vh1YArnv
 kokCYu1tV8URUxEvRdgl+vgkn/d8w1pxcha0OdofgREe7fdKaZ2nYCRb7vmSgKHoZCne
 k9Ft1EneT4NhdZVRJrXy6DLW67/tNBd6jyBiqeWhAEg/7A1dbTTKRjD5PSRPZkBTGPCU
 sNXnHrdecXDGgyVdDsD+i6Goq0tpowUeUR/dslk12/Vnp04HkjQBaeA93i/LKny7AYg7
 RtY6ifIWFframRQFMm5XYvppor5X6lOIYM5d9SqZX+QG5/hiZIvEe3wxsyme7akwK6J0
 Akag==
X-Gm-Message-State: AOAM531T28bXZiTgw5j59Ivks2o7PyGhSvFE7Wf7sATNvjxs0BLXrUEw
 Ei6NV4fqUJgo/B927KezKVegVw==
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 <olivier.matz@6wind.com>
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-stable] [PATCH v2] eal: fix race in ctrl thread creation
X-BeenThere: stable@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: patches for DPDK stable branches <stable.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/stable>,
 <mailto:stable-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/stable/>
List-Post: <mailto:stable@dpdk.org>
List-Help: <mailto:stable-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/stable>,
 <mailto:stable-request@dpdk.org?subject=subscribe>
Errors-To: stable-bounces@dpdk.org
Sender: "stable" <stable-bounces@dpdk.org>

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 <lucp.at.work@gmail.com>
Signed-off-by: David Marchand <david.marchand@redhat.com>
Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---

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(&params->configured);
-	if (ret == PTHREAD_BARRIER_SERIAL_THREAD) {
+	pthread_barrier_wait(&params->configured);
+	if (__atomic_sub_fetch(&params->barrier_refcnt, 1,
+				__ATOMIC_ACQ_REL) == 0) {
 		pthread_barrier_destroy(&params->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(&params->configured, NULL, 2);
-
-	ret = pthread_create(thread, attr, ctrl_thread_init, (void *)params);
+	__atomic_store_n(&params->barrier_refcnt, 2, __ATOMIC_RELEASE);
+	ret = pthread_barrier_init(&params->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(&params->configured);
-	if (ret == PTHREAD_BARRIER_SERIAL_THREAD) {
+	pthread_barrier_wait(&params->configured);
+	if (__atomic_sub_fetch(&params->barrier_refcnt, 1,
+				__ATOMIC_ACQ_REL) == 0) {
 		pthread_barrier_destroy(&params->configured);
 		free(params);
 	}
 
 	return 0;
 
-fail:
-	if (PTHREAD_BARRIER_SERIAL_THREAD ==
-	    pthread_barrier_wait(&params->configured)) {
-		pthread_barrier_destroy(&params->configured);
-		free(params);
-	}
+fail_cancel:
 	pthread_cancel(*thread);
 	pthread_join(*thread, NULL);
+
+fail:
+	pthread_barrier_destroy(&params->configured);
+	free(params);
+
 	return -ret;
 }
 
-- 
2.29.2