0
Files
android_webview
apps
ash
base
build
build_overrides
buildtools
cc
chrome
chromecast
chromeos
clank
codelabs
components
content
crypto
dbus
device
docs
extensions
fuchsia_web
gin
google_apis
gpu
headless
infra
internal
ios
ios_internal
ipc
media
mojo
native_client
native_client_sdk
net
android
base
cert
cert_net
cookies
data
device_bound_sessions
disk_cache
dns
public
BUILD.gn
DIR_METADATA
OWNERS
README.md
address_info.cc
address_info.h
address_info_unittest.cc
address_sorter.h
address_sorter_posix.cc
address_sorter_posix.h
address_sorter_posix_unittest.cc
address_sorter_unittest.cc
address_sorter_win.cc
context_host_resolver.cc
context_host_resolver.h
context_host_resolver_unittest.cc
dns_alias_utility.cc
dns_alias_utility.h
dns_alias_utility_unittest.cc
dns_client.cc
dns_client.h
dns_client_unittest.cc
dns_config.cc
dns_config.h
dns_config_service.cc
dns_config_service.h
dns_config_service_android.cc
dns_config_service_android.h
dns_config_service_android_unittest.cc
dns_config_service_fuchsia.cc
dns_config_service_fuchsia.h
dns_config_service_linux.cc
dns_config_service_linux.h
dns_config_service_linux_unittest.cc
dns_config_service_posix.cc
dns_config_service_posix.h
dns_config_service_posix_unittest.cc
dns_config_service_unittest.cc
dns_config_service_win.cc
dns_config_service_win.h
dns_config_service_win_unittest.cc
dns_config_watcher_mac.cc
dns_config_watcher_mac.h
dns_hosts.cc
dns_hosts.h
dns_hosts_parse_fuzzer.cc
dns_hosts_unittest.cc
dns_names_util.cc
dns_names_util.h
dns_names_util_unittest.cc
dns_parse_domain_ascii_win_fuzzer.cc
dns_query.cc
dns_query.h
dns_query_parse_fuzzer.cc
dns_query_unittest.cc
dns_record_fuzzer.cc
dns_reloader.cc
dns_reloader.h
dns_response.cc
dns_response.h
dns_response_fuzzer.cc
dns_response_result_extractor.cc
dns_response_result_extractor.h
dns_response_result_extractor_unittest.cc
dns_response_unittest.cc
dns_server_iterator.cc
dns_server_iterator.h
dns_session.cc
dns_session.h
dns_task_results_manager.cc
dns_task_results_manager.h
dns_task_results_manager_unittest.cc
dns_test_util.cc
dns_test_util.h
dns_transaction.cc
dns_transaction.h
dns_transaction_unittest.cc
dns_udp_tracker.cc
dns_udp_tracker.h
dns_udp_tracker_unittest.cc
dns_util.cc
dns_util.h
dns_util_unittest.cc
fuzzed_host_resolver_util.cc
fuzzed_host_resolver_util.h
host_cache.cc
host_cache.h
host_cache_fuzzer.cc
host_cache_fuzzer.proto
host_cache_unittest.cc
host_resolver.cc
host_resolver.h
host_resolver_cache.cc
host_resolver_cache.h
host_resolver_cache_fuzzer.cc
host_resolver_cache_unittest.cc
host_resolver_dns_task.cc
host_resolver_dns_task.h
host_resolver_internal_result.cc
host_resolver_internal_result.h
host_resolver_internal_result_test_util.cc
host_resolver_internal_result_test_util.h
host_resolver_internal_result_unittest.cc
host_resolver_manager.cc
host_resolver_manager.h
host_resolver_manager_fuzzer.cc
host_resolver_manager_ipv6_reachability_override_unittest.cc
host_resolver_manager_job.cc
host_resolver_manager_job.h
host_resolver_manager_request_impl.cc
host_resolver_manager_request_impl.h
host_resolver_manager_service_endpoint_request_impl.cc
host_resolver_manager_service_endpoint_request_impl.h
host_resolver_manager_unittest.cc
host_resolver_manager_unittest.h
host_resolver_mdns_listener_impl.cc
host_resolver_mdns_listener_impl.h
host_resolver_mdns_task.cc
host_resolver_mdns_task.h
host_resolver_nat64_task.cc
host_resolver_nat64_task.h
host_resolver_proc.cc
host_resolver_proc.h
host_resolver_results_test_util.cc
host_resolver_results_test_util.h
host_resolver_service_endpoint_request_unittest.cc
host_resolver_system_task.cc
host_resolver_system_task.h
https_record_rdata.cc
https_record_rdata.h
https_record_rdata_fuzzer.cc
https_record_rdata_unittest.cc
httpssvc_metrics.cc
httpssvc_metrics.h
httpssvc_metrics_unittest.cc
loopback_only.cc
loopback_only.h
loopback_only_unittest.cc
mapped_host_resolver.cc
mapped_host_resolver.h
mapped_host_resolver_unittest.cc
mdns_cache.cc
mdns_cache.h
mdns_cache_unittest.cc
mdns_client.cc
mdns_client.h
mdns_client_impl.cc
mdns_client_impl.h
mdns_client_unittest.cc
mock_host_resolver.cc
mock_host_resolver.h
mock_mdns_client.cc
mock_mdns_client.h
mock_mdns_socket_factory.cc
mock_mdns_socket_factory.h
netinet_in_var_ios.h
notify_watcher_mac.cc
notify_watcher_mac.h
nsswitch_reader.cc
nsswitch_reader.h
nsswitch_reader_fuzzer.cc
nsswitch_reader_unittest.cc
opt_record_rdata.cc
opt_record_rdata.h
opt_record_rdata_unittest.cc
record_parsed.cc
record_parsed.h
record_parsed_unittest.cc
record_rdata.cc
record_rdata.h
record_rdata_unittest.cc
resolve_context.cc
resolve_context.h
resolve_context_unittest.cc
serial_worker.cc
serial_worker.h
serial_worker_unittest.cc
stale_host_resolver.cc
stale_host_resolver.h
stale_host_resolver_unittest.cc
system_dns_config_change_notifier.cc
system_dns_config_change_notifier.h
system_dns_config_change_notifier_unittest.cc
test_dns_config_service.cc
test_dns_config_service.h
docs
extras
filter
first_party_sets
http
log
network_error_logging
nqe
ntlm
proxy_resolution
quic
reporting
server
shared_dictionary
socket
spdy
ssl
storage_access_api
test
third_party
tools
traffic_annotation
url_request
websockets
BUILD.gn
COMMON_METADATA
DEPS
DIR_METADATA
OWNERS
PRESUBMIT.py
README.md
features.gni
pdf
ppapi
printing
remoting
rlz
sandbox
services
signing_keys
skia
sql
storage
styleguide
testing
third_party
tools
ui
url
v8
webkit
.clang-format
.clang-tidy
.clangd
.git-blame-ignore-revs
.gitallowed
.gitattributes
.gitignore
.gitmodules
.gn
.mailmap
.rustfmt.toml
.vpython3
.yapfignore
ATL_OWNERS
AUTHORS
BUILD.gn
CODE_OF_CONDUCT.md
CPPLINT.cfg
CRYPTO_OWNERS
DEPS
DIR_METADATA
LICENSE
LICENSE.chromium_os
OWNERS
PRESUBMIT.py
PRESUBMIT_test.py
PRESUBMIT_test_mocks.py
README.md
WATCHLISTS
codereview.settings
src/net/dns/loopback_only.cc
Tom Sepez 3afe88cc17 Prepare to remove net/ from unsafe_bufers_paths.txt
Suppress unsafe buffer usage on a file-by-file basis. A crude
analysis shows that approximately 1900 files are already compliant
vs. the 240 in this CL which are not.

