/etc/gpsd/device-hook not actually called

Bug #1868363 reported by David Kastrup
14
This bug affects 2 people
Affects Status Importance Assigned to Milestone
gpsd (Ubuntu)
Fix Released
Undecided
Unassigned

Bug Description

The manual page of gpsd states

       When a device is activated (i.e. a client requests data from it), gpsd attempts to execute a hook from /etc/gpsd/device-hook with first command line argument set to the pathname of the
       device and the second to ACTIVATE. On deactivation it does the same passing DEACTIVATE for the second argument.

and when such an executable is present, the debug info/log of gpsd indicates that /etc/gpsd/device-hook is being called and exits with state 0. However, this is a lie.

I assume that there is a suitable line missing in

/etc/apparmor.d/usr.sbin.gpsd

but my apparmor-foo is not sufficient to figure out what incantation is required to allow gpsd executing this hook.

ProblemType: Bug
DistroRelease: Ubuntu 20.04
Package: gpsd 3.20-5ubuntu1
ProcVersionSignature: Ubuntu 5.4.0-18.22-lowlatency 5.4.24
Uname: Linux 5.4.0-18-lowlatency x86_64
ApportVersion: 2.20.11-0ubuntu20
Architecture: amd64
CurrentDesktop: XFCE
Date: Sat Mar 21 09:00:23 2020
InstallationDate: Installed on 2011-10-14 (3080 days ago)
InstallationMedia: Ubuntu 11.10 "Oneiric Ocelot" - Release i386 (20111011)
SourcePackage: gpsd
UpgradeStatus: Upgraded to focal on 2020-03-09 (11 days ago)

Related branches

Revision history for this message
David Kastrup (dak) wrote :
tags: added: apparmor
Paride Legovini (paride)
Changed in gpsd (Ubuntu):
status: New → Triaged
tags: added: server-next
Revision history for this message
Paride Legovini (paride) wrote :

Thanks David for for filing this bug report. I believe you are correct in attributing the problem to the AppArmor configuration.

Revision history for this message
Paride Legovini (paride) wrote :

There are several examples of AppArmor profiles allowing execution of scripts in /etc:

https://codesearch.debian.net/search?q=%28%3Fm%29%5E+*%2Fetc.*+.*x%2C%24&literal=0

so I don't think it goes against any AppArmor policy or best practice.

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

I totally agree, on apparmor based reports having the dmesg output of the denial always helps.

I'll try to prep something without that, but if you'd have that at hand please share it here.

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

Without the denial, I'm not entirely sure on rmix, rix, ix.
Lets grant the lowest amount of permissions on the first try.

@David could you try the build in [1] if that resolves your issue?

[1]: https://launchpad.net/~paelzer/+archive/ubuntu/lp-1868363-gpsd-apparmor-device-hook

Revision history for this message
David Kastrup (dak) wrote :

The dmesg output looks like the following:

[112720.972130] audit: type=1400 audit(1585144947.600:71): apparmor="DENIED" operation="exec" profile="/usr/sbin/gpsd" name="/bin/dash" pid=353559 comm="gpsd" requested_mask="x" denied_mask="x" fsuid=0 ouid=0
[112720.973971] audit: type=1400 audit(1585144947.602:72): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=353555 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[112720.973976] audit: type=1400 audit(1585144947.602:73): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=353555 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[112720.973978] audit: type=1400 audit(1585144947.602:74): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=353555 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[112720.973980] audit: type=1400 audit(1585144947.602:75): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=353555 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[112720.973983] audit: type=1400 audit(1585144947.602:76): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=353555 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[112720.973985] audit: type=1400 audit(1585144947.602:77): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=353555 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[112720.973987] audit: type=1400 audit(1585144947.602:78): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=353555 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[112720.973989] audit: type=1400 audit(1585144947.602:79): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=353555 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[112720.973991] audit: type=1400 audit(1585144947.602:80): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=353555 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"

Note that in my case, /etc/gpsd/device-hook is a shell script, starting with

#!/bin/sh

and it would appear that the exec permission gpsd needs is tied to the shell rather than /etc/gpsd/device-hook?

Revision history for this message
David Kastrup (dak) wrote :

PPA doesn't help.

[113847.653970] audit: type=1400 audit(1585146074.312:1469): apparmor="DENIED" operation="exec" profile="/usr/sbin/gpsd" name="/bin/dash" pid=363200 comm="gpsd" requested_mask="x" denied_mask="x" fsuid=0 ouid=0
[113847.655351] audit: type=1400 audit(1585146074.313:1470): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=363199 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[113847.655358] audit: type=1400 audit(1585146074.313:1471): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=363199 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[113847.655363] audit: type=1400 audit(1585146074.313:1472): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=363199 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[113847.655366] audit: type=1400 audit(1585146074.313:1473): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=363199 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[113847.655369] audit: type=1400 audit(1585146074.313:1474): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=363199 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[113847.655373] audit: type=1400 audit(1585146074.313:1475): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=363199 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[113847.655376] audit: type=1400 audit(1585146074.313:1476): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=363199 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[113847.655388] audit: type=1400 audit(1585146074.313:1477): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=363199 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[113847.655391] audit: type=1400 audit(1585146074.313:1478): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=363199 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

