os-prober exits prematurely with "logger: socket /dev/log: Protocol wrong type for socket"

Bug #1826294 reported by Dara Poon
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
AppArmor Profiles
New
Undecided
Unassigned
os-prober (Ubuntu)
Fix Released
Critical
Unassigned
rsyslog (Ubuntu)
New
Critical
Unassigned

Bug Description

Failure occurs on Ubuntu 16.04 with the apparmor-profiles-2.10.95-0ubuntu2.10 package installed.

Running update-grub will run /usr/bin/os-prober, which spews about a dozen of the following line to stderr:

    logger: socket /dev/log: Protocol wrong type for socket

… but fails to report the existence of some installed operating systems as expected.

Furthermore, /var/log/messages contains:

    kernel: audit: type=1400 audit(1556043066.679:11460): apparmor="ALLOWED" operation="sendmsg" info="Failed name lookup - disconnected path" error=-13 profile="syslog-ng" name="dev/log" pid=28566 comm="logger" requested_mask="r" denied_mask="r" fsuid=0 ouid=0

Here is a stripped-down skeleton of the /usr/bin/os-prober script, which demonstrates the problem:

    #!/bin/sh
    set -e -x

    newns () {
      [ "$OS_PROBER_NEWNS" ] || exec /usr/lib/os-prober/newns "$0" "$@"
    }

    log() {
      logger -t "$(basename "$0")" "$@"
    }

    debug() {
      log "debug: $@"
    }

    ls -l /dev/log
    debug "Hello world"
    newns "$@"

The expected behavior is that it should write "debug: os-prober-testcase Hello world" to /var/log/messages twice. However, it only succeeds in writing "Hello world" once. After the script respawns itself with /usr/lib/os-prober/newns (which is like `unshare -m`), the second attempt to write to /dev/log fails as described above.

Since the os-prober Bash script runs with the -e flag, any error, even just a logging error, causes the script to terminate prematurely. (Arguably, the log() function should call `logger -t "$(basename "$0")" "$@" || :` so that logging failures aren't fatal.)

The fix, for me, is to edit /etc/apparmor.d/sbin.syslog-ng, and change

    profile syslog-ng /{usr/,}sbin/syslog-ng flags=(complain) {\
      …
    }

to

    profile syslog-ng /{usr/,}sbin/syslog-ng flags=(complain,attach_disconnected) {
      …
    }

… then run `aa-complain sbin.syslog-ng` and `service syslog-ng restart`, before running update-grub again. I assume that similar fixes would be required for the other logging daemons.

Related branches

Revision history for this message
Dimitri John Ledkov (xnox) wrote :

yeah i get apparmor="DENIED" info="Failed name loookup - disconnected path", which breaks os-prober.

Changed in os-prober (Ubuntu):
importance: Undecided → Critical
Changed in rsyslog (Ubuntu):
importance: Undecided → Critical
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

I'll try to reproduce it and amend the profile as needed.

Revision history for this message
Dimitri John Ledkov (xnox) wrote :
Revision history for this message
Dimitri John Ledkov (xnox) wrote :

Steps i can reproduce:

wget https://bugs.launchpad.net/ubuntu/+source/os-prober/+bug/1826294/+attachment/5652492/+files/reproducer.sh

chmod +x reproducer.sh

sudo journalctl -f -e &

clear

sudo ./reproducer.sh

Revision history for this message
Dimitri John Ledkov (xnox) wrote :

This is Ubuntu desktop install. rsyslog.service is active and running, systemd-journald-dev-log.socket is running.

Revision history for this message
John Johansen (jjohansen) wrote :

The syslog-ng profile needs flags=(attach_disconnected) added to it

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Sorry, works just fine in this lunar vm here:

# id; logger before; ./reproducer.sh ; logger after
uid=0(root) gid=0(root) groups=0(root)
+ set -e
+ . /usr/share/os-prober/common.sh
+ cleanup_tmpdir=false
+ progname=
+ type mapdevfs
+ newns
+ [ ]
+ exec /usr/lib/os-prober/newns ./reproducer.sh
+ set -e
+ . /usr/share/os-prober/common.sh
+ cleanup_tmpdir=false
+ progname=
+ type mapdevfs
+ newns
+ [ 1 ]
+ log hello
+ cache_progname
+ progname=reproducer.sh
+ logger -t reproducer.sh hello

journal:
Mar 07 18:25:21 l-rsyslog-osprober root[2073]: before
Mar 07 18:25:21 l-rsyslog-osprober reproducer.sh[2075]: hello
Mar 07 18:25:21 l-rsyslog-osprober root[2076]: after

# uname -r
6.1.0-16-generic
# ps axwZ|grep rsyslog|grep -v grep
rsyslogd (enforce) 687 ? Ssl 0:00 /usr/sbin/rsyslogd -n -iNONE

systemd-journald-dev-log.socket is also running.

But I tried on amd64. Trying on arm64 will take more time.

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

This bug was fixed in the package os-prober - 1.81ubuntu2

---------------
os-prober (1.81ubuntu2) lunar; urgency=medium

  * Ignore logger socket-errors to workaround apparmor denials. (LP: #1826294)

 -- Dimitri John Ledkov <email address hidden> Tue, 07 Mar 2023 13:28:14 +0000

Changed in os-prober (Ubuntu):
status: New → Fix Released
Revision history for this message
Dimitri John Ledkov (xnox) wrote :

> The syslog-ng profile needs flags=(attach_disconnected) added to it

I failed to reproduce this with syslog-ng, but i guess i didn't configure syslog-ng correctly to attempt attaching to /dev/log

I am also not sure of os-prober usage of logger is correct, and if it actually wants to use that all, or if it should simply use journald only, or nothing at all.

Reading attach_disconnected sounds scary, i'm not sure what os-prober can do better here. bind-mount /dev/log socket into it's new mount namespace?

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

I'm not really looking into syslog-ng. The apparmor profile change I did was to rsyslog, and that's where I tried to reproduce this issue.

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.