Date: Fri, 16 Dec 2005 13:46:59 -0700 (MST) From: "John E. Hein" <jhein@timing.com> To: FreeBSD-gnats-submit@FreeBSD.org Cc: brooks@FreeBSD.org Subject: bin/90518: dhclient-script problems with symlink'd resolv.conf when /etc is read-only Message-ID: <200512162046.jBGKkxn7001129@Elmer.timing.com> Resent-Message-ID: <200512162050.jBGKo34l086570@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 90518 >Category: bin >Synopsis: dhclient-script problems with symlink'd resolv.conf when /etc is read-only >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Dec 16 20:50:03 GMT 2005 >Closed-Date: >Last-Modified: >Originator: John E. Hein >Release: FreeBSD 4.8-RELEASE i386 >Organization: Timing Solutions >Environment: System: noticed on 4.x; still appears to be a problem on -current >Description: Some situations - embedded products, for instance - call for a read-only root (& /etc) file system. In such cases, we sym-link /etc/resolv.conf to a writable file system (e.g., /some/where/etc/resolv.conf). In 4.x, the 'rm /etc/resolv.conf.std' in dhclient-script fails and lines are appended to the actual resolv.conf file. Over time, it can get quite large (in the case where new_domain_name is empty and thus the rm /etc/resolv.conf is attempted)). In this case the easy fix is 'cp /dev/null /etc/resolv.conf' rather than using 'rm'. In -current, the problem is similar but the effect can be different. The way dhclient-script works there, a temporary /etc/resolv.conf.std file is written to, then its contents is cat'd to the real resolv.conf. If /etc/resolv.conf.std does not exist on a read-only /etc, resolv.conf will never populate. If /etc/resolv.conf.std is a sym link (because the someone using a read-only /etc has looked into dhclient-script and seen what files it writes to), then you will hit the 'growing' resolv.conf issue described above. NB: I have not actually tried it on -current yet. I have just looked at the add_new_resolv_conf() function. If I did not dig deep enough, I apologize. I'll try to verify it on -current when I get a chance. >How-To-Repeat: mount -ur / Then run dhclient for your interface (using a dhcp server that supplies DNS server info). Observe the effects (or lack thereof) on resolv.conf >Fix: Here's a patch for -current. The choice of using TMPDIR may be wrong. There could be a possible security issue, but I'm not clear about all the ways dhclient-script can be invoked. Writing to a less accessible directory might be prudent. And using an env var here may allow a malicious user could point TMPDIR somewhere undesirable. Somewhere under /var/run might be a better place. OpenBSD's version has the same problem. Index: dhclient-script =================================================================== RCS file: /base/FreeBSD-CVS/src/sbin/dhclient/dhclient-script,v retrieving revision 1.10 diff -u -p -r1.10 dhclient-script --- dhclient-script 8 Sep 2005 22:49:17 -0000 1.10 +++ dhclient-script 16 Dec 2005 20:31:52 -0000 @@ -134,21 +134,22 @@ add_new_resolv_conf() { # thus broke the script. This code creates the resolv.conf if either # are provided. - rm -f /etc/resolv.conf.std + local tmpres=${TMPDIR:-/tmp}/resolv.conf.std + rm -f $tmpres if [ -n "$new_domain_name" ]; then - echo "search $new_domain_name" >>/etc/resolv.conf.std + echo "search $new_domain_name" >>$tmpres fi if [ -n "$new_domain_name_servers" ]; then for nameserver in $new_domain_name_servers; do - echo "nameserver $nameserver" >>/etc/resolv.conf.std + echo "nameserver $nameserver" >>$tmpres done fi - if [ -f /etc/resolv.conf.std ]; then + if [ -f $tmpres ]; then if [ -f /etc/resolv.conf.tail ]; then - cat /etc/resolv.conf.tail >>/etc/resolv.conf.std + cat /etc/resolv.conf.tail >>$tmpres fi # When resolv.conf is not changed actually, we don't @@ -156,8 +157,8 @@ add_new_resolv_conf() { # If /usr is not mounted yet, we cannot use cmp, then # the following test fails. In such case, we simply # ignore an error and do update resolv.conf. - if cmp -s /etc/resolv.conf.std /etc/resolv.conf; then - rm -f /etc/resolv.conf.std + if cmp -s $tmpres /etc/resolv.conf; then + rm -f $tmpres return 0 fi 2>/dev/null @@ -168,8 +169,8 @@ add_new_resolv_conf() { if [ -f /etc/resolv.conf ]; then cat /etc/resolv.conf > /etc/resolv.conf.save fi - cat /etc/resolv.conf.std > /etc/resolv.conf - rm -f /etc/resolv.conf.std + cat $tmpres > /etc/resolv.conf + rm -f $tmpres # Try to ensure correct ownership and permissions. chown -RL root:wheel /etc/resolv.conf >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200512162046.jBGKkxn7001129>