|
|
7c0489 |
From: Florian Weimer <fweimer@redhat.com>
|
|
|
7c0489 |
Date: Tue, 21 Jan 2020 16:38:15 +0000 (+0100)
|
|
|
7c0489 |
Subject: resolv: Fix ABA race in /etc/resolv.conf change detection [BZ #25420]
|
|
|
7c0489 |
X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=fa00db0a6eb755837ae5d413515e0da582b304f3
|
|
|
7c0489 |
|
|
|
7c0489 |
resolv: Fix ABA race in /etc/resolv.conf change detection [BZ #25420]
|
|
|
7c0489 |
|
|
|
7c0489 |
__resolv_conf_get_current should only record the initial file
|
|
|
7c0489 |
change data if after verifying that file just read matches the
|
|
|
7c0489 |
original measurement. Fixes commit aef16cc8a4c670036d45590877
|
|
|
7c0489 |
("resolv: Automatically reload a changed /etc/resolv.conf file
|
|
|
7c0489 |
[BZ #984]").
|
|
|
7c0489 |
|
|
|
7c0489 |
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
|
|
7c0489 |
---
|
|
|
7c0489 |
|
|
|
7c0489 |
diff --git a/resolv/resolv_conf.c b/resolv/resolv_conf.c
|
|
|
7c0489 |
index bdd2ebb909..29a1f4fb94 100644
|
|
|
7c0489 |
--- a/resolv/resolv_conf.c
|
|
|
7c0489 |
+++ b/resolv/resolv_conf.c
|
|
|
7c0489 |
@@ -136,18 +136,25 @@ __resolv_conf_get_current (void)
|
|
|
7c0489 |
{
|
|
|
7c0489 |
/* Parse configuration while holding the lock. This avoids
|
|
|
7c0489 |
duplicate work. */
|
|
|
7c0489 |
- conf = __resolv_conf_load (NULL, NULL);
|
|
|
7c0489 |
+ struct file_change_detection after_load;
|
|
|
7c0489 |
+ conf = __resolv_conf_load (NULL, &after_load);
|
|
|
7c0489 |
if (conf != NULL)
|
|
|
7c0489 |
{
|
|
|
7c0489 |
if (global_copy->conf_current != NULL)
|
|
|
7c0489 |
conf_decrement (global_copy->conf_current);
|
|
|
7c0489 |
global_copy->conf_current = conf; /* Takes ownership. */
|
|
|
7c0489 |
|
|
|
7c0489 |
- /* Update file modification stamps. The configuration we
|
|
|
7c0489 |
- read could be a newer version of the file, but this does
|
|
|
7c0489 |
- not matter because this will lead to an extraneous reload
|
|
|
7c0489 |
- later. */
|
|
|
7c0489 |
- global_copy->file_resolve_conf = initial;
|
|
|
7c0489 |
+ /* Update file change detection data, but only if it matches
|
|
|
7c0489 |
+ the initial measurement. This avoids an ABA race in case
|
|
|
7c0489 |
+ /etc/resolv.conf is temporarily replaced while the file
|
|
|
7c0489 |
+ is read (after the initial measurement), and restored to
|
|
|
7c0489 |
+ the initial version later. */
|
|
|
7c0489 |
+ if (file_is_unchanged (&initial, &after_load))
|
|
|
7c0489 |
+ global_copy->file_resolve_conf = after_load;
|
|
|
7c0489 |
+ else
|
|
|
7c0489 |
+ /* If there is a discrepancy, trigger a reload during the
|
|
|
7c0489 |
+ next use. */
|
|
|
7c0489 |
+ global_copy->file_resolve_conf.size = -1;
|
|
|
7c0489 |
}
|
|
|
7c0489 |
}
|
|
|
7c0489 |
|