svn commit: r305620 - head/usr.sbin/etcupdate

Anton Yuzhaninov citrin+bsd at citrin.ru
Thu Sep 8 18:45:32 UTC 2016


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.


More information about the svn-src-head mailing list