Package: release.debian.org Severity: normal Tags: trixie X-Debbugs-Cc: [email protected] Control: affects -1 + src:chrony User: [email protected] Usertags: pu
Hi, [ Reason ] A security fix introduced in Linux 6.15¹, and backported to Linux stable series down to version 5.10, prevents chronyd from starting if it is set up to use a PHC refclock configured with the 'extpps' option. [ Impact ] chronyd would fail to start when configured as aforementioned on a system featuring a kernel containing that security fix. More precisely, chronyd would output: "Fatal error : Could not enable external PHC timestamping" [ Tests ] After some required adjustments to 'upstream-simulation-test-suite' autopkgest, all the tests shipped by chrony pass. The proposed fix has also been successfully tested by the person who reported the bug. No regression has been observed. [ Risks ] As mentioned above, the proposed update is well tested so I would say that the risk of regression should be quite low. [ Checklist ] [x] *all* changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in (old)stable [x] the issue is verified as fixed in unstable [ Changes ] - The refclock_phc_open-device-for-writing-with-extpps-option.patch file is a backport of upstream patch (already available in chrony 4.8) to open the PHC reference clock with the O_RDWR flag when enabling the extpps option as recently required by the kernel. - The second change concerns the 'upstream-simulation-test-suite' autopkgtest that fails notably due to the patched open() call. [ Other info ] I will be filing an issue for bookworm to fix the same problem. Cheers, Vincent ¹ https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=97529630d85f910f4e6dfc615f1d111ada9448e3
diff -Nru chrony-4.6.1/debian/changelog chrony-4.6.1/debian/changelog --- chrony-4.6.1/debian/changelog 2025-06-03 17:16:37.000000000 +0200 +++ chrony-4.6.1/debian/changelog 2026-02-16 17:34:12.000000000 +0100 @@ -1,3 +1,14 @@ +chrony (4.6.1-3+deb13u1) trixie; urgency=medium + + * debian/patches/: + - Add refclock_phc_open-device-for-writing-with-extpps-option.patch. + Thanks to Jan Lübbe for the report. (Closes: #1127659) + + * debian/test/upstream-simulation-test-suite: + - Prevent simulation test failures. + + -- Vincent Blut <[email protected]> Mon, 16 Feb 2026 17:34:12 +0100 + chrony (4.6.1-3) unstable; urgency=medium * debian/patches/: diff -Nru chrony-4.6.1/debian/patches/refclock_phc_open-device-for-writing-with-extpps-option.patch chrony-4.6.1/debian/patches/refclock_phc_open-device-for-writing-with-extpps-option.patch --- chrony-4.6.1/debian/patches/refclock_phc_open-device-for-writing-with-extpps-option.patch 1970-01-01 01:00:00.000000000 +0100 +++ chrony-4.6.1/debian/patches/refclock_phc_open-device-for-writing-with-extpps-option.patch 2026-02-16 17:34:12.000000000 +0100 @@ -0,0 +1,104 @@ +Description: Open PHC device for writing with extpps option + In version 6.15 the Linux kernel started checking write access on the + PHC file descriptor in the PTP_PIN_SETFUNC and PTP_EXTTS_REQUEST ioctls. + chronyd opened the PHC device as readonly, which caused the PHC refclock + driver configured with the extpps option to fail with the + "Could not enable external PHC timestamping" error message. + + To ensure compatibility with new kernel versions, add flags to the + SYS_Linux_OpenPHC() function and open the device with the O_RDWR flag + when the extpps option is enabled. +Origin: backport, https://gitlab.com/chrony/chrony/-/commit/f78e4681eff71d941fab3be5ee406d920a155a20 +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1127659 +Last-Update: 2026-02-12 +--- +Index: chrony/ntp_io_linux.c +=================================================================== +--- chrony.orig/ntp_io_linux.c ++++ chrony/ntp_io_linux.c +@@ -220,7 +220,7 @@ add_interface(CNF_HwTsInterface *conf_if + + SCK_CloseSocket(sock_fd); + +- phc_fd = SYS_Linux_OpenPHC(NULL, ts_info.phc_index); ++ phc_fd = SYS_Linux_OpenPHC(NULL, ts_info.phc_index, O_RDONLY); + if (phc_fd < 0) + return 0; + +Index: chrony/refclock_phc.c +=================================================================== +--- chrony.orig/refclock_phc.c ++++ chrony/refclock_phc.c +@@ -66,7 +66,7 @@ static int phc_initialise(RCL_Instance i + { + const char *options[] = {"nocrossts", "extpps", "pin", "channel", "clear", NULL}; + struct phc_instance *phc; +- int phc_fd, rising_edge; ++ int rising_edge; + struct stat st; + char *path, *s; + +@@ -74,19 +74,20 @@ static int phc_initialise(RCL_Instance i + + path = RCL_GetDriverParameter(instance); + +- phc_fd = SYS_Linux_OpenPHC(path, 0); +- if (phc_fd < 0) +- LOG_FATAL("Could not open PHC"); +- + phc = MallocNew(struct phc_instance); +- phc->fd = phc_fd; +- if (fstat(phc_fd, &st) < 0 || !S_ISCHR(st.st_mode)) +- LOG_FATAL("Could not get PHC index"); +- phc->dev_index = minor(st.st_rdev); + phc->mode = 0; + phc->nocrossts = RCL_GetDriverOption(instance, "nocrossts") ? 1 : 0; + phc->extpps = RCL_GetDriverOption(instance, "extpps") ? 1 : 0; + UTI_ZeroTimespec(&phc->last_extts); ++ ++ phc->fd = SYS_Linux_OpenPHC(path, 0, phc->extpps ? O_RDWR : O_RDONLY); ++ if (phc->fd < 0) ++ LOG_FATAL("Could not open PHC"); ++ ++ if (fstat(phc->fd, &st) < 0 || !S_ISCHR(st.st_mode)) ++ LOG_FATAL("Could not get PHC index"); ++ phc->dev_index = minor(st.st_rdev); ++ + phc->clock = HCL_CreateInstance(0, 16, UTI_Log2ToDouble(RCL_GetDriverPoll(instance)), + RCL_GetPrecision(instance)); + +Index: chrony/sys_linux.c +=================================================================== +--- chrony.orig/sys_linux.c ++++ chrony/sys_linux.c +@@ -903,7 +903,7 @@ get_precise_phc_readings(int phc_fd, int + /* ================================================== */ + + int +-SYS_Linux_OpenPHC(const char *path, int phc_index) ++SYS_Linux_OpenPHC(const char *path, int phc_index, int flags) + { + struct ptp_clock_caps caps; + char phc_path[64]; +@@ -915,7 +915,7 @@ SYS_Linux_OpenPHC(const char *path, int + path = phc_path; + } + +- phc_fd = open(path, O_RDONLY); ++ phc_fd = open(path, flags); + if (phc_fd < 0) { + LOG(LOGS_ERR, "Could not open %s : %s", path, strerror(errno)); + return -1; +Index: chrony/sys_linux.h +=================================================================== +--- chrony.orig/sys_linux.h ++++ chrony/sys_linux.h +@@ -39,7 +39,7 @@ extern void SYS_Linux_EnableSystemCallFi + + extern int SYS_Linux_CheckKernelVersion(int req_major, int req_minor); + +-extern int SYS_Linux_OpenPHC(const char *path, int phc_index); ++extern int SYS_Linux_OpenPHC(const char *path, int phc_index, int flags); + + extern int SYS_Linux_GetPHCReadings(int fd, int nocrossts, int *reading_mode, int max_readings, + struct timespec tss[][3]); diff -Nru chrony-4.6.1/debian/patches/series chrony-4.6.1/debian/patches/series --- chrony-4.6.1/debian/patches/series 2025-06-03 17:16:37.000000000 +0200 +++ chrony-4.6.1/debian/patches/series 2026-02-16 17:34:12.000000000 +0100 @@ -1,3 +1,4 @@ +refclock_phc_open-device-for-writing-with-extpps-option.patch conf:_fix_sourcedir_reloading_to_not_multiply_sources.patch debianize-chronyd-restricted-unit-file.patch nm-dispatcher-dhcp_Move-server_dir-to-run.patch diff -Nru chrony-4.6.1/debian/tests/upstream-simulation-test-suite chrony-4.6.1/debian/tests/upstream-simulation-test-suite --- chrony-4.6.1/debian/tests/upstream-simulation-test-suite 2025-06-03 17:16:37.000000000 +0200 +++ chrony-4.6.1/debian/tests/upstream-simulation-test-suite 2026-02-16 17:34:12.000000000 +0100 @@ -27,6 +27,24 @@ tar -xvzf "$CLKNETSIM_PATH"/"$clknetsim_archive" \ -C "$CLKNETSIM_PATH" --strip-components=1 2>&1 || exit 77 + # Prevent simulation test failures introduced by + # refclock_phc_open-device-for-writing-with-extpps-option.patch + sed -i ' + 1498i\ + int __open_2(const char *pathname, int oflag) {\ + return open(pathname, oflag);\ + }\ + \ + int __open64_2(const char *pathname, int oflag) {\ + return open(pathname, oflag);\ + }\ + + 1538i\ + ssize_t __read_chk(int fd, void *buf, size_t count, size_t buflen) {\ + return read(fd, buf, count);\ + }\ + ' "$CLKNETSIM_PATH/client.c" + if [ ! -x "$CLKNETSIM_PATH/clknetsim" ] && [ ! -e "$CLKNETSIM_PATH/clknetsim.so" ]; then case "$DEB_BUILD_ARCH" in armel|armhf)
signature.asc
Description: PGP signature