Suppress only, by inserting boilerplate into affected files. Do not
re-write any code to work around the issues. That should be done in
finer-grained follow-up CLs.

Nor do we remove net/ from the unsafe_bufers_paths.txt file. Do that
in a smaller follow-up CL to ease a revert should it be necessary.

Bug: 40284755
Change-Id: I9cbe356fedae5e7351f6c07b7c0d36454aa1a66d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5564189
Reviewed-by: danakj <danakj@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Owners-Override: danakj <danakj@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1305316}
2024-05-23 20:35:23 +00:00

164 lines
5.7 KiB
C++

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
#pragma allow_unsafe_buffers
#endif
#include "net/dns/loopback_only.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/logging.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/threading/scoped_blocking_call.h"
#include "build/build_config.h"
#include "net/base/network_change_notifier.h"
#include "net/base/network_interfaces.h"
#include "net/base/sys_addrinfo.h"
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#include <net/if.h>
#if BUILDFLAG(IS_ANDROID)
#include "net/android/network_library.h"
#else // BUILDFLAG(IS_ANDROID)
#include <ifaddrs.h>
#endif // BUILDFLAG(IS_ANDROID)
#endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#if BUILDFLAG(IS_LINUX)
#include <linux/rtnetlink.h>
#include "net/base/address_map_linux.h"
#include "net/base/address_tracker_linux.h"
#include "net/base/network_interfaces_linux.h"
#endif
namespace net {
namespace {
#if (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)) || BUILDFLAG(IS_FUCHSIA)
bool HaveOnlyLoopbackAddressesUsingGetifaddrs() {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
struct ifaddrs* interface_addr = nullptr;
int rv = getifaddrs(&interface_addr);
if (rv != 0) {
DVPLOG(1) << "getifaddrs() failed";
return false;
}
bool result = true;
for (struct ifaddrs* interface = interface_addr; interface != nullptr;
interface = interface->ifa_next) {
if (!(IFF_UP & interface->ifa_flags)) {
continue;
}
if (IFF_LOOPBACK & interface->ifa_flags) {
continue;
}
const struct sockaddr* addr = interface->ifa_addr;
if (!addr) {
continue;
}
if (addr->sa_family == AF_INET6) {
// Safe cast since this is AF_INET6.
const struct sockaddr_in6* addr_in6 =
reinterpret_cast<const struct sockaddr_in6*>(addr);
const struct in6_addr* sin6_addr = &addr_in6->sin6_addr;
if (IN6_IS_ADDR_LOOPBACK(sin6_addr) || IN6_IS_ADDR_LINKLOCAL(sin6_addr)) {
continue;
}
}
if (addr->sa_family != AF_INET6 && addr->sa_family != AF_INET) {
continue;
}
result = false;
break;
}
freeifaddrs(interface_addr);
return result;
}
#endif // (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)) ||
// BUILDFLAG(IS_FUCHSIA)
// This implementation will always be posted to a thread pool.
bool HaveOnlyLoopbackAddressesSlow() {
#if BUILDFLAG(IS_WIN)
// TODO(wtc): implement with the GetAdaptersAddresses function.
NOTIMPLEMENTED();
return false;
#elif BUILDFLAG(IS_ANDROID)
return android::HaveOnlyLoopbackAddresses();
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
return HaveOnlyLoopbackAddressesUsingGetifaddrs();
#endif // defined(various platforms)
}
#if BUILDFLAG(IS_LINUX)
// This implementation can run on the main thread as it will not block.
bool HaveOnlyLoopbackAddressesFast(AddressMapOwnerLinux* address_map_owner) {
// The AddressMapOwnerLinux has already cached all the information necessary
// to determine if only loopback addresses exist.
AddressMapOwnerLinux::AddressMap address_map =
address_map_owner->GetAddressMap();
std::unordered_set<int> online_links = address_map_owner->GetOnlineLinks();
for (const auto& [address, ifaddrmsg] : address_map) {
// If there is an online link that isn't loopback or IPv6 link-local, return
// false.
// `online_links` shouldn't ever contain a loopback address, but keep the
// check as it is clearer and harmless.
//
// NOTE(2023-05-26): `online_links` only contains links with *both*
// IFF_LOWER_UP and IFF_UP, which is stricter than the
// HaveOnlyLoopbackAddressesUsingGetifaddrs() check above. LOWER_UP means
// the physical link layer is up and IFF_UP means the interface is
// administratively up. This new behavior might even be desirable, but if
// this causes issues it will need to be reverted.
if (online_links.contains(ifaddrmsg.ifa_index) && !address.IsLoopback() &&
!(address.IsIPv6() && address.IsLinkLocal())) {
return false;
}
}
return true;
}
#endif // BUILDFLAG(IS_LINUX)
} // namespace
void RunHaveOnlyLoopbackAddressesJob(
base::OnceCallback<void(bool)> finished_cb) {
#if BUILDFLAG(IS_LINUX)
// On Linux, this check can be fast if it accesses only network information
// that's cached by NetworkChangeNotifier, so there's no need to post this
// task to a thread pool. If HaveOnlyLoopbackAddressesFast() *is* posted to a
// different thread, it can cause a TSAN error when also setting a mock
// NetworkChangeNotifier in tests. So it's important to not run off the main
// thread if using cached, global information.
AddressMapOwnerLinux* address_map_owner =
NetworkChangeNotifier::GetAddressMapOwner();
if (address_map_owner) {
// Post `finished_cb` to avoid the bug-prone sometimes-synchronous behavior,
// which is only useful in latency-sensitive situations.
base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE,
base::BindOnce(std::move(finished_cb),
HaveOnlyLoopbackAddressesFast(address_map_owner)));
return;
}
#endif // BUILDFLAG(IS_LINUX)
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE,
{base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::BindOnce(&HaveOnlyLoopbackAddressesSlow), std::move(finished_cb));
}
} // namespace net