From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f41.google.com (mail-wr1-f41.google.com [209.85.221.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 08ED53BFE3A for ; Tue, 19 May 2026 20:48:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.41 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779223695; cv=none; b=u1vqrKodYGWMFwWgS7MbuwQEWb0jNI87orHnYU2IhdT1kuBM6BHR1GKzJ3TstyuYRvbTpFAr8Qh8kZmzMXUci0BIIUchGx1YIHJ2JAsEukTLpueLPqqixzacJ+qWOWAhrhW+WzOo6e6xcre/QRKMyJGxFo2depBjra/imSMJKjo= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779223695; c=relaxed/simple; bh=qB+N5sBAU4+OEoQbOXMEFHFAdXvpKcGGTLPscoURS9w=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=kSq2FJ2oRTW4EETu3sD/RudEpvfJqmuCfT4kt7WIPmqMHTBx1g22M37TNKOUPoeuBT1DUtdFVMJMrcaNH1DibQlG3QE5v36TfP045LZChSYpo2MtSaOOl2XHSrlHXhMNSC5mBGDlG46narXJpL19Sfg/IpsRj92o1bjOns/BtZs= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Wfb6pC+G; arc=none smtp.client-ip=209.85.221.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Wfb6pC+G" Received: by mail-wr1-f41.google.com with SMTP id ffacd0b85a97d-43d7828221bso225301f8f.3 for ; Tue, 19 May 2026 13:48:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779223692; x=1779828492; darn=vger.kernel.org; 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=46bxzW7AWDk4uXlyHvKMVMwj/OyP1y7/MWcuxerPlBc=; b=Wfb6pC+GGEpo96iCWR7/A6fRITHK92G27tcZ4w6/eqxj2e4EfGSbg9GVhdvywCrtCv iPs/ICt3xXPSNfPNGuHXktejgtBRwYBByOCloS/vMmAbfLMygzDXMvSsvueU63TYa5zl rM1TxsyLzTFntSfYLBSpGyTJFqUTX8vl6Xg0CKuVR/JzUon5swW2ZFMzzrfKJqvabNO0 T+z+rX1Artvmc2cUSjqPR7PZ5UoXbrf00mdKqBUGzNc7q/4QtIfMYVC1vn6jVmWf6Zc9 JF5sBEZ/+UYz8q9H8TmkAUVp/wBqtZaUQ1W0CfCHZlAxsiqGfppIPsEtP4QzjyNB4ZAr UntA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779223692; x=1779828492; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=46bxzW7AWDk4uXlyHvKMVMwj/OyP1y7/MWcuxerPlBc=; b=P4Ru/9SDAZoqBE0H2CErOghh87yojPoUeD9SL4yEeDpR0wj08vbg/6eNJNXyqYgDxq pEnTznXiBaPWvJuc750Y63dNxpj8IwTzK2vD83Hn7yQGNC6rH808ryUzuEZkFRWkMKr0 nLanPcV8FJrr6jpZtVrAFOKyq2fa+npwgsGFNC67bXQea6EP8Mk0/LyK7k46Fk51MyKW 0nlNRNuzI+4QbBz8jQ7rPVdeezZI6T6rlqvIrUaRVV8P9D0ixjJBnJS3J7Df6uIKtbFK 5B2XdQE3MytgE4SOhtRitOUf9mIZpRLiwcagJCUi4xYF9NLNJbMz2AC3Tv4fYtVkaTLi GEYw== X-Forwarded-Encrypted: i=1; AFNElJ99wxl+Zb5FnQEX9bxFcIbEpPSmwsEnW/QEu5zGIHzyb1uphPZGrr+5lpCoOjsK1ukOTfUHJfnxHkE4jnc=@vger.kernel.org X-Gm-Message-State: AOJu0Yxb8P8JuRVXEiN9ML5RIQAzN3YBfoO8DCXeHXucyFZ4iRsTYBHz yc8ZnWawwtaH4v/vdMHTuir3E0DvEsxOBYno6eJooe05Q7GZp+H0t0dn X-Gm-Gg: Acq92OFmz+V7blEXPv+xGaP2fRcgkHT+2RhRlJJ2qs1rFCBsuNN80QmfMcpzEvW63Q6 tUHvV7ALK4U6wQCgyafNDjRJNwkZB2oKa5GVGexxPSPXE4XJ5UjZJbhLtiy3xxeNJZUFq+W4J8I WLXM5rMPa6CBDklUrPtqHWtDXIjjgPn40rPMmV0v6OvA59Ucf2S4Jp7+XmNWUUSI4esmKXTJiVk l4aqGC/naDMto4rde1PTdEfPY8xKas2dYI/21XcnuHlBZeGbNGIQGm9flUGeFTP+LJMrDryEj36 6RfrijH59q+TbcZ2ztdhbTDQXsw/RnMgmN058f9iRJFryBNBMVPYhBspUbRvTP/3MXid8YBYMwO 8LCZojzI0FVhXwjKtIin3C/iaNl8YaLYtn0qXQ4GCCjEEuQ0b666nkYShs8GkqsxevcJfom8Csx vn7LG2S0IsYSS3JrB2Fi7ErT368N+xXFOdvNf5wH5xdDEMkpaFvSd1ICJpSmeO9nw= X-Received: by 2002:a05:600c:8b25:b0:490:6ab:406a with SMTP id 5b1f17b1804b1-49006ab40f1mr111033255e9.8.1779223692230; Tue, 19 May 2026 13:48:12 -0700 (PDT) Received: from menon.v.cablecom.net (84-74-0-139.dclient.hispeed.ch. [84.74.0.139]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48fe4dac000sm356457755e9.0.2026.05.19.13.48.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 May 2026 13:48:11 -0700 (PDT) From: Lothar Rubusch To: thorsten.blum@linux.dev, herbert@gondor.apana.org.au, davem@davemloft.net, nicolas.ferre@microchip.com, alexandre.belloni@bootlin.com, claudiu.beznea@tuxon.dev Cc: linux-crypto@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, l.rubusch@gmail.com Subject: [PATCH v2 03/12] crypto: atmel-ecc - fix multi-device kpp registration Date: Tue, 19 May 2026 20:47:54 +0000 Message-Id: <20260519204803.17034-4-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260519204803.17034-1-l.rubusch@gmail.com> References: <20260519204803.17034-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit In a scenario where multiple such devices are attached, the following situation may arise (finding by sashiko): Device 1 Probes: Calls crypto_register_kpp(&atmel_ecdh_nist_p256). The Crypto Core modifies fields inside this global structure to link it into the system-wide algorithm list. Registration succeeds. Device 2 Probes (Minutes later, on a system with two of these I2C chips): It executes the exact same line of code. It passes the exact same global &atmel_ecdh_nist_p256 memory address to crypto_register_kpp(). The Disaster: The Crypto Core tries to register it again. It overwrites the internal fields that Device 1 was already using. This corrupts the Linux crypto subsystem's internal linked lists, usually leading to an immediate kernel panic or silent memory corruption. Introduce a global mutex and reference counter to ensure that the static kpp algorithm is registered only once by the first probing device, and unregistered only when the last matching device is removed. Fixes: 11105693fa05 ("crypto: atmel-ecc - introduce Microchip / Atmel ECC driver") Signed-off-by: Lothar Rubusch --- drivers/crypto/atmel-ecc.c | 55 +++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/drivers/crypto/atmel-ecc.c b/drivers/crypto/atmel-ecc.c index 19d5435aa42b..e5dd166fd785 100644 --- a/drivers/crypto/atmel-ecc.c +++ b/drivers/crypto/atmel-ecc.c @@ -23,6 +23,9 @@ #include #include "atmel-i2c.h" +static DEFINE_MUTEX(atmel_ecc_kpp_lock); +static int atmel_ecc_kpp_refcnt; + static struct atmel_ecc_driver_data atmel_i2c_mgmt; /** @@ -331,23 +334,30 @@ static int atmel_ecc_probe(struct i2c_client *client) &atmel_i2c_mgmt.i2c_client_list); spin_unlock(&atmel_i2c_mgmt.i2c_list_lock); - ret = crypto_register_kpp(&atmel_ecdh_nist_p256); - if (ret) { - spin_lock(&atmel_i2c_mgmt.i2c_list_lock); - list_del(&i2c_priv->i2c_client_list_node); - spin_unlock(&atmel_i2c_mgmt.i2c_list_lock); + mutex_lock(&atmel_ecc_kpp_lock); + if (atmel_ecc_kpp_refcnt == 0) { + ret = crypto_register_kpp(&atmel_ecdh_nist_p256); + if (ret) { + spin_lock(&atmel_i2c_mgmt.i2c_list_lock); + list_del(&i2c_priv->i2c_client_list_node); + spin_unlock(&atmel_i2c_mgmt.i2c_list_lock); - dev_err(&client->dev, "%s alg registration failed\n", - atmel_ecdh_nist_p256.base.cra_driver_name); - return ret; - } else { - dev_info(&client->dev, "atmel ecc algorithms registered in /proc/crypto\n"); + dev_err(&client->dev, "%s alg registration failed\n", + atmel_ecdh_nist_p256.base.cra_driver_name); + + mutex_unlock(&atmel_ecc_kpp_lock); + return ret; + } } + atmel_ecc_kpp_refcnt++; + mutex_unlock(&atmel_ecc_kpp_lock); spin_lock(&atmel_i2c_mgmt.i2c_list_lock); i2c_priv->ready = true; spin_unlock(&atmel_i2c_mgmt.i2c_list_lock); + dev_info(&client->dev, "atmel ecc algorithms registered in /proc/crypto\n"); + return ret; } @@ -359,21 +369,16 @@ static void atmel_ecc_remove(struct i2c_client *client) i2c_priv->ready = false; spin_unlock(&atmel_i2c_mgmt.i2c_list_lock); - /* Return EBUSY if i2c client already allocated. */ - if (atomic_read(&i2c_priv->tfm_count)) { - /* - * After we return here, the memory backing the device is freed. - * That happens no matter what the return value of this function - * is because in the Linux device model there is no error - * handling for unbinding a driver. - * If there is still some action pending, it probably involves - * accessing the freed memory. - */ - dev_emerg(&client->dev, "Device is busy, expect memory corruption.\n"); - return; - } - - crypto_unregister_kpp(&atmel_ecdh_nist_p256); + /* + * Note, the Linux Crypto Core automatically blocks until all active + * transformations utilizing that specific algorithm structure + * are fully freed and closed. + */ + mutex_lock(&atmel_ecc_kpp_lock); + atmel_ecc_kpp_refcnt--; + if (atmel_ecc_kpp_refcnt == 0) + crypto_unregister_kpp(&atmel_ecdh_nist_p256); + mutex_unlock(&atmel_ecc_kpp_lock); spin_lock(&atmel_i2c_mgmt.i2c_list_lock); list_del(&i2c_priv->i2c_client_list_node); -- 2.39.5