Package: postfix
Version: 3.10.5 (Debian 13 / trixie)
Severity: important

Summary:
Postfix systemd hardening MemoryDenyWriteExecute breaks pipe delivery to Schleuder (Ruby/FFI)

Description:
On Debian 13, Postfix is started with systemd hardening enabled by default. One of the enabled options is:

MemoryDenyWriteExecute=yes

When Postfix delivers mail via the pipe transport to external programs written in Ruby and using native extensions (for example Schleuder using ruby-ffi), delivery fails at runtime.

The same command works reliably when executed outside of Postfix.


Steps to reproduce:

1. Install postfix and schleuder on Debian 13.

2. Configure a pipe transport in /etc/postfix/master.cf:

schleuder unix - n n - - pipe
    flags=DRhu user=schleuder argv=/usr/bin/schleuder work ${recipient}

3. Ensure Postfix is running with the default systemd service configuration which includes MemoryDenyWriteExecute=yes.

4. Send a valid OpenPGP/MIME encrypted email to a Schleuder list address.

5. Observe that delivery fails.


Observed result:

The pipe transport is invoked, but the external program exits with an error.
Schleuder logs show a Ruby FFI failure similar to:

/usr/lib/.../gems/ffi-1.17.0/lib/ffi/function.rb:65:in attach

Postfix logs show successful pipe invocation, but no list delivery occurs.


Expected result:
Postfix pipe delivery should reliably support external programs, including Ruby programs using native extensions.


Analysis:
The failure only occurs when the program is executed in the Postfix systemd service context. Running the exact same command manually as user "schleuder" with identical input succeeds.

This indicates that MemoryDenyWriteExecute=yes prevents Ruby FFI from functioning correctly, likely by blocking runtime memory permission changes required by native extensions.


Workaround:
Create a systemd drop-in override for postfix.service:

/etc/systemd/system/postfix.service.d/override.conf

[Service]
MemoryDenyWriteExecute=no


After running:

systemctl daemon-reload
systemctl restart postfix

pipe delivery to Schleuder works reliably again.


Additional notes:
- I created the bug report using a translation tool.
- AppArmor is not enabled on the system.
- SystemCallFilter does not need to be changed; disabling
- MemoryDenyWriteExecute alone is sufficient.
- This issue affects any Postfix pipe delivery to Ruby programs using FFI or native extensions.
--
e: [email protected]

PGP Key
https://keys.openpgp.org/search?q=5D1C5286C7D27E4AF895A589946E08AF4D28B509

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

Reply via email to