aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/subr_hints.c
diff options
context:
space:
mode:
authorKyle Evans <kevans@FreeBSD.org>2018-08-18 19:45:56 +0000
committerKyle Evans <kevans@FreeBSD.org>2018-08-18 19:45:56 +0000
commitd529de874b527a686ce9eee5e70ce1809e7bccea (patch)
treec5caa40e7fd2ad20d3753aa3e0c39ae7ed7aac39 /sys/kern/subr_hints.c
parentfdab4d3b293953a1d0c7fce2f5683be5c8ae49a5 (diff)
downloadsrc-d529de874b527a686ce9eee5e70ce1809e7bccea.tar.gz
src-d529de874b527a686ce9eee5e70ce1809e7bccea.zip
res_find: Fix fallback logic
The fallback logic was broken if hints were found in multiple environments. If we found a hint in either the loader environment or the static environment, fallback would be incremented excessively when we returned to the environment-selection bits. These checks should have also been guarded by the fbacklvl checks. As a result, fbacklvl could quickly get to a point where we skip either the static environment and/or the static hints depending on which environments contained valid hints. The impact of this bug is minimal, mostly affecting mips boards that use static hints and may have hints in either the loader environment or the static environment. There may be better ways to express the searchable environments and describing their characteristics (immutable, already searched, etc.) but this may be revisited after 12 branches. Reported by: Dan Nelson <dnelson_1901@yahoo.com> Triaged by: Dan Nelson <dnelson_1901@yahoo.com> MFC after: 3 days
Notes
Notes: svn path=/head/; revision=338020
Diffstat (limited to 'sys/kern/subr_hints.c')
-rw-r--r--sys/kern/subr_hints.c53
1 files changed, 30 insertions, 23 deletions
diff --git a/sys/kern/subr_hints.c b/sys/kern/subr_hints.c
index e63fe0cf3564..ba30e23d9f8a 100644
--- a/sys/kern/subr_hints.c
+++ b/sys/kern/subr_hints.c
@@ -174,30 +174,37 @@ fallback:
if (dyn_used || fbacklvl >= FBACK_STATIC)
return (ENOENT);
- if (fbacklvl <= FBACK_MDENV &&
- _res_checkenv(md_envp)) {
- hintp = md_envp;
- goto found;
+ switch (fbacklvl) {
+ case FBACK_MDENV:
+ fbacklvl++;
+ if (_res_checkenv(md_envp)) {
+ hintp = md_envp;
+ break;
+ }
+
+ /* FALLTHROUGH */
+ case FBACK_STENV:
+ fbacklvl++;
+ if (!stenv_skip && _res_checkenv(kern_envp)) {
+ hintp = kern_envp;
+ break;
+ } else
+ stenv_skip = true;
+
+ /* FALLTHROUGH */
+ case FBACK_STATIC:
+ fbacklvl++;
+ /* We'll fallback to static_hints if needed/can */
+ if (!sthints_skip &&
+ _res_checkenv(static_hints))
+ hintp = static_hints;
+ else
+ sthints_skip = true;
+
+ break;
+ default:
+ return (ENOENT);
}
- fbacklvl++;
-
- if (!stenv_skip && fbacklvl <= FBACK_STENV &&
- _res_checkenv(kern_envp)) {
- hintp = kern_envp;
- goto found;
- } else
- stenv_skip = true;
-
- fbacklvl++;
-
- /* We'll fallback to static_hints if needed/can */
- if (!sthints_skip && fbacklvl <= FBACK_STATIC &&
- _res_checkenv(static_hints))
- hintp = static_hints;
- else
- sthints_skip = true;
-found:
- fbacklvl++;
}
if (hintp == NULL)