-
sdwdate-1.0.0-8 Stable
released this
2026-07-11 21:02:16 +02:00 | 0 commits to main since this releasesdwdate (LainOS Layer 02 port) ~ Changelog
1.0.0-8 ~ /etc/adjtime permission fix
Bug Fix
- Fixed
hwclock: cannot open /etc/adjtime: Permission denied, occurring afterhwclock --systohcsuccessfully ran (following the 1.0.0-5 fix) but couldn't read/write its clock-drift calibration file./etc/adjtimedefaults to0644, root-owned, with no group access. - Fix: added a
checkpathcall in the init script'sstart_pre()granting group access (root:sdwdate, mode0664). - An initial attempt at this fix (in 1.0.0-7, not separately released) used
checkpath -g sdwdate, an option that doesn't exist ~checkpathhas no-gflag. Corrected tocheckpath -f -m 0664 -o root:sdwdate /etc/adjtime, using-o user:groupinstead. - Verified end-to-end: forced a full service restart (guaranteeing a first-sync, which always uses the instant
/bin/date+hwclockpath regardless of correction size), confirmed the log showsInstantly setting the time, a successful/bin/date output, and noadjtimeerror ~hwclock --systohccompleted silently and successfully this time.
This is the third and final permission gap found through fresh-install testing in a clean KVM guest (after the RTC device access and
hwclockCAP_SYS_TIMEgrant in 1.0.0-5). All three were only caught by testing on a genuinely clean install rather than continuing to iterate on an already-patched development machine.
Downloads
- Fixed
-
sdwdate-1.0.0-6 Stable
released this
2026-07-11 20:33:18 +02:00 | 1 commits to main since this releasesdwdate (LainOS Layer 02 port) ~ Changelog
1.0.0-6 ~ Tor consensus check fix (fresh installs)
Bug Fix
- Fixed
Tor Consensus Time Sanity Check: error: Could not request from Tor control connection. error: <class 'AttributeError'>on fresh installs, causing every time source to reportremote_status: Falseand fail. Root cause: thesdwdatesystem user was never added to thetorgroup, so it couldn't read Tor's control-port authentication cookie (/var/lib/tor/control_auth_cookie, mode0640, ownedtor:tor) needed for the consensus check. This fix had previously only been applied manually, live, on one already-installed system, and was never actually added to the package itself. - Fix: added
usermod -aG tor sdwdateto both the package'spost_install/post_upgradehooks and the OpenRC init script'sstart_pre()~ the latter for the same Calamares-chroot reliability reason established for the log file fix in 1.0.0-3 (install-time hooks have been found not to reliably survive Calamares' chroot-based install process; init-script-time fixes run fresh on every start regardless of install method). - Verified end-to-end on a fresh KVM ISO install: confirmed
sdwdatewas missing from thetorgroup before the fix, rebuilt and reinstalled the package, forced a full service restart, confirmed group membership took effect (id sdwdateshowingtorin the group list), and observed a complete sync cycle withTor Consensus Time Sanity Check: saneon all three contacted onion sources.
Note: this bug and the 1.0.0-5 hardware clock fix were both found through genuine fresh-install testing in a KVM guest, not by continuing to test on an already-patched development machine ~ neither would have surfaced from further testing on a system that had already accumulated manual live fixes.
Downloads
- Fixed
-
sdwdate-1.0.0-5 Stable
released this
2026-07-11 19:43:32 +02:00 | 2 commits to main since this releasesdwdate (LainOS Layer 02 port) ~ Changelog
1.0.0-5 ~ Hardware clock sync fix
Bug Fix
- Fixed
FileNotFoundError: [Errno 2] No such file or directory: '/usr/bin/leaprun'during a real sync cycle. Two call sites insdwdate.py(run_sclockadj_and_hwclock()andrun_sclockadj()) shell out toleaprun sdwdate-sync-hwclockafter applying a time correction, to sync the hardware clock (hwclock --systohc) so the correction survives a reboot.leaprunis part of Kicksecure's privleap privilege-delegation tool, not used on LainOS ~ this call site was missed during the initial port (the CLI wrapper'sleapruncall was caught and fixed earlier; these two daemon-internal calls were not). - Fix: patched both call sites to invoke
/usr/bin/hwclock --systohcdirectly. - This surfaced a second, distinct permission issue:
hwclock: ioctl(RTC_SET_TIME) to /dev/rtc to set the time failed: Permission denied./dev/rtc0wasroot-only (0600) with no group access, and even after granting access, theRTC_SET_TIMEioctl itself additionally requires the calling process to holdCAP_SYS_TIMEbeyond plain file permissions. - Fix:
- Added a udev rule (
99-lainos-sdwdate-rtc.rules) granting thesdwdategroup read/write access to/dev/rtc0(mode0660). - Granted
CAP_SYS_TIMEto/usr/bin/hwclockviasetcap, alongside the existing grants forsdwdate,sclockadj, and/bin/date.
- Added a udev rule (
- Verified end-to-end from a clean package install: forced a real 30-second clock discrepancy, triggered a fresh sync, confirmed
sclockadjcompleted,Syncing hardware clocklogged with no error, and the sync loop returned to its normal sleep cycle ~ the full corrected chain, not just a zero-diff no-op.
Downloads
- Fixed
-
sdwdate-1.0.0-4 Stable
released this
2026-07-11 17:49:46 +02:00 | 3 commits to main since this releasesdwdate (lainOS layer 02 port) ~ Changelog
1.0.0-4 ~ First-sync permission fix
Bug Fix
- Fixed
date: cannot set date: Operation not permittedon sdwdate's first successful sync after being enabled (or after any hard clock-jump correction). sdwdate's own code (set_time_using_date()insdwdate.py) shells out directly to/bin/date --setfor the first sync and any explicit hard jump, rather than the gradualsclockadjpath used for all subsequent, smaller corrections. This path was missing theCAP_SYS_TIMEcapability grant thatsdwdateandsclockadjalready had. - Fix: granted
CAP_SYS_TIMEto/bin/dateviasetcapin the init script'sstart_pre(), alongside the existing grants forsdwdateandsclockadj. - Note on scope: unlike the other two
setcapgrants (which apply to single-purpose binaries only thesdwdateuser ever invokes),/bin/dateis a general system utility used by every user on the system. This capability grant is file-wide, meaning any local user could technically usedate --setto change the system clock, not just thesdwdatedaemon.CAP_SYS_TIMEalone grants no other capability (no file access, no broader privilege escalation path), and this was accepted as a reasonable, documented tradeoff rather than patching upstream's source to avoid the/bin/datecall entirely for the first-sync case. Commented clearly in the init script for future reference. - Verified fixed: a forced first-sync (via
lainos-sdwdate disable/enable) completed successfully with the correction applied and no permission error.
Downloads
- Fixed
-
sdwdate-1.0.0-3 Stable
released this
2026-07-10 22:58:57 +02:00 | 3 commits to main since this releasesdwdate (lainOS layer 02 port) ~ Changelog
1.0.0-3 ~ Fresh-install log permission fix
Bug Fix
- Fixed
start-stop-daemon: unable to open the logfile for stdout '/var/log/sdwdate.log': Permission deniedon fresh installs. The package'spost_installhook correctly creates and chowns/var/log/sdwdate.log, but this was found not to reliably survive Calamares' ISO install-time chroot execution ~ confirmed present via a livepacman -Uon an already-running system, but absent on a fresh Calamares-installed system despite the install script containing identicaltouch/chownlogic. - Moved log file creation into the OpenRC init script's
start_pre()(viacheckpath -f), matching the existing, already-reliable pattern used for/run/sdwdate,/var/lib/sdwdate, and/var/lib/sdwdate-forbidden-temp. This runs fresh on every service start regardless of install method, rather than depending on a one-time install hook. - Verified fixed end-to-end on a fresh ISO install:
checkpathcorrectly creates and owns the log file,sdwdatestarts cleanly,lainos-sdwdate statusreports it running.
Downloads
- Fixed
-
sdwdate-1.0.0-1 Stable
released this
2026-07-10 18:19:31 +02:00 | 7 commits to main since this releasesdwdate (lainOS layer 02 port) ~ Changelog
1.0.0-1 (2026-07-10) ~ Initial port
First working LainOS Layer 02 / OpenRC port of Kicksecure's sdwdate.
Ported from upstream (GPLv3):
- Core Python daemon and
sclockadjC helper (compiled with upstream's full hardened compiler flag set) - Default time-source pool configuration
url_to_unixtimeper-source fetcher
New, LainOS-native components (not vendored from Kicksecure):
sanitize_string/guimessages.translations~ minimal reimplementations of two cosmetic Kicksecure helper packageslainos-minimum-unixtime-show~ reimplementation of the anti-replay-protection floor-timestamp mechanism (replaces Kicksecure'stimesanitycheckpackage dependency)lainos-onion-time-pre-script~ no-op replacement for upstream's privleap/AppArmor-dependent Tor-restart-request signaling (not applicable on LainOS)- OpenRC init script, translated from upstream's systemd unit:
need tor/after tordependency ordering,setcap cap_sys_time+epin place ofAmbientCapabilities=CAP_SYS_TIME, required runtime directories created instart_pre()
Deliberately not ported: AppArmor profiles, privleap integration, Qubes-specific conditionals, the Tor-restart-request file-watcher mechanism, and dev-only test scripts. See README for full rationale on each.
Known gaps relative to upstream:
- No seccomp/
SystemCallFilterequivalent yet (OpenRC has no direct translation; a wrapper-based approach similar toprotocol7-core's daemons would be needed) - Tor-restart-on-request is not implemented (daemon runs fine without it; only affects the specific edge case upstream's file-watcher mechanism handles)
Verified working end-to-end (2026-07-10): real onion time sources contacted over Tor, Tor consensus sanity checks passing, correct median computation across sources,
sclockadjcorrectly applying a real (small) gradual clock correction, all with a genuinely accurate result.Companion change (in
lainos-utils): addedlainos-sdwdatetoggle script (enable/disable/status) to switch betweenchrony(default) andsdwdate, since sdwdate has no fallback if Tor is unreachable and the two should not run simultaneously.
Bugs found and fixed during initial porting/testing
For reference, the real issues found getting this daemon running for the first time, each confirmed via actual testing rather than assumed:
/usr/bin/sdwdate(the interactive CLI wrapper) callsleaprun, a privleap command not present on LainOS ~ resolved by pointing the OpenRC service at the real daemon entry point (/usr/libexec/sdwdate/sdwdate) directly, matching what upstream's own systemd unit does (the wrapper script was never meant to be the service entry point).- Python package files installed to Debian's
dist-packagesconvention; Arch usessite-packages~ fixed install paths in the PKGBUILD. sdwdatesystem user's home directory didn't match what the daemon's status-file logic expects (/run/sdwdate) ~ fixed viausermod/.install./var/lib/sdwdate-forbidden-temp(a directory upstream's code creates unconditionally, originally to work around an AppArmor constraint that doesn't apply here) wasn't being created ~ added to the init script'sstart_pre()./usr/libexec/helper-scripts/onion-time-pre-scriptwas missing entirely (privleap/AppArmor-specific upstream component) ~ replaced with the no-oplainos-onion-time-pre-scriptdescribed above.url_to_unixtimewasn't installed at all (missed in the initial package file list) ~ added.- Tor's control-port authentication cookie (
/var/lib/tor/control_auth_cookie) wasn't readable by thesdwdateuser, causing Tor consensus sanity checks to fail even though basic SOCKS-based fetching worked ~ fixed by addingsdwdateto thetorgroup.
Downloads
- Core Python daemon and