Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 667410 - sci-geosciences/gpsd vs sys-fs/udev: serial console groups uucp->dialout
Summary: sci-geosciences/gpsd vs sys-fs/udev: serial console groups uucp->dialout
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Current packages (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Sci-geo Project
URL:
Whiteboard:
Keywords:
Depends on: 282130
Blocks: 691746
  Show dependency tree
 
Reported: 2018-09-30 20:02 UTC by Robin Johnson
Modified: 2020-07-29 02:48 UTC (History)
2 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Robin Johnson archtester Gentoo Infrastructure gentoo-dev Security 2018-09-30 20:02:11 UTC
Back in bug 282130, gpsd changed it's group to be 'uucp', to match udev's behavior.

However, udev changed between udev-135 & udev-140:
udev-135/rules/rules.d/50-udev-default.rules:KERNEL=="tty[A-Z]*|pppox*|ircomm*|noz*", GROUP="uucp"
udev-140/rules/rules.d/50-udev-default.rules:KERNEL=="tty[A-Z]*[0-9]|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*", GROUP="dialout"

I propose that gpsd changes the group it runs as to be dialout instead now. 
This is complicated by the fact that the setting is a compile-time option for gpsd, and cannot be done dynamically.

I have opened the bug because I suspect users might have come to depend the  specific group, and will need to adjust scripts.
Comment 1 Ben 2020-01-10 19:37:39 UTC
Is bug #691746 the same as this?
Not sure what the best solution is...
Comment 2 Robin Johnson archtester Gentoo Infrastructure gentoo-dev Security 2020-01-10 21:38:18 UTC
Linking it together.

I found a further complexity to it, and never got back to an adequate resolution.

Specifically, the PPS sync and the dialout change broke dynamic addition of serial devices to gpsd, but JUST the PPS functionality of the device. The GPS NMEA or binary streams on the normal serial TX/PS are fine.

If gpsd is started explicitly passing the console, PPS works.

If the dynamic gpsdctl is used, then PPS fails.

explicitly passed:
2020-01-10T21:35:46.000000+00:00 bohr-int gpsd[23870]: gpsd:INFO: gpsd_activate(2): activated GPS (fd 8)
2020-01-10T21:35:46.000000+00:00 bohr-int gpsd[23870]: gpsd:PROG: PPS:/dev/ttyUSB0 chrony socket /var/run/chrony.ttyUSB0.sock doesn't exist
2020-01-10T21:35:46.000000+00:00 bohr-int gpsd[23870]: gpsd:PROG: KPPS:/dev/ttyUSB0 checking /sys/devices/virtual/pps/pps0/path, 
2020-01-10T21:35:46.000000+00:00 bohr-int gpsd[23870]: gpsd:PROG: KPPS:/dev/ttyUSB0 checking /sys/devices/virtual/pps/pps1/path, /dev/ttyUSB0
2020-01-10T21:35:46.000000+00:00 bohr-int gpsd[23870]: gpsd:INFO: KPPS:/dev/ttyUSB0 RFC2783 path:/dev/pps1, fd is 9
2020-01-10T21:35:46.000000+00:00 bohr-int gpsd[23870]: gpsd:INFO: KPPS:/dev/ttyUSB0 pps_caps 0x1133
2020-01-10T21:35:46.000000+00:00 bohr-int gpsd[23870]: gpsd:INFO: KPPS:/dev/ttyUSB0 have PPS_CANWAIT
2020-01-10T21:35:46.000000+00:00 bohr-int gpsd[23870]: gpsd:INFO: KPPS:/dev/ttyUSB0 kernel PPS will be used
2020-01-10T21:35:46.000000+00:00 bohr-int gpsd[23870]: gpsd:PROG: PPS:/dev/ttyUSB0 thread launched
2020-01-10T21:35:46.252121+00:00 bohr-int kernel: pps pps1: new PPS source usbserial0
2020-01-10T21:35:46.252121+00:00 bohr-int kernel: pps pps1: source "/dev/ttyUSB0" added
2020-01-10T21:35:46.000000+00:00 bohr-int gpsd[23870]: gpsd:INFO: PPS:/dev/ttyUSB0 ntpshm_link_activate: 1
2020-01-10T21:35:46.000000+00:00 bohr-int gpsd[23870]: gpsd:INFO: device /dev/ttyUSB0 activated


dynamic:
# ls -la /dev/{ttyUSB,pps}*
crw-rw---- 1 root dialout 247, 1 Jan 10 13:30 /dev/pps1
crw-rw---- 1 gpsd dialout 188, 0 Jan 10 13:30 /dev/ttyUSB0

logs:
2020-01-10T21:30:46.000000+00:00 bohr-int gpsd[19058]: gpsd:PROG: PPS:/dev/ttyUSB0 chrony socket /tmp/chrony.ttyUSB0.sock doesn't exist
2020-01-10T21:30:46.000000+00:00 bohr-int gpsd[19058]: gpsd:PROG: KPPS:/dev/ttyUSB0 checking /sys/devices/virtual/pps/pps0/path, 
2020-01-10T21:30:46.000000+00:00 bohr-int gpsd[19058]: gpsd:PROG: KPPS:/dev/ttyUSB0 checking /sys/devices/virtual/pps/pps1/path, /dev/ttyUSB0
2020-01-10T21:30:46.000000+00:00 bohr-int gpsd[19058]: gpsd:INFO: KPPS:/dev/ttyUSB0 running as 132/132, cannot open /dev/pps1: unknown error
2020-01-10T21:30:46.000000+00:00 bohr-int gpsd[19058]: gpsd:WARN: KPPS:/dev/ttyUSB0 kernel PPS unavailable, PPS accuracy will suffer
2020-01-10T21:30:46.000000+00:00 bohr-int gpsd[19058]: gpsd:PROG: PPS:/dev/ttyUSB0 thread launched
2020-01-10T21:30:46.253124+00:00 bohr-int kernel: pps pps1: new PPS source usbserial0
2020-01-10T21:30:46.253124+00:00 bohr-int kernel: pps pps1: source "/dev/ttyUSB0" added
2020-01-10T21:30:46.000000+00:00 bohr-int gpsd[19058]: gpsd:INFO: PPS:/dev/ttyUSB0 ntpshm_link_activate: 1
2020-01-10T21:30:46.000000+00:00 bohr-int gpsd[19058]: gpsd:INFO: device /dev/ttyUSB0 activated
Comment 3 Michael Weiser 2020-04-15 19:59:43 UTC
I came across this while working on https://bugs.gentoo.org/show_bug.cgi?id=704580.

I had a look at gpsd's droppriv code and it does an explicit setgid() to GPSD_GROUP, so it really runs with effective group uucp xor dialout, never more.

Would it help if instead, gpsd dropped to whatever the group of GPSD_USER is and did an initgroups() to fill the supplementary group list as well? Then, the gpsd user could simply be a member of both groups for a time as a migration path:

uid=413(gpsd) gid=413(gpsd) groups=413(gpsd),20(dialout),14(uucp)

I volunteer to raise this with upstream if helpful.
Comment 4 Robin Johnson archtester Gentoo Infrastructure gentoo-dev Security 2020-04-15 20:12:19 UTC
(In reply to Michael Weiser from comment #3)
> I had a look at gpsd's droppriv code and it does an explicit setgid() to
> GPSD_GROUP, so it really runs with effective group uucp xor dialout, never
> more.
> 
> Would it help if instead, gpsd dropped to whatever the group of GPSD_USER is
> and did an initgroups() to fill the supplementary group list as well? Then,
> the gpsd user could simply be a member of both groups for a time as a
> migration path:
> 
> uid=413(gpsd) gid=413(gpsd) groups=413(gpsd),20(dialout),14(uucp)
> 
> I volunteer to raise this with upstream if helpful.

YES! Thank you for this discovery, that explains a lot of what I saw.

Upstream is good with patches, and I can help you test it with PPS hardware as well.
Comment 5 Michael Weiser 2020-04-16 19:54:24 UTC
I had a closer look around the code and it turns out that the build system explicitly checks for Gentoo and then switches the default of GPSD_GROUP from dialout to uucp: https://gitlab.com/gpsd/gpsd/-/blob/master/SConstruct#L403, https://gitlab.com/gpsd/gpsd/-/commit/6c1742bc6470c09edfd2e824935e00f96933144a. Was anyone here involved in that change?

Two points about that:
1. Upstream will likely welcome Gentoo falling in line with others using group dialout so that special handling in the build system can go away and complexity decreases for once.
2. But if it was me, I'd ask hard questions why Gentoo's migration path *to* group dialout requires increasing complexity in security sensitive code. I have to admit I'm not quite clear on that yet. Is it just that we can't be sure which version of udev the user will be running and therefore which group device nodes will belong to? Would it be realistic to just sit this out by waiting for stabilisation of a udev version that uses dialout for sure and then some time for users to upgrade?

Also, the droppriv code does have a (slightly obscure) runtime-config path: If gpsd_group=<group> was provided to scons, which defines GPSD_GROUP, that group is unconditionally used as effective group. But if GPSD_GROUP is undefined (I found that passing gpsd_group="" makes that happen), the group id is determined from a tty device passed on the command line: https://gitlab.com/gpsd/gpsd/-/blob/master/gpsd.c#L2203. I'd expect that second code path to be rarely used nowadays because GPSD_GROUP has a default of dialout that is rather obscure to override to nothing.

I wonder if this second behaviour could work to our advantage here: The way I read it (untested), it works like this:
- if a device is passed on the command line (e.g. gpsd /dev/ttyUSB0) then that device node's owner group is determined using stat and gpsd uses that as effective group ID. This would automatically adapt to /dev/ttyUSB0 being owned by uucp, dialout or whomever upon restart of gpsd. As long as this remains consistent for new devices as well, we're fine.
- if no device is passed on the command line, /dev/ttyS0 is attempted as a "prototype device" instead. As long as it exists and is owned by uucp/dialout, all remains well. https://gitlab.com/gpsd/gpsd/-/blob/master/gpsd.c#L60, https://gitlab.com/gpsd/gpsd/-/blob/master/www/hacking.html.in#L1303
- if /dev/ttyS0 doesn't exist either, no setgid is executed and the effective group ID remains 0!? Since the effective uid is no longer 0, gpsd doesn't have capability DAC_OVERRIDE anymore and since the device nodes of hotplugged GPS receivers don't belong to group 0 that should break. Maybe, somehow by me misreading the code, that's even what you describe.

Anyway: Could we write a udev rule that unconditionally creates a dummy device node (or just file) /run/gpsd/tty.proto that belongs to what udev uses as dialout/uucp group and patch gpsd to use that as prototype device instead? If not a udev rule then it could maybe be part of the startup script. This would be a temporary workaround to bridge the time until we can be sure all users have updated to a udev version using group dialout. Does that make sense?
Comment 6 Rick Farina (Zero_Chaos) gentoo-dev 2020-07-29 02:48:13 UTC
Fixed in gpsd-3.20