I beg your pardon, my former build was on an outdated base, due to that the PPA has a lower version than what we have in Focal.

I rebased and uploaded a new build - New version is 3.20-5ubuntu2~ppa1

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

Hmm, it directly seems to call the interpreter - eager to see if the rule I added actually helps.

I have not yet added anything for the ptrace denials, it might (hopefully) go away once the running of the hook inherits the profile as intended.
Otherwise granting ptrace to everything unconfined would be too open and we'll need a subprofile for the hook I guess.

Waiting for your next update here ...

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

As so many other packages recently we will also in some environments (e.g. containers) need the allowance to map and execute the own binary.

  # own binary
  /usr/sbin/gpsd rmix,

Revision history for this message
David Kastrup (dak) wrote :

Version 3.20-5ubuntu2-ppa1 is what I have installed.

I don't even think it directly calls the interpreter: I discovered that my hashbang was
#!/bin/bash
while the complained was about /usr/bin/dash (and still is).

That rather sounds like system rather than exec is being used here. Or the system shell is sandwiched in between in some other manner. I seem to remember that for potential interpreter scripts there once was something called "sanitized_helper" that worked in rules.

Sorry not to be able to be more specific: this whole underdocumented mess and framework is just beyond me.

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

The new upload 3.20-5ubuntu2~ppa2 will have the latter rule as well.
But I can't get it to fake a device in my virtual env to trigger the issue you are seeing.
Therefore I'm waiting on a new report by David how far he gets now.

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

gpsd.h:1062:#define DEVICEHOOKPATH "/" SYSCONFDIR "/gpsd/device-hook"

The dash call also isn't uncommon, if still failing lets add it:
https://codesearch.debian.net/search?q=+%2Fbin%2Fdash.*%2C&literal=0

Would be this then:
  /bin/dash rix,

@David
If you fail on dash still, you can add the line above in
  /etc/apparmor.d/local/usr.sbin.gpsd
Afterwards restart the service
  systemctl restart gpsd
to reload the profile.
And then try again - report back what you got ...

Revision history for this message
David Kastrup (dak) wrote :

Audit mentions /bin/dash, not /usr/bin/dash . Sorry.

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

3.20-5ubuntu2~ppa3I just uploaded 3.20-5ubuntu2~ppa3 which also has the rule for dash as found in many other packages.

@David
Can you retry with that version once built and report the remaining denials (if any)?

Revision history for this message
Seth Arnold (seth-arnold) wrote : Re: [Bug 1868363] Re: /etc/gpsd/device-hook not actually called

On Wed, Mar 25, 2020 at 02:54:24PM -0000, David Kastrup wrote:
> I don't even think it directly calls the interpreter: I discovered that my hashbang was
> #!/bin/bash
> while the complained was about /usr/bin/dash (and still is).

This may be due to a confusing, relatively new, symlink:

$ ls -ld /bin /bin/bash /usr/bin/bash
lrwxrwxrwx 1 root root 7 Apr 10 2019 /bin -> usr/bin
-rwxr-xr-x 1 root root 1183448 Feb 25 12:03 /bin/bash
-rwxr-xr-x 1 root root 1183448 Feb 25 12:03 /usr/bin/bash

Symlinks are 'resolved' before AppArmor's mediation points in the kernel,
so AppArmor will see /usr/bin/bash as the execution target.

Thanks

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

@David - does it work with the new build or are there any ptrace issues left?

Revision history for this message
David Kastrup (dak) wrote :

The script now gets executed but doesn't have the original permissions, so I need to rework what it does. Here is what I get on the console:

dak@lola:/usr/local/tmp/lilypond$ sudo gpsd -n -N /dev/ttyACM2
/etc/gpsd/device-hook: 2: cannot create /tmp/bubu: Permission denied
/etc/gpsd/device-hook: 6: cannot create /tmp/nohup: Permission denied

Basically, I need to find some other place for my logs I guess.

