Fix SIGPIPE errors in wallace due to closing stderr and reusing FD2
Needs ReviewPublic

Authored by fjl on Sep 24 2018, 12:09 PM.

Details

Reviewers
None
Group Reviewers
PyKolab Developers
Summary

Both wallace and kolabd daemonize themselves and during that process, close the file descriptors 0, 1 and 2 (stdin, stdout and stderr). These FDs then are reused for other purposes, e.g. the IMAP connection. Unfortunately, the libcalendaring library used by pykolab tends to print debug / log / error information to FD 2, expecting that to be stderr. This data is then sent down the IMAP connection, of course violating the protocol. This triggers a SIGPIPE.

In systems that use systemd, we could simply keep FD 0, 1 and 2 open as systemd re-routes them to the system journal (log). But as we can't expect to have systemd in place everywhere, the portable solution would be to re-open FD 0, 1 and 2 on /dev/null so any kind of unexpected output from libraries is simply ignored.

Test Plan

We detected this by strace'ing wallace. It starts fine, connecting and sending regular IMAPs traffic through FD 2:

6321 socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 2
6321 connect(2, {sa_family=AF_INET, sin_port=htons(993), sin_addr=inet_addr("192.168.20.55")}, 16) = 0
6321 getsockopt(2, SOL_SOCKET, SO_TYPE, [1], [4]) = 0
6321 getpeername(2, {sa_family=AF_INET, sin_port=htons(993), sin_addr=inet_addr("192.168.20.55")}, [16]) = 0
6321 write(2, "\26\3[...]
6321 read(2, "\26\3\3\0W\2\0", 7) = 7

But then we saw unexpected output to the same FD 2:

6321 write(2, "unnamed app(6321) KSystemTimeZonesPrivate::readConfig: readConfig(): local zone= \"UTC\"\n", 87) = 87
6321 write(2, "unnamed app(6321) KSystemTimeZonesPrivate::readZoneTab: readZoneTab( \"/usr/share/zoneinfo/zone.tab\" )\n", 102) = 102
6321 write(2, "\27\3\[...]) = -1 EPIPE
6321 --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=6321, si_uid=412} ---

Diff Detail

Repository
rP pykolab
Lint
Lint Skipped
Unit
Unit Tests Skipped
fjl created this revision.Sep 24 2018, 12:09 PM