From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 203A742F705; Thu, 16 Jul 2026 14:33:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784212422; cv=none; b=Oy/m9kAtvWpG7JTTws6x/pyy28kk5rgEHs2lVxJRL4InlMWjj/p9pdSPBnesOcQpXmz2EucE0d54oQpIy1tp+IqYlKRRK+TW6S7dVKTEe/sdBg0XxNY/NtqBL/eKbEibyJaZITghI5qdt7AvSXEcNPwRI1KyQsH8WaGjDvnYA9U= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784212422; c=relaxed/simple; bh=QHZOwbtAcuiRER8/7FuUS+utg2Ir2izidnKZsKTpU84=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=L2+7hllb0qSnQUI27+AT/bo5GU1kME/5X+L6pm4R3EQRgwTCImbcRwXls6aKpg92irIryxQjmEQkKafaCSjRSWGnBlZJt92nhzsX63fNNp5GW6hqZynu+YH1BNOes7yJHCB6zT7RBiNUVePN8BUlp5TWsL9FeI03D+26RvkJulw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=adxjzKU+; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="adxjzKU+" Received: by smtp.kernel.org (Postfix) with ESMTPSA id ACD861F000E9; Thu, 16 Jul 2026 14:33:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1784212421; bh=ASZpr7EMVoSBiT7h4e+sqY/ZbRD2tlIKLPKUp+aQp78=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=adxjzKU+mF7ZYlCO4JUnTBYVAKbNx+XgzC3fMAs8qUieHlcHRgWI+XZq3929UrsLc ApwUeWNQmBaHtg2M+k/TGEk8bhth2wqyWn173kglHVKOG6d3ofXiW49PbioNH/W3S4 ulqcExYGcVDmSoq/pEwjsxE9S7lD1SFPx4MyDdBI= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Ahsan Atta , Maksim Lukoshkov , Giovanni Cabiddu , Herbert Xu Subject: [PATCH 6.12 284/349] crypto: qat - protect service table iterations with service_lock Date: Thu, 16 Jul 2026 15:33:38 +0200 Message-ID: <20260716133039.691469077@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260716133033.287196923@linuxfoundation.org> References: <20260716133033.287196923@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Ahsan Atta commit 5c6f845e77ec35f9b7b047cc8f9789bf397cdd3e upstream. The service_table list is protected by service_lock when entries are added or removed (in adf_service_add() and adf_service_remove()), but several functions iterate over the list without holding this lock. A concurrent adf_service_register() or adf_service_unregister() call could modify the list during traversal, leading to list corruption or a use-after-free. Fix this by holding service_lock across all list_for_each_entry() iterations of service_table in adf_dev_init(), adf_dev_start(), adf_dev_stop(), adf_dev_shutdown(), adf_dev_restarting_notify(), adf_dev_restarted_notify(), and adf_error_notifier(). The lock ordering is safe: callers of the static helpers (adf_dev_up() and adf_dev_down()) acquire state_lock before service_lock, and no event_hld callback or service_lock holder ever acquires state_lock in the reverse order. Cc: stable@vger.kernel.org Fixes: d8cba25d2c68 ("crypto: qat - Intel(R) QAT driver framework") Signed-off-by: Ahsan Atta Co-developed-by: Maksim Lukoshkov Signed-off-by: Maksim Lukoshkov Reviewed-by: Giovanni Cabiddu Signed-off-by: Herbert Xu Signed-off-by: Greg Kroah-Hartman --- drivers/crypto/intel/qat/qat_common/adf_init.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) --- a/drivers/crypto/intel/qat/qat_common/adf_init.c +++ b/drivers/crypto/intel/qat/qat_common/adf_init.c @@ -152,15 +152,18 @@ static int adf_dev_init(struct adf_accel * This is to facilitate any ordering dependencies between services * prior to starting any of the accelerators. */ + mutex_lock(&service_lock); list_for_each_entry(service, &service_table, list) { if (service->event_hld(accel_dev, ADF_EVENT_INIT)) { dev_err(&GET_DEV(accel_dev), "Failed to initialise service %s\n", service->name); + mutex_unlock(&service_lock); return -EFAULT; } set_bit(accel_dev->accel_id, service->init_status); } + mutex_unlock(&service_lock); return 0; } @@ -229,15 +232,18 @@ static int adf_dev_start(struct adf_acce if (ret && ret != -EOPNOTSUPP) return ret; + mutex_lock(&service_lock); list_for_each_entry(service, &service_table, list) { if (service->event_hld(accel_dev, ADF_EVENT_START)) { dev_err(&GET_DEV(accel_dev), "Failed to start service %s\n", service->name); + mutex_unlock(&service_lock); return -EFAULT; } set_bit(accel_dev->accel_id, service->start_status); } + mutex_unlock(&service_lock); clear_bit(ADF_STATUS_STARTING, &accel_dev->status); set_bit(ADF_STATUS_STARTED, &accel_dev->status); @@ -308,6 +314,7 @@ static void adf_dev_stop(struct adf_acce qat_comp_algs_unregister(); clear_bit(ADF_STATUS_COMP_ALGS_REGISTERED, &accel_dev->status); + mutex_lock(&service_lock); list_for_each_entry(service, &service_table, list) { if (!test_bit(accel_dev->accel_id, service->start_status)) continue; @@ -319,6 +326,7 @@ static void adf_dev_stop(struct adf_acce clear_bit(accel_dev->accel_id, service->start_status); } } + mutex_unlock(&service_lock); if (hw_data->stop_timer) hw_data->stop_timer(accel_dev); @@ -368,6 +376,7 @@ static void adf_dev_shutdown(struct adf_ &accel_dev->status); } + mutex_lock(&service_lock); list_for_each_entry(service, &service_table, list) { if (!test_bit(accel_dev->accel_id, service->init_status)) continue; @@ -378,6 +387,7 @@ static void adf_dev_shutdown(struct adf_ else clear_bit(accel_dev->accel_id, service->init_status); } + mutex_unlock(&service_lock); adf_rl_exit(accel_dev); @@ -412,12 +422,14 @@ int adf_dev_restarting_notify(struct adf { struct service_hndl *service; + mutex_lock(&service_lock); list_for_each_entry(service, &service_table, list) { if (service->event_hld(accel_dev, ADF_EVENT_RESTARTING)) dev_err(&GET_DEV(accel_dev), "Failed to restart service %s.\n", service->name); } + mutex_unlock(&service_lock); return 0; } @@ -425,12 +437,14 @@ int adf_dev_restarted_notify(struct adf_ { struct service_hndl *service; + mutex_lock(&service_lock); list_for_each_entry(service, &service_table, list) { if (service->event_hld(accel_dev, ADF_EVENT_RESTARTED)) dev_err(&GET_DEV(accel_dev), "Failed to restart service %s.\n", service->name); } + mutex_unlock(&service_lock); return 0; } @@ -438,12 +452,14 @@ void adf_error_notifier(struct adf_accel { struct service_hndl *service; + mutex_lock(&service_lock); list_for_each_entry(service, &service_table, list) { if (service->event_hld(accel_dev, ADF_EVENT_FATAL_ERROR)) dev_err(&GET_DEV(accel_dev), "Failed to send error event to %s.\n", service->name); } + mutex_unlock(&service_lock); } int adf_dev_down(struct adf_accel_dev *accel_dev)