FS#62404 - [nullmailer][systemd] missing setuid bit for nullmailer-queue

Attached to Project: Community Packages
Opened by Sebastian Schloßer (Sebastian256) - Friday, 19 April 2019, 18:05 GMT
Last edited by Eli Schwartz (eschwartz) - Friday, 19 April 2019, 20:41 GMT
Task Type Bug Report
Category Packages
Status Closed
Assigned To No-one
Architecture All
Severity Low
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 1
Private No

Details

I cannot send mail using nullmailer 2.2-1.
Using an unprivileged user, the sendmail command fails with "nullmailer-inject: nullmailer-queue failed: 1"
Using root, the mail gets queued but not delivered: "nullmailer-send: Can't open file '1555695487.2489'"

The reason for the problem is that mails are put into the /var/spool/nullmailer/queue folder by nullmailer-queue. That works only if the executing user is nullmail or root.
The mails are then read from there by nullmailer-send. Since that process is executed by the nullmail user, it cannot read queued files owned by root with mode 600.

The solution is to set the setuid bit for the nullmailer-queue executable. Then mails can be queued and always have the correct owner.
This task depends upon

Closed by  Eli Schwartz (eschwartz)
Friday, 19 April 2019, 20:41 GMT
Reason for closing:  Fixed
Additional comments about closing:  Worked around in nullmailer 2.2-2
Comment by Sebastian Schloßer (Sebastian256) - Friday, 19 April 2019, 18:15 GMT
Rebooting solves the issue. You have the systemd-tmpfiles snippet in the package which sets the permissions. But that has no effect until the next start of systemd-tmpfiles-setup.service (e.g. a reboot).
Is there a way to apply the permissions immediately on package install, or at least wo warn the user that he has to reboot?
Comment by loqs (loqs) - Friday, 19 April 2019, 18:32 GMT
/usr/share/libalpm/hooks/systemd-tmpfiles.hook should run at the end of the transaction calling /usr/share/libalpm/scripts/systemd-hook which calls /usr/bin/systemd-tmpfiles --create
Comment by Sebastian Schloßer (Sebastian256) - Friday, 19 April 2019, 19:43 GMT
Thanks for these hints. Running '/usr/bin/systemd-tmpfiles --create' again manually after the installation fixes permissions without reboot. That is somehow weird, so I analyzed a bit.
I have put a 'strace' call before '/usr/bin/systemd-tmpfiles --create' in /usr/share/libalpm/scripts/systemd-hook.

Look at this excerpt:

openat(4, "nullmailer-queue", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 5
fstat(5, {st_mode=S_IFREG|0755, st_size=26488, ...}) = 0
close(4) = 0
fstat(5, {st_mode=S_IFREG|0755, st_size=26488, ...}) = 0
chmod("/proc/self/fd/5", 04755) = 0
fchownat(5, "", 962, -1, AT_EMPTY_PATH) = 0
close(5) = 0

For me it looks like the chmod to 04755 is done before the chown to 962 (nullmail), but chown implicitly resets the setuid bit.
The second (manual) invocation of systemd-tmpfiles does no chown anymore, because the owner is already correct.

I'll experiment a bit with systemd-tmpfiles to find the smallest possible example and then file a bug against systemd.
Comment by Sebastian Schloßer (Sebastian256) - Friday, 19 April 2019, 20:05 GMT
Reported upstream to systemd: https://github.com/systemd/systemd/issues/12354
Thanks again for the hint with the hook that helped me to find it.
Comment by Eli Schwartz (eschwartz) - Friday, 19 April 2019, 20:11 GMT
Huh...  FS#62371  except on actual Arch Linux. I could swear this used to work, though. The package has been that way for over a year, BTW. Did something change in systemd?

...

So it does correctly set the ownership, but not the relevant permission.
Comment by Sebastian Schloßer (Sebastian256) - Friday, 19 April 2019, 20:30 GMT
Looking at the source of systemd-tmpfiles: https://github.com/systemd/systemd/blame/v241/src/tmpfiles/tmpfiles.c:
Chmod is in line 820, chown at line 833. The order has been like this for a year.

To hit this bug you need to install/update nullmailer and then send mails before you reboot the system or install another package that also triggers the tmpfiles hook.
The first invocation of systemd-tmpfiles sets the permissions (including setuid bit) and than changes the owner to nullmail, which clears the setuid bit again. A second invocation (reboot/manual/other package triggers hook) sets the setuid bit and since the owner is already correct, no chown is done and the bit stays until you update/reinstall nullmailer.
Comment by Eli Schwartz (eschwartz) - Friday, 19 April 2019, 20:40 GMT
Workaround: list the permissions twice. Implemented in nullmailer 2.2-2

Loading...