See https://bugzilla.redhat.com/show_bug.cgi?id=1862056 According to strace, it opens /etc/passwd with O_TRUNC and writes new contents. If power outage happened at this point, FS may reveal en empty file. In order to overcome, it MUST: 1. open temporary file in the same dir (i.e. in /etc) securely like mkostemp() 2. copy ownerhsip info, permissions, possibly some attributes (selinux? xattr?) from current file to temporary one 3. fill new file with new data 4. fdatasync(tmpfile) 5. close(tmpfile) 5. rename("/etc/passwd.tmp", "/etc/passwd") 6. dirfd = open("/etc", O_DIRECTORY|O_RDONLY) 7. fdatasync(dirfd) 8. close(dirfd) This is the only way to secure(safe) replace a file. If possible, it's better to: 1. Do all the operations using *at syscalls with opened "/etc" at the start of the change operation. 2. use openat(O_TEMPFILE)+ linkat("/proc/self/fd/%d") instead of rename() in order not to leave temporary files on accidental poweroff. If not, remove all temporary files left from the previous call after gaining the main lock.
Where do you see that? shadow-utils should not open /etc/passwd with O_TRUNC at all. Could you attach the strace where this would be visible?
Sorry, my fault. It does not open /etc/passwd with O_TRUNC.