Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 8 Sep 2016 14:45:20 -0400
From:      Anton Yuzhaninov <citrin+bsd@citrin.ru>
To:        svn-src-head@freebsd.org
Cc:        Eric van Gyzen <vangyzen@FreeBSD.org>
Subject:   Re: svn commit: r305620 - head/usr.sbin/etcupdate
Message-ID:  <81fb0474-0b66-465d-ecc4-22d67624741a@citrin.ru>
In-Reply-To: <201609081553.u88Frnnn006304@repo.freebsd.org>
References:  <201609081553.u88Frnnn006304@repo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?81fb0474-0b66-465d-ecc4-22d67624741a>