Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package ntpd-rs for openSUSE:Factory checked in at 2026-02-13 12:49:07 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ntpd-rs (Old) and /work/SRC/openSUSE:Factory/.ntpd-rs.new.1977 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ntpd-rs" Fri Feb 13 12:49:07 2026 rev:13 rq:1332804 version:1.7.1 Changes: -------- --- /work/SRC/openSUSE:Factory/ntpd-rs/ntpd-rs.changes 2026-01-30 18:34:24.880071957 +0100 +++ /work/SRC/openSUSE:Factory/.ntpd-rs.new.1977/ntpd-rs.changes 2026-02-13 12:49:12.408488612 +0100 @@ -1,0 +2,9 @@ +Thu Feb 12 19:30:03 UTC 2026 - Martin Hauke <[email protected]> + +- Update to version 1.7.1 + * Updated dependencies. + * Fixed issue that could result in excessive CPU usage on + receiving NTS messages asking for many cookies. + * Fixed network-triggerable log spam. + +------------------------------------------------------------------- Old: ---- ntpd-rs-1.7.0.tar.gz New: ---- ntpd-rs-1.7.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ntpd-rs.spec ++++++ --- /var/tmp/diff_new_pack.jH7v8B/_old 2026-02-13 12:49:14.480575393 +0100 +++ /var/tmp/diff_new_pack.jH7v8B/_new 2026-02-13 12:49:14.484575561 +0100 @@ -2,7 +2,7 @@ # spec file for package ntpd-rs # # Copyright (c) 2026 SUSE LLC and contributors -# Copyright (c) 2024-2027, Martin Hauke <[email protected]> +# Copyright (c) 2024-2026, Martin Hauke <[email protected]> # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,7 +19,7 @@ %define services ntpd-rs.service ntpd-rs-metrics.service Name: ntpd-rs -Version: 1.7.0 +Version: 1.7.1 Release: 0 Summary: Full-featured implementation of NTP with NTS support License: Apache-2.0 OR MIT ++++++ ntpd-rs-1.7.0.tar.gz -> ntpd-rs-1.7.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ntpd-rs-1.7.0/.github/workflows/checks.yaml new/ntpd-rs-1.7.1/.github/workflows/checks.yaml --- old/ntpd-rs-1.7.0/.github/workflows/checks.yaml 2026-01-30 11:31:48.000000000 +0100 +++ new/ntpd-rs-1.7.1/.github/workflows/checks.yaml 2026-02-12 15:44:16.000000000 +0100 @@ -263,6 +263,9 @@ - fuzz_target: ipfilter corpus: "" features: '' + - fuzz_target: handle + corpus: "" + features: '' - fuzz_target: key_exchange_response_parsing corpus: "" features: '' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ntpd-rs-1.7.0/CHANGELOG.md new/ntpd-rs-1.7.1/CHANGELOG.md --- old/ntpd-rs-1.7.0/CHANGELOG.md 2026-01-30 11:31:48.000000000 +0100 +++ new/ntpd-rs-1.7.1/CHANGELOG.md 2026-02-12 15:44:16.000000000 +0100 @@ -1,5 +1,14 @@ # Changelog +## [1.7.1] + +### Changed +- Updated dependencies. + +### Fixed +- Fixed issue that could result in excessive CPU usage on receiving NTS messages asking for many cookies. +- Fixed network-triggerable log spam. + ## [1.7.0] ### Added diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ntpd-rs-1.7.0/Cargo.lock new/ntpd-rs-1.7.1/Cargo.lock --- old/ntpd-rs-1.7.0/Cargo.lock 2026-01-30 11:31:48.000000000 +0100 +++ new/ntpd-rs-1.7.1/Cargo.lock 2026-02-12 15:44:16.000000000 +0100 @@ -57,9 +57,9 @@ [[package]] name = "aws-lc-sys" -version = "0.37.0" +version = "0.37.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c34dda4df7017c8db52132f0f8a2e0f8161649d15723ed63fc00c82d0f2081a" +checksum = "b092fe214090261288111db7a2b2c2118e5a7f30dc2569f1732c4069a6840549" dependencies = [ "cc", "cmake", @@ -84,15 +84,15 @@ [[package]] name = "bytes" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cc" -version = "1.2.54" +version = "1.2.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6354c81bbfd62d9cfa9cb3c773c2b7b2a3a482d569de977fd0e961f6e7c00583" +checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" dependencies = [ "find-msvc-tools", "jobserver", @@ -240,9 +240,9 @@ [[package]] name = "find-msvc-tools" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "fs_extra" @@ -354,9 +354,9 @@ [[package]] name = "libc" -version = "0.2.180" +version = "0.2.181" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" +checksum = "459427e2af2b9c839b132acb702a1c654d95e10f8c326bfc2ad11310e458b1c5" [[package]] name = "log" @@ -376,9 +376,9 @@ [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "mio" @@ -393,7 +393,7 @@ [[package]] name = "ntp-proto" -version = "1.7.0" +version = "1.7.1" dependencies = [ "aead", "aes-siv", @@ -412,7 +412,7 @@ [[package]] name = "ntpd" -version = "1.7.0" +version = "1.7.1" dependencies = [ "clock-steering", "libc", @@ -916,9 +916,9 @@ [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" [[package]] name = "untrusted" @@ -1232,18 +1232,18 @@ [[package]] name = "zerocopy" -version = "0.8.34" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71ddd76bcebeed25db614f82bf31a9f4222d3fbba300e6fb6c00afa26cbd4d9d" +checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.34" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8187381b52e32220d50b255276aa16a084ec0a9017a0ca2152a1f55c539758d" +checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" dependencies = [ "proc-macro2", "quote", @@ -1258,6 +1258,6 @@ [[package]] name = "zmij" -version = "1.0.17" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02aae0f83f69aafc94776e879363e9771d7ecbffe2c7fbb6c14c5e00dfe88439" +checksum = "4de98dfa5d5b7fef4ee834d0073d560c9ca7b6c46a71d058c48db7960f8cfaf7" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ntpd-rs-1.7.0/Cargo.toml new/ntpd-rs-1.7.1/Cargo.toml --- old/ntpd-rs-1.7.0/Cargo.toml 2026-01-30 11:31:48.000000000 +0100 +++ new/ntpd-rs-1.7.1/Cargo.toml 2026-02-12 15:44:16.000000000 +0100 @@ -10,7 +10,7 @@ # Global settings for our crates [workspace.package] -version = "1.7.0" +version = "1.7.1" edition = "2024" license = "Apache-2.0 OR MIT" repository = "https://github.com/pendulum-project/ntpd-rs" @@ -58,4 +58,4 @@ # our own crates used as dependencies, same version as the workspace version # NOTE: keep this part at the bottom of the file, do not change this line -ntp-proto = { version = "1.7.0", path = "./ntp-proto", default-features = false, features = ["__internal-api"] } +ntp-proto = { version = "1.7.1", path = "./ntp-proto", default-features = false, features = ["__internal-api"] } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ntpd-rs-1.7.0/docs/man/ntp-ctl.8.md new/ntpd-rs-1.7.1/docs/man/ntp-ctl.8.md --- old/ntpd-rs-1.7.0/docs/man/ntp-ctl.8.md 2026-01-30 11:31:48.000000000 +0100 +++ new/ntpd-rs-1.7.1/docs/man/ntp-ctl.8.md 2026-02-12 15:44:16.000000000 +0100 @@ -1,5 +1,5 @@ <!-- --- -title: NTP-CTL(8) ntpd-rs 1.7.0 | ntpd-rs +title: NTP-CTL(8) ntpd-rs 1.7.1 | ntpd-rs --- --> # NAME diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ntpd-rs-1.7.0/docs/man/ntp-daemon.8.md new/ntpd-rs-1.7.1/docs/man/ntp-daemon.8.md --- old/ntpd-rs-1.7.0/docs/man/ntp-daemon.8.md 2026-01-30 11:31:48.000000000 +0100 +++ new/ntpd-rs-1.7.1/docs/man/ntp-daemon.8.md 2026-02-12 15:44:16.000000000 +0100 @@ -1,5 +1,5 @@ <!-- --- -title: NTP-DAEMON(8) ntpd-rs 1.7.0 | ntpd-rs +title: NTP-DAEMON(8) ntpd-rs 1.7.1 | ntpd-rs --- --> # NAME diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ntpd-rs-1.7.0/docs/man/ntp-metrics-exporter.8.md new/ntpd-rs-1.7.1/docs/man/ntp-metrics-exporter.8.md --- old/ntpd-rs-1.7.0/docs/man/ntp-metrics-exporter.8.md 2026-01-30 11:31:48.000000000 +0100 +++ new/ntpd-rs-1.7.1/docs/man/ntp-metrics-exporter.8.md 2026-02-12 15:44:16.000000000 +0100 @@ -1,5 +1,5 @@ <!-- --- -title: NTP-METRICS-EXPORTER(8) ntpd-rs 1.7.0 | ntpd-rs +title: NTP-METRICS-EXPORTER(8) ntpd-rs 1.7.1 | ntpd-rs --- --> # NAME diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ntpd-rs-1.7.0/docs/man/ntp.toml.5.md new/ntpd-rs-1.7.1/docs/man/ntp.toml.5.md --- old/ntpd-rs-1.7.0/docs/man/ntp.toml.5.md 2026-01-30 11:31:48.000000000 +0100 +++ new/ntpd-rs-1.7.1/docs/man/ntp.toml.5.md 2026-02-12 15:44:16.000000000 +0100 @@ -1,5 +1,5 @@ <!-- --- -title: NTP.TOML(5) ntpd-rs 1.7.0 | ntpd-rs +title: NTP.TOML(5) ntpd-rs 1.7.1 | ntpd-rs --- --> # NAME diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ntpd-rs-1.7.0/docs/precompiled/man/ntp-ctl.8 new/ntpd-rs-1.7.1/docs/precompiled/man/ntp-ctl.8 --- old/ntpd-rs-1.7.0/docs/precompiled/man/ntp-ctl.8 2026-01-30 11:31:48.000000000 +0100 +++ new/ntpd-rs-1.7.1/docs/precompiled/man/ntp-ctl.8 2026-02-12 15:44:16.000000000 +0100 @@ -14,7 +14,7 @@ . ftr VB CB . ftr VBI CBI .\} -.TH "NTP-CTL" "8" "" "ntpd-rs 1.7.0" "ntpd-rs" +.TH "NTP-CTL" "8" "" "ntpd-rs 1.7.1" "ntpd-rs" .hy .SH NAME .PP diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ntpd-rs-1.7.0/docs/precompiled/man/ntp-daemon.8 new/ntpd-rs-1.7.1/docs/precompiled/man/ntp-daemon.8 --- old/ntpd-rs-1.7.0/docs/precompiled/man/ntp-daemon.8 2026-01-30 11:31:48.000000000 +0100 +++ new/ntpd-rs-1.7.1/docs/precompiled/man/ntp-daemon.8 2026-02-12 15:44:16.000000000 +0100 @@ -14,7 +14,7 @@ . ftr VB CB . ftr VBI CBI .\} -.TH "NTP-DAEMON" "8" "" "ntpd-rs 1.7.0" "ntpd-rs" +.TH "NTP-DAEMON" "8" "" "ntpd-rs 1.7.1" "ntpd-rs" .hy .SH NAME .PP diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ntpd-rs-1.7.0/docs/precompiled/man/ntp-metrics-exporter.8 new/ntpd-rs-1.7.1/docs/precompiled/man/ntp-metrics-exporter.8 --- old/ntpd-rs-1.7.0/docs/precompiled/man/ntp-metrics-exporter.8 2026-01-30 11:31:48.000000000 +0100 +++ new/ntpd-rs-1.7.1/docs/precompiled/man/ntp-metrics-exporter.8 2026-02-12 15:44:16.000000000 +0100 @@ -14,7 +14,7 @@ . ftr VB CB . ftr VBI CBI .\} -.TH "NTP-METRICS-EXPORTER" "8" "" "ntpd-rs 1.7.0" "ntpd-rs" +.TH "NTP-METRICS-EXPORTER" "8" "" "ntpd-rs 1.7.1" "ntpd-rs" .hy .SH NAME .PP diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ntpd-rs-1.7.0/docs/precompiled/man/ntp.toml.5 new/ntpd-rs-1.7.1/docs/precompiled/man/ntp.toml.5 --- old/ntpd-rs-1.7.0/docs/precompiled/man/ntp.toml.5 2026-01-30 11:31:48.000000000 +0100 +++ new/ntpd-rs-1.7.1/docs/precompiled/man/ntp.toml.5 2026-02-12 15:44:16.000000000 +0100 @@ -14,7 +14,7 @@ . ftr VB CB . ftr VBI CBI .\} -.TH "NTP.TOML" "5" "" "ntpd-rs 1.7.0" "ntpd-rs" +.TH "NTP.TOML" "5" "" "ntpd-rs 1.7.1" "ntpd-rs" .hy .SH NAME .PP diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ntpd-rs-1.7.0/fuzz/Cargo.lock new/ntpd-rs-1.7.1/fuzz/Cargo.lock --- old/ntpd-rs-1.7.0/fuzz/Cargo.lock 2026-01-30 11:31:48.000000000 +0100 +++ new/ntpd-rs-1.7.1/fuzz/Cargo.lock 2026-02-12 15:44:16.000000000 +0100 @@ -60,9 +60,9 @@ [[package]] name = "aws-lc-sys" -version = "0.37.0" +version = "0.37.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c34dda4df7017c8db52132f0f8a2e0f8161649d15723ed63fc00c82d0f2081a" +checksum = "b092fe214090261288111db7a2b2c2118e5a7f30dc2569f1732c4069a6840549" dependencies = [ "cc", "cmake", @@ -87,15 +87,15 @@ [[package]] name = "bytes" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cc" -version = "1.2.54" +version = "1.2.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6354c81bbfd62d9cfa9cb3c773c2b7b2a3a482d569de977fd0e961f6e7c00583" +checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" dependencies = [ "find-msvc-tools", "jobserver", @@ -244,14 +244,14 @@ checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.1", ] [[package]] name = "find-msvc-tools" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "fs_extra" @@ -335,15 +335,15 @@ [[package]] name = "libc" -version = "0.2.180" +version = "0.2.181" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" +checksum = "459427e2af2b9c839b132acb702a1c654d95e10f8c326bfc2ad11310e458b1c5" [[package]] name = "libfuzzer-sys" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5037190e1f70cbeef565bd267599242926f724d3b8a9f510fd7e0b540cfa4404" +checksum = "f12a681b7dd8ce12bff52488013ba614b869148d54dd79836ab85aafdd53f08d" dependencies = [ "arbitrary", "cc", @@ -376,9 +376,9 @@ [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "mio" @@ -393,7 +393,7 @@ [[package]] name = "ntp-proto" -version = "1.7.0-alpha.20260122" +version = "1.7.0" dependencies = [ "aead", "aes-siv", @@ -848,9 +848,9 @@ [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" [[package]] name = "untrusted" @@ -913,7 +913,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.1", ] [[package]] @@ -1155,18 +1155,18 @@ [[package]] name = "zerocopy" -version = "0.8.34" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71ddd76bcebeed25db614f82bf31a9f4222d3fbba300e6fb6c00afa26cbd4d9d" +checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.34" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8187381b52e32220d50b255276aa16a084ec0a9017a0ca2152a1f55c539758d" +checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" dependencies = [ "proc-macro2", "quote", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ntpd-rs-1.7.0/fuzz/Cargo.toml new/ntpd-rs-1.7.1/fuzz/Cargo.toml --- old/ntpd-rs-1.7.0/fuzz/Cargo.toml 2026-01-30 11:31:48.000000000 +0100 +++ new/ntpd-rs-1.7.1/fuzz/Cargo.toml 2026-02-12 15:44:16.000000000 +0100 @@ -55,6 +55,12 @@ doc = false [[bin]] +name = "handle" +path = "fuzz_targets/handle.rs" +test = false +doc = false + +[[bin]] name = "ipfilter" path = "fuzz_targets/ipfilter.rs" test = false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ntpd-rs-1.7.0/fuzz/fuzz_targets/handle.rs new/ntpd-rs-1.7.1/fuzz/fuzz_targets/handle.rs --- old/ntpd-rs-1.7.0/fuzz/fuzz_targets/handle.rs 1970-01-01 01:00:00.000000000 +0100 +++ new/ntpd-rs-1.7.1/fuzz/fuzz_targets/handle.rs 2026-02-12 15:44:16.000000000 +0100 @@ -0,0 +1,202 @@ +#![no_main] +#![expect(clippy::type_complexity)] + +use std::{ + borrow::Cow, + io::{Cursor, Write}, + net::IpAddr, + time::Duration, +}; + +use libfuzzer_sys::fuzz_target; +use ntp_proto::{ + test_cookie, + v5::{BloomFilter, ServerId}, + EncryptResult, ExtensionField, ExtensionHeaderVersion, FilterAction, FilterList, + HandleInnerData, KeySetProvider, NtpClock, NtpDuration, NtpLeapIndicator, NtpTimestamp, + NtpVersion, ReferenceId, Server, ServerConfig, ServerReason, ServerResponse, ServerStatHandler, + SystemSnapshot, TimeSnapshot, +}; +use rand::{rngs::StdRng, set_thread_rng, SeedableRng}; + +const fn next_multiple_of(lhs: u16, rhs: u16) -> u16 { + match lhs % rhs { + 0 => lhs, + r => lhs + (rhs - r), + } +} + +fuzz_target!(|parts: ( + Vec<u8>, + u64, + [u8; 4], + Option<(Vec<u8>, Vec<u8>, Vec<u8>, ExtensionHeaderVersion)> +)| { + set_thread_rng(StdRng::seed_from_u64(parts.1)); + + // Can't test reencoding because of the keyset + let provider = KeySetProvider::dangerous_new_deterministic(1); + + let keyset = provider.get(); + + let mut cursor = Cursor::new([0u8; 8192]); + + let message = if let Some(encrypted) = parts.3 { + // Build packet + let _ = cursor.write_all(&parts.0); + let cookie = test_cookie(); + let enc_cookie = keyset.encode_cookie_pub(&cookie); + let _ = ExtensionField::NtsCookie(Cow::Borrowed(&enc_cookie)).serialize_pub( + &mut cursor, + 4, + encrypted.3, + ); + let _ = cursor.write_all(&encrypted.0); + + let mut ciphertext = encrypted.1.clone(); + ciphertext.resize(ciphertext.len() + 32, 0); + let EncryptResult { + nonce_length, + ciphertext_length, + } = cookie + .c2s + .encrypt( + &mut ciphertext, + encrypted.1.len(), + &cursor.get_ref()[..cursor.position() as usize], + ) + .unwrap(); + + let _ = cursor.write_all(&0x404u16.to_be_bytes()); + let _ = cursor.write_all( + &(8 + next_multiple_of((nonce_length + ciphertext_length) as u16, 4)).to_be_bytes(), + ); + let _ = cursor.write_all(&(nonce_length as u16).to_be_bytes()); + let _ = cursor.write_all(&(ciphertext_length as u16).to_be_bytes()); + let _ = cursor.write_all(&ciphertext); + let _ = cursor.write_all(&encrypted.2); + cursor.get_ref() + } else { + let _ = cursor.write_all(&parts.0); + cursor.get_ref() + }; + + let denylist = FilterList { + filter: vec!["1.0.0.0/24".parse().unwrap()], + action: FilterAction::Ignore, + }; + + let allowlist = FilterList { + filter: vec!["1.0.0.0/8".parse().unwrap()], + action: FilterAction::Deny, + }; + + let ip = IpAddr::from(parts.2); + + let mut server = Server::new( + ServerConfig { + denylist, + allowlist, + rate_limiting_cache_size: 0, + rate_limiting_cutoff: Duration::from_secs(1), + require_nts: None, + accepted_versions: vec![NtpVersion::V3, NtpVersion::V4, NtpVersion::V5], + }, + TestClock { + cur: NtpTimestamp::from_seconds_nanos_since_ntp_era(100, 0), + }, + SystemSnapshot { + stratum: 1, + reference_id: ReferenceId::NONE, + accumulated_steps_threshold: Some(NtpDuration::from_seconds(0.0)), + time_snapshot: TimeSnapshot { + precision: NtpDuration::from_seconds(0.00001), + root_delay: NtpDuration::from_seconds(0.01), + root_variance_base_time: NtpTimestamp::from_seconds_nanos_since_ntp_era(90, 0), + root_variance_base: 1e-9, + root_variance_linear: 0.0, + root_variance_quadratic: 0.0, + root_variance_cubic: 0.0, + leap_indicator: NtpLeapIndicator::NoWarning, + accumulated_steps: NtpDuration::from_seconds(0.0), + }, + bloom_filter: BloomFilter::new(), + server_id: ServerId::new(&mut rand::thread_rng()), + }, + keyset, + ); + + let mut buffer = [0u8; 8192]; + + if let Ok(HandleInnerData { + packet, + cipher, + desired_size, + .. + }) = server.fuzz_handle_inner( + ip, + NtpTimestamp::from_seconds_nanos_since_ntp_era(99, 900000000), + message, + &mut TestStatHandler, + ) { + let mut cursor = Cursor::new(&mut buffer[..message.len()]); + assert!(packet + .serialize(&mut cursor, &cipher.as_deref(), desired_size) + .is_ok()); + } +}); + +#[derive(Debug, Clone, Default)] +struct TestClock { + cur: NtpTimestamp, +} + +impl NtpClock for TestClock { + type Error = std::time::SystemTimeError; + + fn now(&self) -> std::result::Result<NtpTimestamp, Self::Error> { + Ok(self.cur) + } + + fn set_frequency(&self, _freq: f64) -> Result<NtpTimestamp, Self::Error> { + panic!("Shouldn't be called by server"); + } + + fn get_frequency(&self) -> Result<f64, Self::Error> { + Ok(0.0) + } + + fn step_clock(&self, _offset: NtpDuration) -> Result<NtpTimestamp, Self::Error> { + panic!("Shouldn't be called by server"); + } + + fn disable_ntp_algorithm(&self) -> Result<(), Self::Error> { + panic!("Shouldn't be called by server"); + } + + fn error_estimate_update( + &self, + _est_error: NtpDuration, + _max_error: NtpDuration, + ) -> Result<(), Self::Error> { + panic!("Shouldn't be called by server"); + } + + fn status_update(&self, _leap_status: NtpLeapIndicator) -> Result<(), Self::Error> { + panic!("Shouldn't be called by source"); + } +} + +#[derive(Debug, Default)] +struct TestStatHandler; + +impl ServerStatHandler for TestStatHandler { + fn register( + &mut self, + _version: u8, + _nts: bool, + _reason: ServerReason, + _response: ServerResponse, + ) { + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ntpd-rs-1.7.0/ntp-proto/src/lib.rs new/ntpd-rs-1.7.1/ntp-proto/src/lib.rs --- old/ntpd-rs-1.7.0/ntp-proto/src/lib.rs 2026-01-30 11:31:48.000000000 +0100 +++ new/ntpd-rs-1.7.1/ntp-proto/src/lib.rs 2026-02-12 15:44:16.000000000 +0100 @@ -240,6 +240,8 @@ Cipher, CipherProvider, EncryptResult, ExtensionHeaderVersion, NoCipher, NtpAssociationMode, NtpLeapIndicator, NtpPacket, PacketParsingError, }; + #[cfg(feature = "__internal-fuzz")] + pub use super::server::HandleInnerData; pub use super::server::{ FilterAction, FilterList, IpSubnet, Server, ServerAction, ServerConfig, ServerReason, ServerResponse, ServerStatHandler, SubnetParseError, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ntpd-rs-1.7.0/ntp-proto/src/packet/mod.rs new/ntpd-rs-1.7.1/ntp-proto/src/packet/mod.rs --- old/ntpd-rs-1.7.0/ntp-proto/src/packet/mod.rs 2026-01-30 11:31:48.000000000 +0100 +++ new/ntpd-rs-1.7.1/ntp-proto/src/packet/mod.rs 2026-02-12 15:44:16.000000000 +0100 @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use crate::{ - NtpVersion, + MAX_COOKIES, NtpVersion, clock::NtpClock, identifiers::ReferenceId, io::NonBlockingWrite, @@ -477,7 +477,9 @@ mac.serialize(&mut *w)?; } - if let Some(desired_size) = desired_size { + if matches!(self.header, NtpHeader::V5(_)) + && let Some(desired_size) = desired_size + { let written = (w.position() - start) as usize; if desired_size > written { ExtensionField::Padding(desired_size - written).serialize( @@ -708,6 +710,7 @@ }) } + #[allow(clippy::too_many_lines)] pub fn nts_timestamp_response<C: NtpClock>( system: &SystemSnapshot, input: Self, @@ -731,6 +734,7 @@ .authenticated .iter() .chain(input.efdata.encrypted.iter()) + .take(MAX_COOKIES) .filter_map(|f| match f { ExtensionField::NtsCookiePlaceholder { cookie_length } => { let new_cookie = keyset.encode_cookie(cookie); @@ -775,6 +779,7 @@ .authenticated .iter() .chain(input.efdata.encrypted.iter()) + .take(MAX_COOKIES) .filter_map(|f| match f { ExtensionField::NtsCookiePlaceholder { cookie_length } => { let new_cookie = keyset.encode_cookie(cookie); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ntpd-rs-1.7.0/ntp-proto/src/server.rs new/ntpd-rs-1.7.1/ntp-proto/src/server.rs --- old/ntpd-rs-1.7.0/ntp-proto/src/server.rs 2026-01-30 11:31:48.000000000 +0100 +++ new/ntpd-rs-1.7.1/ntp-proto/src/server.rs 2026-02-12 15:44:16.000000000 +0100 @@ -10,7 +10,7 @@ use serde::{Deserialize, Deserializer, de}; use crate::{ - KeySet, NoCipher, NtpClock, NtpPacket, NtpTimestamp, NtpVersion, PacketParsingError, + Cipher, KeySet, NtpClock, NtpPacket, NtpTimestamp, NtpVersion, PacketParsingError, SystemSnapshot, ipfilter::IpFilter, }; @@ -164,14 +164,22 @@ } } +pub struct HandleInnerData<'a> { + pub action: ServerResponse, + pub reason: ServerReason, + pub version: NtpVersion, + pub nts: bool, + pub packet: NtpPacket<'a>, + pub cipher: Option<Box<dyn Cipher>>, + pub desired_size: Option<usize>, +} + impl<C: NtpClock> Server<C> { /// Handle a packet sent to the server /// /// If the buffer isn't large enough to encode the reply, this /// will log an error and ignore the incoming packet. A buffer /// as large as the message will always suffice. - // FIXME: Figure out a way to simplify or split this function - #[expect(clippy::too_many_lines)] pub fn handle<'a>( &mut self, client_ip: IpAddr, @@ -180,12 +188,55 @@ buffer: &'a mut [u8], stats_handler: &mut impl ServerStatHandler, ) -> ServerAction<'a> { - let (mut action, mut reason) = self.intended_action(client_ip); + let HandleInnerData { + action, + reason, + version, + nts, + packet, + cipher, + desired_size, + } = match self.handle_inner(client_ip, recv_timestamp, message, stats_handler) { + Ok(value) => value, + Err(value) => return value, + }; + + let mut cursor = Cursor::new(buffer); + match packet.serialize(&mut cursor, &cipher.as_deref(), desired_size) { + Ok(_) => { + stats_handler.register(version.into(), nts, reason, action); + let length = cursor.position(); + ServerAction::Respond { + message: &cursor.into_inner()[..length as _], + } + } + Err(e) => { + tracing::debug!("Could not serialize response: {}", e); + stats_handler.register( + version.into(), + nts, + ServerReason::InternalError, + ServerResponse::Ignore, + ); + ServerAction::Ignore + } + } + } + // FIXME: Figure out a way to split this + #[expect(clippy::too_many_lines)] + fn handle_inner<'a>( + &mut self, + client_ip: IpAddr, + recv_timestamp: NtpTimestamp, + message: &'a [u8], + stats_handler: &mut impl ServerStatHandler, + ) -> Result<HandleInnerData<'a>, ServerAction<'static>> { + let (mut action, mut reason) = self.intended_action(client_ip); if action == ServerResponse::Ignore { // Early exit for ignore stats_handler.register(fallback_message_version(message), false, reason, action); - return ServerAction::Ignore; + return Err(ServerAction::Ignore); } // Try and parse the message @@ -199,7 +250,7 @@ ServerReason::ParseError, ServerResponse::Ignore, ); - return ServerAction::Ignore; + return Err(ServerAction::Ignore); } }, Err(PacketParsingError::DecryptError(packet)) => { @@ -217,7 +268,7 @@ ServerReason::ParseError, ServerResponse::Ignore, ); - return ServerAction::Ignore; + return Err(ServerAction::Ignore); } }; @@ -232,7 +283,7 @@ ServerReason::Policy, ServerResponse::Ignore, ); - return ServerAction::Ignore; + return Err(ServerAction::Ignore); } let nts = cookie.is_some() || action == ServerResponse::NTSNak; @@ -246,69 +297,71 @@ ServerReason::Policy, ServerResponse::Ignore, ); - return ServerAction::Ignore; + return Err(ServerAction::Ignore); } action = ServerResponse::Deny; reason = ServerReason::Policy; } - let mut cursor = Cursor::new(buffer); - let result = match action { - ServerResponse::NTSNak => { - NtpPacket::nts_nak_response(packet).serialize(&mut cursor, &NoCipher, None) - } + let (packet, cipher, desired_size) = match action { + ServerResponse::NTSNak => (NtpPacket::nts_nak_response(packet), None, None), ServerResponse::Deny => { if let Some(cookie) = cookie { - NtpPacket::nts_deny_response(packet).serialize( - &mut cursor, - cookie.s2c.as_ref(), - None, - ) + (NtpPacket::nts_deny_response(packet), Some(cookie.s2c), None) } else { - NtpPacket::deny_response(packet).serialize(&mut cursor, &NoCipher, None) + (NtpPacket::deny_response(packet), None, None) } } ServerResponse::ProvideTime => { if let Some(cookie) = cookie { - NtpPacket::nts_timestamp_response( - &self.system, - packet, - recv_timestamp, - &self.clock, - &cookie, - &self.keyset, - ) - .serialize( - &mut cursor, - cookie.s2c.as_ref(), + ( + NtpPacket::nts_timestamp_response( + &self.system, + packet, + recv_timestamp, + &self.clock, + &cookie, + &self.keyset, + ), + Some(cookie.s2c), Some(message.len()), ) } else { - NtpPacket::timestamp_response(&self.system, packet, recv_timestamp, &self.clock) - .serialize(&mut cursor, &NoCipher, Some(message.len())) + ( + NtpPacket::timestamp_response( + &self.system, + packet, + recv_timestamp, + &self.clock, + ), + None, + Some(message.len()), + ) } } ServerResponse::Ignore => unreachable!(), }; - match result { - Ok(_) => { - stats_handler.register(version.into(), nts, reason, action); - let length = cursor.position(); - ServerAction::Respond { - message: &cursor.into_inner()[..length as _], - } - } - Err(e) => { - tracing::error!("Could not serialize response: {}", e); - stats_handler.register( - version.into(), - nts, - ServerReason::InternalError, - ServerResponse::Ignore, - ); - ServerAction::Ignore - } - } + + Ok(HandleInnerData { + action, + reason, + version, + nts, + packet, + cipher, + desired_size, + }) + } + + #[cfg(feature = "__internal-fuzz")] + pub fn fuzz_handle_inner<'a>( + &mut self, + client_ip: IpAddr, + recv_timestamp: NtpTimestamp, + message: &'a [u8], + stats_handler: &mut impl ServerStatHandler, + ) -> Result<HandleInnerData<'a>, ServerAction<'static>> { + self.handle_inner(client_ip, recv_timestamp, message, stats_handler) } } @@ -442,7 +495,7 @@ use std::net::{Ipv4Addr, Ipv6Addr}; use crate::{ - Cipher, DecodedServerCookie, KeySetProvider, NtpDuration, NtpLeapIndicator, + Cipher, DecodedServerCookie, KeySetProvider, NoCipher, NtpDuration, NtpLeapIndicator, PollIntervalLimits, nts::AeadAlgorithm, packet::AesSivCmac256, }; ++++++ vendor.tar.zst ++++++ /work/SRC/openSUSE:Factory/ntpd-rs/vendor.tar.zst /work/SRC/openSUSE:Factory/.ntpd-rs.new.1977/vendor.tar.zst differ: char 7, line 1
