On 2016-09-08 11:53, Eric van Gyzen wrote:
                        if [ -z "$dryrun" ]; then
                                temp=$(mktemp -t etcupdate)
                                diff3 -E -m ${DESTDIR}$1 ${OLDTREE}$1 ${NEWTREE}$1 
> ${temp}
-                               mv -f ${temp} ${DESTDIR}$1
+                               # Use "cat >" to preserve metadata.
+                               cat ${temp} > ${DESTDIR}$1
+                               rm -f ${temp}
                        fi

In previous code file update was atomic if /tmp/ (or TMPDIR) is on root file system.

With new code file update is not atomic in any case - if etcupdate will be interrupted for some reason (e. g. unexpected power failure) destination file can be half-written or empty. If destination file is important system config (like /etc/rc.d/netif of /etc/rc.d/sshd) remote access to host will be lost.

To keep update atomic and preserve owner/mode something like this can be used:

eval $(stat -s ${DESTDIR}$1) # XXX possible security problem
install -CS -m ${st_mode} -o ${st_uid} -g ${st_gid} ${temp} ${DESTDIR}$1
rm -f ${temp}

But even with install -S race is still possible, because there is no fsync() in install(1).

More reliable way to update important files
1. write temp_file in dest dir
2. fsync tepm_file
3. mv temp_file dest_file

install -S does only 1 and 3.
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to