> On Jun 21, 2019, at 12:32, Xin LI <delp...@gmail.com> wrote:
> 
> 
>> On Thu, Jun 20, 2019 at 7:38 PM Conrad Meyer <c...@freebsd.org> wrote:
>> Author: cem
>> Date: Fri Jun 21 02:37:54 2019
>> New Revision: 349256
>> URL: https://svnweb.freebsd.org/changeset/base/349256
>> 
>> Log:
>>   rc.d/motd: Update motd more robustly
>> 
>>   Use appropriate fsyncs to persist the rewritten /etc/motd file, when a
>>   rewrite is performed.
> 
> Why is /etc/motd so important to deserve this kind of construct?  The worst 
> that could happen to /etc/motd with previous code is that you might end up 
> with an empty or non-existent /etc/motd, and the change have introduced more 
> problems than it intended to solve.
>  
>> 
>>   Reported by:  Jonathan Walton <jonathan AT isilon.com>
>>   Reviewed by:  allanjude, vangyzen
>>   Sponsored by: Dell EMC Isilon
>>   Differential Revision:        https://reviews.freebsd.org/D20701
>> 
>> Modified:
>>   head/libexec/rc/rc.d/motd
>> 
>> Modified: head/libexec/rc/rc.d/motd
>> ==============================================================================
>> --- head/libexec/rc/rc.d/motd   Fri Jun 21 00:52:30 2019        (r349255)
>> +++ head/libexec/rc/rc.d/motd   Fri Jun 21 02:37:54 2019        (r349256)
>> @@ -37,11 +37,15 @@ motd_start()
>>         uname -v | sed -e 's,^\([^#]*\) #\(.* 
>> [1-2][0-9][0-9][0-9]\).*/\([^\]*\) $,\1 (\3) #\2,' > ${T}
>>         awk '{if (NR == 1) {if ($1 == "FreeBSD") {next} else {print "\n"$0}} 
>> else {print}}' < /etc/motd >> ${T}
>> 
>> -       cmp -s $T /etc/motd || {
>> -               cp $T /etc/motd
>> +       if ! cmp -s $T /etc/motd; then
>> +               mv -f $T /etc/.motd.tmp
> 
> This have partially defeated the benefit of doing mktemp in the code above.  
> The old code tries to avoid excessive writes to /, which is preserved, but it 
> is not safe to assume /etc/.motd.tmp is a non-existent plain file: mv would 
> happily proceed when .motd.tmp is a preexisting directory, for instance (and 
> subsequent mv -f would fail).  A malicious system administrator can now plant 
> a timing bomb which will fill / eventually.
> 
> You can do a TMPDIR=/etc/ mktemp .motd.tmp.XXXXXXXX and use that to mitigate 
> the attack above, but then if the system crash in the middle you would still 
> end up with a dangling .motd.tmp.XXXXXXXX file in /etc.
> 
> Also note that $T is on /tmp which is likely to be a different filesystem, 
> internally this is mostly equivalent to cp + rm.  You can simplify the code 
> by reverting to previous cp and keep the rm -f below as an unconditional 
> remove like before.
> 
>> +               fsync /etc/.motd.tmp
>> +               mv -f /etc/.motd.tmp /etc/motd
>>                 chmod ${PERMS} /etc/motd
>> -       }
>> -       rm -f $T
>> +               fsync /etc
> 
> There is absolutely no reason to fsync /etc here.  mv'ing on the same file 
> system is performed with rename(2) which is required to be atomic by POSIX.  
> /etc/motd will be pointing to either the old one or the new one in the event 
> of a crash, and both are acceptable.
>  
> So, in my opinion the new code would have made the situation worse than the 
> old code.
> 
> But ultimately, I think the real design question here that needs to be solved 
> would probably be "Why are piling up multiple layers of workarounds around 
> motd? Does it even need to be located in /etc?"  The contents is meant to be 
> updated every time when there is a kernel change, and to that extent it seems 
> to be more appropriate for /var/run and generated at boot from a template 
> located somewhere in /etc.  The benefit of this approach is that you would 
> have one less file to merge for each etcupdate/mergemaster (or at least only 
> need to do it when some customization is made), and there is no need to worry 
> about write durability.

    I don’t know the exact reasoning today, but once upon a time, there used to 
be a number of things hooked to /etc/motd generation that could influence 
information provided to downstream callers/systems.
Thank you,
-Enji
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to