mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-27 03:33:33 +08:00
resolv: Fix ABA race in /etc/resolv.conf change detection [BZ #25420]
__resolv_conf_get_current should only record the initial file
change data if after verifying that file just read matches the
original measurement. Fixes commit aef16cc8a4
("resolv: Automatically reload a changed /etc/resolv.conf file
[BZ #984]").
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This commit is contained in:
parent
dd0b4df329
commit
fa00db0a6e
@ -136,18 +136,25 @@ __resolv_conf_get_current (void)
|
||||
{
|
||||
/* Parse configuration while holding the lock. This avoids
|
||||
duplicate work. */
|
||||
conf = __resolv_conf_load (NULL, NULL);
|
||||
struct file_change_detection after_load;
|
||||
conf = __resolv_conf_load (NULL, &after_load);
|
||||
if (conf != NULL)
|
||||
{
|
||||
if (global_copy->conf_current != NULL)
|
||||
conf_decrement (global_copy->conf_current);
|
||||
global_copy->conf_current = conf; /* Takes ownership. */
|
||||
|
||||
/* Update file modification stamps. The configuration we
|
||||
read could be a newer version of the file, but this does
|
||||
not matter because this will lead to an extraneous reload
|
||||
later. */
|
||||
global_copy->file_resolve_conf = initial;
|
||||
/* Update file change detection data, but only if it matches
|
||||
the initial measurement. This avoids an ABA race in case
|
||||
/etc/resolv.conf is temporarily replaced while the file
|
||||
is read (after the initial measurement), and restored to
|
||||
the initial version later. */
|
||||
if (file_is_unchanged (&initial, &after_load))
|
||||
global_copy->file_resolve_conf = after_load;
|
||||
else
|
||||
/* If there is a discrepancy, trigger a reload during the
|
||||
next use. */
|
||||
global_copy->file_resolve_conf.size = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user