I get in dmesg now
[146468.234320] audit: type=1400 audit(1585218755.403:2590): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/usr/sbin/gpsd" pid=504973 comm="apparmor_parser"
[146504.975241] audit: type=1400 audit(1585218792.144:2591): apparmor="DENIED" operation="mknod" profile="/usr/sbin/gpsd" name="/tmp/bubu" pid=506327 comm="device-hook" requested_mask="c" denied_mask="c" fsuid=0 ouid=0
[146504.975735] audit: type=1400 audit(1585218792.145:2592): apparmor="DENIED" operation="mknod" profile="/usr/sbin/gpsd" name="/tmp/nohup" pid=506328 comm="device-hook" requested_mask="c" denied_mask="c" fsuid=0 ouid=0
[146504.978485] audit: type=1400 audit(1585218792.148:2593): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=506325 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[146504.978493] audit: type=1400 audit(1585218792.148:2594): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=506325 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[146504.978499] audit: type=1400 audit(1585218792.148:2595): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=506325 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[146504.978505] audit: type=1400 audit(1585218792.148:2596): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=506325 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[146504.978511] audit: type=1400 audit(1585218792.148:2597): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=506325 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[146504.978517] audit: type=1400 audit(1585218792.148:2598): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=506325 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[146504.978523] audit: type=1400 audit(1585218792.148:2599): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=506325 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"
[146504.978528] audit: type=1400 audit(1585218792.148:2600): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/gpsd" pid=506325 comm="gpsd" requested_mask="read" denied_mask="read" peer="unconfined"

But I don't see any obvious adverse effect from the refused ptrace operations.

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

Thanks for the check David.
It intentionally runs under the same confinement as gpsd does to not break out too easily.
You can modify you local allowance in:
  /etc/apparmor.d/local/usr.sbin.gpsd

That file is intended to take whatever you want to custom-change in the apparmor rules for gpsd.
It will survive upgrades and will effectively be included by the packaged profile.

So we can fix the bug reported here by the upload that I have prepared.
I'll go on with the fix ...

P.S. I'm still concerned about the operation="ptrace" peer="unconfined", but would need a functional issue due to those being blocked to open them up. Preferably then more fine grained than "all of them". If you happen to find what exactly triggers those and what might be missing due to that please let me know in a new bug.

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

Submitted for review and also Debian inclusion. That will make sure it works there as well, we don't derive too much from each other and we will later be able to re-sync gpsd in 20.10.

=> https://salsa.debian.org/debian-gps-team/pkg-gpsd/-/merge_requests/4

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

@David - could I ask you a favor. With the new package that now is able to call the device-hook - could you make your device-hook (for a test) just do `echo "ok"`?
I want to check if the ptrace denials are dependent to the content that you had in that hook.

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

As we can't sync from Debian anyway (right now due to the feature freeze) here also an Ubuntu MP to fix it in Focal.
=> https://code.launchpad.net/~paelzer/ubuntu/+source/gpsd/+git/gpsd/+merge/381292

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

The former Delta:
   4 * [b0d9ef06] Fix autopkgtest for new systemd releases.
   5 Thanks to Michael Biebl (Closes: #953760)
As well as my new suggested fix
   8 * [4c4e5ea1] device-hook apparmor fixes (LP: #1868363)
   9 The manpage defines a hook that is called by gpsd which due to current
  10 confinement it is unable to run.
  11 - d/usr.sbin.gpsd: allow to call the /etc/gpsd/device-hook in the
  12 apparmor profile
  13 - d/usr.sbin.gpsd: allow to map and execute the own binary as needed
  14 in some containers
  15 - d/usr.sbin.gpsd: allow to run common shell interpreters bash/dash
  16 That hook will run within the confinement of gpsd, so if it is expected
  17 to do anything more special a user will have to allow that in
  18 /etc/apparmor.d/local/usr.sbin.gpsd

is in the new version 3.20-6 in Debian (thanks Bernd for merging)
Both are fixes not violating the FFe, so we can as well make this a sync again.

Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package gpsd - 3.20-6

---------------
gpsd (3.20-6) unstable; urgency=medium

  [ Bernd Zeimetz ]
  * [b0d9ef06] Fix autopkgtest for new systemd releases.
    Thanks to Michael Biebl (Closes: #953760)

  [ Christian Ehrhardt ]
  * [4c4e5ea1] device-hook apparmor fixes (LP: #1868363)
    The manpage defines a hook that is called by gpsd which due to current
    confinement it is unable to run.
    - d/usr.sbin.gpsd: allow to call the /etc/gpsd/device-hook in the
      apparmor profile
    - d/usr.sbin.gpsd: allow to map and execute the own binary as needed
      in some containers
    - d/usr.sbin.gpsd: allow to run common shell interpreters bash/dash
    That hook will run within the confinement of gpsd, so if it is expected
    to do anything more special a user will have to allow that in
    /etc/apparmor.d/local/usr.sbin.gpsd
    Signed-off-by: Christian Ehrhardt <email address hidden>

 -- Bernd Zeimetz <email address hidden> Sat, 28 Mar 2020 22:16:13 +0100

Changed in gpsd (Ubuntu):
status: Triaged → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.