On 08/21/23 at 04:42am, Dragan Simic wrote: > Running "pacman -Syyu" to perform a full system update resulted > in a rather conspicuous error message in the output of pacman: > > ( 3/18) Creating temporary files... > Assertion 'fd' failed at src/tmpfiles/tmpfiles.c:843, function > fd_set_perms(). Aborting. > /usr/share/libalpm/scripts/systemd-hook: line 28: 1735 Aborted (core > dumped) /usr/bin/systemd-tmpfiles --create > error: command failed to execute correctly > > Expectedly, running "systemd-tmpfiles --create" manually afterwards > went just fine and resulted in no errors, leading to a conclusion > that executing /usr/share/libalpm/hooks/30-systemd-tmpfiles.hook > failed, but only when it was run from within pacman. > > After a detailed and rather lengthy investigation, it turned out > the code in lib/libalpm/util.c that executes the hooks by forking > a child has some bugs that allow the error to occur under certain > circumstances. In particular, function _alpm_run_chroot() that > executes hooks in a fork()ed child does not employ dup2() properly, > but instead executes close() followed by dup2(). > > The man page for dup2() clearly states in the quotation below that > attempts to re-implement the equivalent functionality, which is the > case in function _alpm_run_chroot(), must be avoided: > > The dup2() system call performs the same task as dup(), but > instead of using the lowest-numbered unused file descriptor, > it uses the file descriptor number specified in newfd. In other > words, the file descriptor newfd is adjusted so that it now > refers to the same open file description as oldfd. > > If the file descriptor newfd was previously open, it is closed > before being reused; the close is performed silently (i.e., any > errors during the close are not reported by dup2()). > > The steps of closing and reusing the file descriptor newfd are > performed atomically. This is important, because trying to > implement equivalent functionality using close(2) and dup() > would be subject to race conditions, whereby newfd might be > reused between the two steps. Such reuse could happen because > the main program is interrupted by a signal handler that > allocates a file descriptor, or because a parallel thread > allocates a file descriptor. > > As a result, a condition can occur in which the file descriptor 0 is > closed by calling close(0), and left closed after the while loop that > fails to execute dup2() because of receiving EBUSY, resulting in the > described issues. Also, failed attempts to execute dup2() should be > treated as fatal errors instead of being silently ignored.
I am trying to reproduce this to wrap my head around what's actually happening and verify that this actually fixes it, but I am unable to get pacman to execute a hook with fd 0 closed with or without the ARM patches. Can you provide a reproducible case? apg