From nobody Mon Jun 8 08:36:46 2026 Received: from mail-dl1-f44.google.com (mail-dl1-f44.google.com [74.125.82.44]) (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 CCACE45349C for ; Wed, 3 Jun 2026 17:25:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780507552; cv=none; b=TMxP9ZF9RcAiItoTjpRSWbfQ754IYifArmWFhYl8BT4oT814dGLfBLZjs0ioL//CwxXDHMZcrbk7zBkjYkYhw3tbsOo8gqlisad3u7JJtv0OS3mrEILZk7XPzcVlSNkXiG8UTqPzjmK5Jg3+4pNiajlTd6t4TNRB+4zLDcjDj5U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780507552; c=relaxed/simple; bh=Mv0a2OKuvZeqTE5cE4qPXaYLHkPNq+TYx2FvWK2CuVk=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=F/u3AldEbngIq2rrmyBBwSkdVPVYdTR5ffdZflISmm9ovntT/WcOUgF6ShA/ZqeTagnKbClOd5GvpLCOC+o2WvWJSRqJHnubsRXINyTvQhaYtqMu4YgfNt/MqdhF0vfm47b0BRf2ikB499hlGAQM8kl/skK4hSruv6A9L23oD88= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=wbinvd.org; spf=pass smtp.mailfrom=wbinvd.org; dkim=pass (2048-bit key) header.d=wbinvd.org header.i=@wbinvd.org header.b=SacBfYAQ; arc=none smtp.client-ip=74.125.82.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=wbinvd.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=wbinvd.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=wbinvd.org header.i=@wbinvd.org header.b="SacBfYAQ" Received: by mail-dl1-f44.google.com with SMTP id a92af1059eb24-137f0aa125bso4433900c88.0 for ; Wed, 03 Jun 2026 10:25:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=wbinvd.org; s=wbinvd; t=1780507550; x=1781112350; 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; bh=XksCM6KgOWruU/VVPGqWgJD+tCuryqWBovKseddiYkQ=; b=SacBfYAQTWCxOOcwBJ2LAXsXRvyyIsGufyVim2hUttSM3+vio+vgzHYuUKOx2S85cp y1+l/wX2RVjZUBCJJc738D5l9lrKKH6GpMBRqsc0AGVoyEBVekq9IykR3eWkre/6l7VB dJKunBvKm0a/CuDax+y098AZmuN+WVuZQwIvyaebp5HfE+czatTmGZu5fS0ROJAnBoEI EwIu6k9/TEN3WKAaPMvJ3sHg4GPBpZvnPxXTTRXRfW6GppWbn0ew1AtP8dLguoLQyhkf ojTcYJ5y+M574Uj+/ZwJYCVCXHJVzppfPUQIyZbBBGBz1eHpxh4Xpe7FPrMtkDfcX1ta E7KA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780507550; x=1781112350; 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; bh=XksCM6KgOWruU/VVPGqWgJD+tCuryqWBovKseddiYkQ=; b=aPMAVmWvDqqvMuzYY6xiizUY96fUq3tuqIQ64LwfWcHF3RQPOZSupeBx/TtaZZQI5R Pp+gTbSNbxPBLTLOJz4aj43TEJd16GoTd9LQdie08tHc/QPwyIyEhOXau4fjd8tDzf4F uz0xg8VFq0pLI8K+IrNedL3TAgUXC90A0MhFFCNsuAAFj1vzkkX1B3RgR+Q1TYDQVJJ4 9o6A2OK1JRu2Wvk4IC3E5nPr/Ct2aPcqiAEudrugnp650849C0yJJ6iIzUBP7S+68pFw kSB3o9mqmsPQD96h5hXVu4HWa0nbG9xeoLsrE1Ft66bl4ECN/fo2XwbEjIDuFzwhoRXw FtFw== X-Gm-Message-State: AOJu0Yz7c/0hHQ0sbWW1RGMWdutc7MjoPB7zJlL9Yp+FeDvlk/+mFChx lKp9gK0YFbjsR0SUk3mjdIqWc47rXRpLNKzrUc5GaD6ChcL98ZY2G8p0iaINddgdg8qwubY70S6 lRrRd X-Gm-Gg: Acq92OEGabyqYrJwAEcY8Vp676Y6aql9SsEvS3QwR7geP3y07bbFkE+/r5weJm+FH+0 IKeKAp55JmdZ0Sqna/5ZYBl0agZs3/ayh/qaV6OOs+JX59cCD9wa8miMQ9TGtqcZG2KEQYojTJK O7POhUwxJ8lfT8ByfjL0/LAJLPRkGLqZUnueqV1QbPqGJL610/Zse/73UDT01QINR/O4JYl8EaT FCm0zlexfPnc56Sd6UnHE/vouLwvHg1NnPw1tHeF7mJXs3vHlxNd16XnSp0m/fnykwdWfL3VSK8 Dqu2quT1KAJgiD88PC2NP7zsn2UyRzkyqW5vDlWJEQoJjLGt5bcONzXfdu84F769QZFc0vCUoQz t91NIsxoGfSo7YnHIvIgGuLI7QOuaweZXamqDbLbYbPU0wlHq+12ndiDn+L6HlXOU/wB33Hri0m 8BcJOyemBCK8Y4qulCZ6CCJpOQDC5EsE73bYjC X-Received: by 2002:a05:7022:419:b0:137:f1a2:c0c8 with SMTP id a92af1059eb24-137f6bf2bb9mr1712068c88.40.1780507549679; Wed, 03 Jun 2026 10:25:49 -0700 (PDT) Received: from mozart.vkv.me ([2001:5a8:468b:d015:1487:bdb2:8f0e:f9f0]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-137f54c9c12sm2330285c88.6.2026.06.03.10.25.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Jun 2026 10:25:49 -0700 (PDT) From: Calvin Owens To: linux-kernel@vger.kernel.org Cc: Rodolfo Giometti , Greg Kroah-Hartman Subject: [PATCH v2] pps: Don't allow PPS_KC_BIND on removed devices Date: Wed, 3 Jun 2026 10:25:44 -0700 Message-ID: <672778c177ac9b6fdcb445e35c97ac4ca7d1149f.1780506611.git.calvin@wbinvd.org> X-Mailer: git-send-email 2.47.3 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If userspace holds its file descriptor open, it can call PPS_KC_BIND on a device which has been unplugged, leaving pps_kc_hardpps_dev as a dangling pointer after close(). After that sequence, PPS_KC_BIND is broken until the system is rebooted, because the pointer comparison in pps_kc_bind() can never be true. calling pps_ktimer_init+0x0/0x1000 [pps_ktimer] @ 1081 initcall pps_ktimer_init+0x0/0x1000 [pps_ktimer] returned 0 after 811 u= secs pps pps0: bound kernel consumer: edge=3D0x1 pps pps0: unbound kernel consumer on device removal pps pps0: bound kernel consumer: edge=3D0x1 calling pps_ktimer_init+0x0/0x1000 [pps_ktimer] @ 1085 initcall pps_ktimer_init+0x0/0x1000 [pps_ktimer] returned 0 after 340 u= secs pps pps0: another kernel consumer is already bound Here is a short reproducer, which uses rmmod of the pps-ktimer testcase to simulate a device being unplugged: #include #include #include #include #include #include #include #include int main(void) { while (1) { int fd; if (system("insmod ./pps-ktimer.ko")) err(1, "insmod failed"); fd =3D open("/dev/pps0", O_RDWR); if (fd =3D=3D -1) err(1, "open failed"); struct pps_bind_args args =3D { .tsformat =3D PPS_TSFMT_TSPEC, .edge =3D PPS_CAPTUREASSERT, .consumer =3D PPS_KC_HARDPPS, }; if (ioctl(fd, PPS_KC_BIND, &args)) err(1, "first PPS_KC_BIND failed"); if (system("rmmod pps-ktimer")) err(1, "rmmod failed"); if (ioctl(fd, PPS_KC_BIND, &args)) { if (errno !=3D ENODEV) err(1, "second PPS_KC_BIND failed"); else puts("Got ENODEV, kernel is patched"); } close(fd); } } Fix this by setting a flag when the device is unplugged, returning -ENODEV from PPS_KC_BIND if the flag is set. For userspace to encounter this new behavior, it must do something which breaks the interface today, so this fix shouldn't cause any observable behavior change for working programs. Reported-by: Sashiko Closes: https://sashiko.dev/#/patchset/cover.1779733602.git.calvin%40wbinvd= .org?part=3D1 Signed-off-by: Calvin Owens Acked-by: Rodolfo Giometti --- Changes in v2: * Drop guard() changes so irqs are unmasked for printk() calls [Rodolfo] v1: https://lore.kernel.org/lkml/c9bfee54cbabbbfc8da7aa3d3893cf61d3ebf3b2.1= 780108479.git.calvin@wbinvd.org/ drivers/pps/kc.c | 10 ++++++++++ include/linux/pps_kernel.h | 1 + 2 files changed, 11 insertions(+) diff --git a/drivers/pps/kc.c b/drivers/pps/kc.c index fbd23295afd7..4f8fffa7edd6 100644 --- a/drivers/pps/kc.c +++ b/drivers/pps/kc.c @@ -38,6 +38,14 @@ int pps_kc_bind(struct pps_device *pps, struct pps_bind_= args *bind_args) /* Check if another consumer is already bound */ spin_lock_irq(&pps_kc_hardpps_lock); =20 + /* + * Don't allow PPS_KC_BIND on a removed device. + */ + if (pps->kc_removed) { + spin_unlock_irq(&pps_kc_hardpps_lock); + return -ENODEV; + } + if (bind_args->edge =3D=3D 0) if (pps_kc_hardpps_dev =3D=3D pps) { pps_kc_hardpps_mode =3D 0; @@ -79,6 +87,8 @@ int pps_kc_bind(struct pps_device *pps, struct pps_bind_a= rgs *bind_args) void pps_kc_remove(struct pps_device *pps) { spin_lock_irq(&pps_kc_hardpps_lock); + + pps->kc_removed =3D true; if (pps =3D=3D pps_kc_hardpps_dev) { pps_kc_hardpps_mode =3D 0; pps_kc_hardpps_dev =3D NULL; diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h index aab0aebb529e..3c2979f8a5ac 100644 --- a/include/linux/pps_kernel.h +++ b/include/linux/pps_kernel.h @@ -60,6 +60,7 @@ struct pps_device { struct device dev; struct fasync_struct *async_queue; /* fasync method */ spinlock_t lock; + bool kc_removed; }; =20 /* --=20 2.47.3