GPSD unable to use Kernel PPS
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
gpsd (Ubuntu) |
Fix Released
|
Undecided
|
Christian Ehrhardt | ||
Focal |
Fix Released
|
High
|
Unassigned |
Bug Description
[Impact]
* Current GPSD apparmor isolation is too strict to use PPS devices
properly.
* backport changes we added to 20.10 to fix this
[Test Case]
* Set up a PPS device with chrony/gpsd as described in [1]
Check the log output.
Bad case:
gpsd:INFO: KPPS:/dev/ttyS0 device not found.
gpsd:WARN: KPPS:/dev/ttyS0 kernel PPS unavailable, PPS accuracy will suffer
Good case does not show the errors above. Check that gpsd properly
initializes the device by ensuring this works for the whole stack
and chrony ends up getting proper PPS time data (also in [1]).
[1]: https:/
[Regression Potential]
* As always with apparmor changes the regression risk comes in two way:
- we allow more than before, that could be insecure but we have the +1
from the security team and optimized to further reduce permissions.
- we deny some access (to silence warnings) which could, if strictly
required for un-tested use cases break these use-cases. Neither in the
tests nor in the review/discussion such cases were identified.
[Other Info]
* This is accepted in Debians packaging git, if not in Groovy in time I'll
need to put an 3.20-8ubuntu1 there, but I can preparing the SRU
independent to that.
----
I am working with gpsd and a pulse-per-second (PPS) signal on a serial port.
GPSD is able to detect the PPS signal but it is not able to use Kernel PPS for lower jitter. Here are the relevant log lines when PPS is being detected and enabled:
gpsd:INFO: KPPS:/dev/ttyS0 device not found.
gpsd:WARN: KPPS:/dev/ttyS0 kernel PPS unavailable, PPS accuracy will suffer
gpsd:PROG: PPS:/dev/ttyS0 thread launched
gpsd:INFO: PPS:/dev/ttyS0 ntpshm_
gpsd:PROG: TPPS:/dev/ttyS0 ioctl(TIOCMIWAIT) succeeded, time: 1586594708.
gpsd:PROG: TPPS:/dev/ttyS0 Clear, cycle: 1586594708000179, duration: 1586594708000179 @ 1586594708.
gpsd:PROG: PPS:/dev/ttyS0 Clear cycle: 1586594708000179, duration: 1586594708000179 @ 1586594708.
gpsd:PROG: TPPS:/dev/ttyS0 ioctl(TIOCMIWAIT) succeeded, time: 1586594708.
gpsd:PROG: TPPS:/dev/ttyS0 Assert, cycle: 1586594708100154, duration: 99975 @ 1586594708.
gpsd:PROG: PPS:/dev/ttyS0 Assert cycle: 1586594708100154, duration: 99975 @ 1586594708.
gpsd:PROG: PPS:/dev/ttyS0 Assert ignored missing last_fixtime
gpsd:PROG: TPPS:/dev/ttyS0 ioctl(TIOCMIWAIT) succeeded, time: 1586594709.
gpsd:PROG: TPPS:/dev/ttyS0 Clear, cycle: 999938, duration: 899962 @ 1586594709.
gpsd:PROG: PPS:/dev/ttyS0 Clear cycle: 999938, duration: 899962 @ 1586594709.
gpsd:INFO: PPS:/dev/ttyS0 Clear hooks called clock: 1586594709.
gpsd:PROG: PPS:/dev/ttyS0 Clear no fix @ 1586594709.
gpsd:PROG: TPPS:/dev/ttyS0 ioctl(TIOCMIWAIT) succeeded, time: 1586594709.
gpsd:PROG: TPPS:/dev/ttyS0 Assert, cycle: 1000012, duration: 100049 @ 1586594709.
gpsd:PROG: PPS:/dev/ttyS0 Assert cycle: 1000012, duration: 100049 @ 1586594709.
gpsd:PROG: PPS:/dev/ttyS0 Assert ignored this second already handled
The kernel does have PPS configured and the pps_ldisc module loaded. I think GPSd actually drove the loading of the module but I am not sure. I see the module being loaded and the serial port becoming a pps0 source during the boot sequence:
10:34:09 doorway kernel: [ 8.691161] pps_ldisc: PPS line discipline registered
10:34:09 doorway kernel: [ 8.691686] pps pps0: new PPS source serial0
10:34:09 doorway kernel: [ 8.691714] pps pps0: source "/dev/ttyS0" added
This is confirmed with ppsfind:
$ ppsfind ttyS0
pps0: name=serial0 path=/dev/ttyS0
And this pps0 device is working well:
$ sudo ppswatch /dev/pps0
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
timestamp: 1586596125, sequence: 1418, offset: 85067
timestamp: 1586596125, sequence: 1418, offset: 85067
timestamp: 1586596126, sequence: 1419, offset: 81949
timestamp: 1586596126, sequence: 1419, offset: 81949
timestamp: 1586596127, sequence: 1420, offset: 80119
timestamp: 1586596127, sequence: 1420, offset: 80119
timestamp: 1586596128, sequence: 1421, offset: 81099
timestamp: 1586596128, sequence: 1421, offset: 81099
So, the kernel PPS subsystem is there and appears to be perfectly happy with the pps0 coming from /dev/ttyS0 but still GPSD appears unable to use all of that.
Related branches
- Christian Ehrhardt (community): Approve
- Lucas Kanashiro (community): Needs Fixing
- Canonical Server: Pending requested
-
Diff: 115 lines (+56/-0) (has conflicts)5 files modifieddebian/changelog (+11/-0)
debian/control (+5/-0)
debian/control.in (+5/-0)
debian/gpsd.default (+6/-0)
debian/usr.sbin.gpsd (+29/-0)
no longer affects: | chrony (Ubuntu) |
tags: | added: server-next |
Changed in gpsd (Ubuntu): | |
assignee: | nobody → Christian Ehrhardt (paelzer) |
description: | updated |
Hi Mark,
Disclaimer: my gps device has no PPS so I'm stabbing a bit in the dark here. I beg your pardon for that in advance.
By default devices are hot-added as they are detected e.g. via udev.
But for PPS there is a permission issue if you have it set up like it.
From [1]: "In order to present the smallest possible attack surface to privilege- escalation attempts, gpsd, if run as root, drops its root privileges very soon after startup - just after it has opened any serial device paths passed on the command line.
Thus, KPPS can only be used with devices passed that way, not with GPSes that are later presented to gpsd by the hotplug system. Those hotplug devices may, however, be able to use plain, non-kernel PPS. gpsd tries to automatically fall back to this when absence of root permissions makes KPPS unavailable."
I assume it is ok for your setup, but just to be sure you have set $DEVICES to include, maybe even both of them?
The hot adding is rather new and has other known bugs (e.g. 1873415) anyway and since your gpsd debug output lists the device you should be ok on that, but I wanted to ask to be sure.
How does "systemctl status gpsd.service" look like, does it have e.g.:
● gpsd.service - GPS (Global Positioning System) Daemon
...
└─1085 /usr/sbin/gpsd /dev/ttyUSB0 /dev/pps0
I guess for debugging you might already run it directly with something like:
$ sudo gpsd -D 5 -N /dev/ttyS0 /dev/pps0
Is that assumption right?
The error message that you see "kernel PPS unavailable, PPS accuracy will suffer" has a comment referencing to those potential permissions issues as well. kernel_ pps(&inner_ context) ; kernelpps_ handle ) {
1263 /* some operations in init_kernel_pps() require root privs */
1264 (void)init_
1265 if ( 0 <= inner_context.
We might want/need to debug the details of that init_kernel_pps function if it returns an RC.
Any chance to log onto your system?
Also maybe anything in dmesg for apparmor denies?
[1]: https:/ /gpsd.gitlab. io/gpsd/ gpsd-time- service- howto.html# _gps_time