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 211C7A0A02 for ; 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 ; Thu, 25 Mar 2021 12:27:59 +0100 (CET) Received: by mail-wr1-f54.google.com with SMTP id o16so1963234wrn.0 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=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 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Sender: "stable" 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