Skip to content

Commit 0fdbfd0

Browse files
committed
libc: Don't update resolv.conf on signature mismatch
Apparently some users just don't want to set resolvconf=NO or libc=NO in resolvconf.conf and do not expect resolvconf to overwrite their lovingly hand crafted file by default. This is fair, so only udpate resolv.conf if it's signature matches our expectation. If it does not match, warn noisly about it and prompt running `resolvconf -u` to fix it.
1 parent 5214317 commit 0fdbfd0

2 files changed

Lines changed: 33 additions & 37 deletions

File tree

libc.in

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,18 @@ KEYDIR="$VARDIR/keys"
3434
if [ ! -d "$KEYDIR" ] && [ -d "$VARDIR/interfaces" ]; then
3535
KEYDIR="$VARDIR/interfaces"
3636
fi
37+
38+
CMD="$1"
39+
KEY="$2"
40+
3741
NL="
3842
"
3943

44+
warn()
45+
{
46+
echo "$(basename $0): $*" >&2
47+
}
48+
4049
# sed may not be available, and this is faster on small files
4150
key_get_value()
4251
{
@@ -113,7 +122,6 @@ then
113122
resolv_conf_tail="$(cat "$SYSCONFDIR"/resolv.conf.tail)"
114123
fi
115124

116-
backup=true
117125
signature="# Generated by resolvconf"
118126

119127
uniqify()
@@ -131,15 +139,14 @@ uniqify()
131139

132140
case "${resolv_conf_passthrough:-NO}" in
133141
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
134-
backup=false
135142
newest=
136143
for conf in "$KEYDIR"/*; do
137144
if [ -z "$newest" ] || [ "$conf" -nt "$newest" ]; then
138145
newest="$conf"
139146
fi
140147
done
141148
[ -z "$newest" ] && exit 0
142-
newconf="$(cat "$newest")$NL"
149+
newconf="$signature$NL$(cat "$newest")$NL"
143150
;;
144151
/dev/null|[Nn][Uu][Ll][Ll])
145152
: ${resolv_conf_local_only:=NO}
@@ -215,33 +222,28 @@ esac
215222

216223
# Check if the file has actually changed or not
217224
if [ -e "$resolv_conf" ]; then
218-
[ "$(cat "$resolv_conf")" = "$(printf %s "$newconf")" ] && exit 0
219-
fi
220-
221-
# Change is good.
222-
# If the old file does not have our signature, back it up.
223-
# If the new file just has our signature, restore the backup.
224-
if $backup; then
225-
if [ "$newconf" = "$signature$NL" ]; then
226-
case "${resolv_conf_restore:=YES}" in
227-
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
228-
if [ -e "$resolv_conf.bak" ]; then
229-
newconf="$(cat "$resolv_conf.bak")$NL"
230-
fi
231-
;;
232-
esac
233-
elif [ -e "$resolv_conf" ]; then
234-
read line <"$resolv_conf"
235-
if [ "$line" != "$signature" ]; then
236-
cp "$resolv_conf" "$resolv_conf.bak"
225+
if [ "$CMD" != u ] && \
226+
[ "$(cat "$resolv_conf")" = "$(printf %s "$newconf")" ]
227+
then
228+
exit 0
229+
fi
230+
read line <"$resolv_conf"
231+
if [ "$line" != "$signature" ]; then
232+
if [ "$CMD" != u ]; then
233+
warn "signature mismatch: $resolv_conf"
234+
warn "run \`resolvconf -u\` to update"
235+
exit 1
237236
fi
237+
cp "$resolv_conf" "$resolv_conf.bak"
238238
fi
239239
fi
240240

241241
# There are pros and cons for writing directly to resolv.conf
242242
# instead of a temporary file and then moving it over.
243243
# The default is to write to resolv.conf as it has the least
244244
# issues and has been the long standing default behaviour.
245+
# resolv.conf could also be bind mounted for network namespaces
246+
# so we cannot move in this instance.
245247
case "${resolv_conf_mv:-NO}" in
246248
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
247249
# Protect against symlink attack, ensure new file does not exist

resolvconf.8.in

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2323
.\" SUCH DAMAGE.
2424
.\"
25-
.Dd June 24, 2025
25+
.Dd June 26, 2025
2626
.Dt RESOLVCONF 8
2727
.Os
2828
.Sh NAME
@@ -78,6 +78,14 @@ instead of the filesystem.
7878
then updates
7979
.Pa /etc/resolv.conf
8080
as it thinks best.
81+
If
82+
.Pa /etc/resolv.conf
83+
already exists and the top line does not match the expected signature,
84+
then
85+
.Nm
86+
will refuse to update it unless the
87+
.Fl u
88+
update command is given.
8189
When a local resolver other than libc is installed, such as
8290
.Xr dnsmasq 8
8391
or
@@ -111,20 +119,6 @@ outside of
111119
.Nm .
112120
.Pp
113121
.Nm
114-
assumes it has a job to do.
115-
In some situations
116-
.Nm
117-
needs to act as a deterrent to writing to
118-
.Pa /etc/resolv.conf .
119-
Where this file cannot be made immutable or you just need to toggle this
120-
behaviour,
121-
.Nm
122-
can be disabled by adding
123-
.Sy resolvconf Ns = Ns NO
124-
to
125-
.Xr resolvconf.conf 5 .
126-
.Pp
127-
.Nm
128122
can mark a
129123
.Pa resolv.conf
130124
as private and optionally non-searchable.

0 commit comments

Comments
 (0)