From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f52.google.com (mail-wr1-f52.google.com [209.85.221.52]) (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 35717346FB5 for ; Sat, 8 Aug 2026 22:39:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.52 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786228751; cv=none; b=FtVOp4piykYId85qVgnkGOv5WABsV2S/LE8kNjYw0o2k1PF+27nyP40QUFX6x6FzdxJJQ/tliWqSvIZLsRbmLffT4IsFbBcDnJ06NmCkY+yfdkGp6Rf0LnOAFVtCiYLlkCqXo00dTd24FiFE0++c3Oh2Z3pKZrNJIfLcUEvF96s= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786228751; c=relaxed/simple; bh=/Ri+76lmeMTI0L0K9x/tU/UJQSgi9MDW+TkkxjfzvnI=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=hjem/XtOBwMtur0UpKn9lKMYJ0FGiAwbZ4/823ZTB9nMWfVlyQYqG+IsvskuQAa13JQHJeVomTLmrl1g+cQ1To3m2XshJecYwt8fuF0xNJ5fJDh1J+K/xIT6zoGhHb0GWjPeMePMoFTBFGCrADlnQ3EkK6lezC/naZGKcNh4VGg= 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=VIbmY/I0; arc=none smtp.client-ip=209.85.221.52 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="VIbmY/I0" Received: by mail-wr1-f52.google.com with SMTP id ffacd0b85a97d-472326ca506so375191f8f.2 for ; Sat, 08 Aug 2026 15:39:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786228748; x=1786833548; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=hIDW4mWudSHacH5kmeKRE0d0Qth6MvHevd3mWB6RzP0=; b=VIbmY/I0NTOGt5qrUj2cfpgQ89jxjl/a5URZfaBTfQcC/O3rC0eq81IDBIA3ZLcFzI AlQOQRuiak8770HrvrPzubvsakqQOvBLkRpeJQVOVjfhyEeKvIdK5BQcHnhhi42Dl4fV gYNMykiAZvHrepN2TXHxDTY6/3CfC1HtLf5k4vy/dZ6MMAzm5jaDUgseDFYp68ZXxzM5 P40rnJcgjcYMpKQqWWuEwj7w5e+HtmPAbcJVfSrDy8gKulWFcbfdvL8QIljxvNfecnKn De3G6rROrSTwldvoAKnwuZlHJIEAoTx8jJvKyhZD+PjzQYEF/ZYn1II3utFOJa7cnuOy EfGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786228748; x=1786833548; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=hIDW4mWudSHacH5kmeKRE0d0Qth6MvHevd3mWB6RzP0=; b=K5OfvKhBspkUsFojMy0js4R+8qp6T3JTu8pCNQ5W6oazF4fXShhvdYtFi8rhX2C5KH q9tEH+HlUtA3zNzQ0xbrKZNAF//9eF7A0kRGmOM3+QTo3B3JTTfVFIrSE0Bw0snOKhzK mR1ZJTEkjmPXFJH0vSUHKwZbFkfpcPHJz47xYHNj7LuY0ULaFSkzsSiBQu54/GDM17WR o9XFhWF/UdgNSjdpJPiM8NvyWNU5yMt53+InkTfmLfkaXo5g5AuPHtlx8n1FgVh6GuoQ 3gi2cXtnH0euB3KUCDq+qYK3jyWVWwNOjhEIfK7XX9qrvouyMNpLdaF38upjgXZ6eNu6 UJAw== X-Forwarded-Encrypted: i=1; AHgh+RoneOCza+2uRUioo8/t+rfriBUeQNG5Hu55cKTIUtqnYCF3CSai43IQgNRTK6ERHX9ZkLtD2CTJ9UnfNpQ=@vger.kernel.org X-Gm-Message-State: AOJu0YxyS9FrCzayTeGsdUDzOMVSzuK7f6P7Y38mlK3d7iTCm5lC02Ql 6I+kSErxZz+IPorm53R04h8sjRlfNzTlXtONMxSKYCrgXeGEnvGX3tM2 X-Gm-Gg: AR+sD10YjW87lUOjXVl3gO1XOm2Pf3IhUtE7xT7UH+C3LoTngtbp1XeokT3VBIcOt8C JksFeZ0AuAH7xjhiWP0MD6Nzb1VmQDN7HEDvLTILNML/nr0MYbsBMu76le4W9ZScMcY6QtApOGx XI8KnHcnCxH2nqNfiO34YxoVaHjtHc4Gh3LsXzaGboZ/+sA5p15BgCUHIBkY8jtva6eaIiUxy5s 0KZOQEjBtax0u86kPbkPB3Rowq2s6OJKgpvSjgZpT7Abp2+IP4LH4flrzfIVAgsuf3gEPyhkA0w b5cOIvAWyle4J9kEgu3LtBr04zHyUGIQcZoFcRiVfuXAJ0ToGBAD4dNKlZE+ygq86y9mb6m+AYa 2MQ+MSQF6zLGhpZR+TeUDghLnHAH8cPX6FNMrhGtCoQw0F9t+bXLdTjFPtJShVu/RChWqQ/KWd6 0evpikxUdY987l0Q1cDVe1s3GtGsqEmFs4lRQqDffomgewrkywPHKfBuQjWmozyAqQwFzM8y3RQ Q9dXUetzi0QOqJPG2UFVnYnmrKvKOBoy+QQcjwWhQ== X-Received: by 2002:a05:6000:2c0d:b0:47f:6b9a:9d54 with SMTP id ffacd0b85a97d-47fec4ebd82mr49986071f8f.7.1786228748190; Sat, 08 Aug 2026 15:39:08 -0700 (PDT) Received: from fedora ([105.191.54.205]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-480021501bcsm17943429f8f.9.2026.08.08.15.39.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 08 Aug 2026 15:39:07 -0700 (PDT) From: Jad Keskes To: bp@alien8.de Cc: linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org, Mauro Carvalho Chehab , Tony Luck , James Morse , Robert Richter , Jad Keskes Subject: [PATCH] EDAC/device: Serialize poll_msec updates against device teardown Date: Sat, 8 Aug 2026 23:39:03 +0100 Message-ID: <20260808223903.16768-1-inasj268@gmail.com> X-Mailer: git-send-email 2.55.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The poll_msec attribute was writable on interrupt-driven controllers, where the value is meaningless, and a write racing with device removal could re-arm the polling workqueue after it had been stopped and the ctl_info freed -- use-after-free. Restrict the attribute to controllers that are actually polled: _show() and _store() now return -EPERM unless the controller is in the OP_RUNNING_POLL state. That check alone is not sufficient against the teardown race: _store() can pass it and then be preempted by a concurrent del_device() that sets OP_OFFLINE, stops the workqueue and frees the ctl_info once the store completes. So re-check the state inside reset_delay_period() under device_ctls_mutex -- the same lock under which del_device() updates op_state -- making the check atomic with the re-arm. The mutex is taken only around the check and re-arm, never across the stop/teardown path, so it cannot deadlock against other pollers queued on the shared EDAC workqueue. Reported-by: Borislav Petkov Signed-off-by: Jad Keskes --- drivers/edac/edac_device.c | 11 +++++++++++ drivers/edac/edac_device_sysfs.c | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c index 361dc985497b..519d1c6d0930 100644 --- a/drivers/edac/edac_device.c +++ b/drivers/edac/edac_device.c @@ -392,10 +392,21 @@ static void edac_device_workq_teardown(struct edac_device_ctl_info *edac_dev) */ void edac_device_reset_delay_period(struct edac_device_ctl_info *edac_dev, unsigned int msec) { + mutex_lock(&device_ctls_mutex); + + /* Don't re-arm the workqueue once teardown has begun or when the + * controller isn't polled; this check must be atomic with the + * re-arm below so it can't race a concurrent del_device(). + */ + if (edac_dev->op_state != OP_RUNNING_POLL) + goto out; + edac_dev->poll_msec = msec; edac_dev->delay = msecs_to_jiffies(msec); edac_mod_work(&edac_dev->work, edac_dev->delay); +out: + mutex_unlock(&device_ctls_mutex); } int edac_device_alloc_index(void) diff --git a/drivers/edac/edac_device_sysfs.c b/drivers/edac/edac_device_sysfs.c index e12122b2f42e..821a80806086 100644 --- a/drivers/edac/edac_device_sysfs.c +++ b/drivers/edac/edac_device_sysfs.c @@ -83,6 +83,10 @@ static ssize_t edac_device_ctl_panic_on_ue_store(struct edac_device_ctl_info static ssize_t edac_device_ctl_poll_msec_show(struct edac_device_ctl_info *ctl_info, char *data) { + /* Interval is only meaningful while running under polling */ + if (ctl_info->op_state != OP_RUNNING_POLL) + return -EPERM; + return sprintf(data, "%u\n", ctl_info->poll_msec); } @@ -93,6 +97,10 @@ static ssize_t edac_device_ctl_poll_msec_store(struct edac_device_ctl_info unsigned int value; int ret; + /* Only meaningful when the device is running under polling */ + if (ctl_info->op_state != OP_RUNNING_POLL) + return -EPERM; + /* * Get the value, make sure it is non-zero, must be at least one * millisecond for the delay period between scans. -- 2.55.0