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>