https://bugs.kde.org/show_bug.cgi?id=420921
Bug ID: 420921 Summary: execute_kwallet() accidentally closes syslog socket, which results in failure to listen() on its own socket, breaking kwalletd Product: kwallet-pam Version: unspecified Platform: Debian unstable OS: Linux Status: REPORTED Severity: major Priority: NOR Component: general Assignee: plasma-b...@kde.org Reporter: k...@kdebugs.elan.rulez.org Target Milestone: --- SUMMARY execute_kwallet() closes many of its inherited file descriptors, which includes the one used for syslog() previously (I assume by pam_syslog()). However, somewhere there is still global state that remembers that FD number. The function goes on to create envSocket of type SOCK_STREAM, then calls syslog() to log a debug message, and eventually tries to listen on envSocket. The problem is that envSocket ends up having the same FD as the one saved for syslog in global state; so in the call to syslog(), libc(?) closes the FD and reopens it for logging as SOCK_DGRAM. listen() won't work on a datagram socket, so that the listen() call fails and kwalletd does not run. Severity set to major because this makes pam_kwallet unusable. There are a number of reports scattered in various forums about this, but I didn't find an actual bug report. strace: socket(AF_UNIX, SOCK_STREAM, 0) = 3 // this is the 'envSocket = socket(AF_UNIX, SOCK_STREAM, 0)' call unlink("/run/user/xxxx/kwallet5.socket") = -1 ENOENT (No such file or directory) getpid() = xxxx sendto(3, "<87>[some date] lightdm[xxxx]: pam_kwallet5: final socket path: /run/user/xxxx/kwallet5.socket", 98, MSG_NOSIGNAL, NULL, 0) = -1 ENOTCONN (Transport endpoint is not connected) // this is the syslog() call close(3) = 0 // this is syslog() being smart about apparently having lost its connection to /dev/log socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0) = 3 connect(3, {sa_family=AF_UNIX, sun_path="/dev/log"}, 110) = 0 sendto(3, "<87>[some date] lightdm[xxxx]: pam_kwallet5: final socket path: /run/user/1011/kwallet5.socket", 98, MSG_NOSIGNAL, NULL, 0) = 98 // this is where syslog() actually logs the message, but FD3 is already SOCK_DGRAM bind(3, {sa_family=AF_UNIX, sun_path="/run/user/xxxx/kwallet5.socket"}, 32) = 0 // we're back from syslog() and in execute_kwallet() but at this point, FD3 is already a SOCK_DGRAM listen(3, 5) = -1 EOPNOTSUPP (Operation not supported) // so listen() fails STEPS TO REPRODUCE Try to start kwalletd from pam. OBSERVED RESULT kwalletd doesn't start and instead logs "pam_kwallet5-kwalletd: Couldn't listen in socket" EXPECTED RESULT kwalletd starts and listens on its Unix domain socket. SOFTWARE/OS VERSIONS Windows: macOS: Linux/KDE Plasma: all (available in About System) KDE Plasma Version: reproduced with 5.17.5, but the code on github seems to be the same KDE Frameworks Version: Qt Version: irrelevant ADDITIONAL INFORMATION Calling closelog() explicitly might be a fix. Also, how do you know there are no inherited FDs above 63 you need to close? Maybe you know, but in that case a comment that points this out would be helpful. Currently the loop boundary at the beginning of the function looks like either magic or a guess. -- You are receiving this mail because: You are watching all bug changes.