Commit 1517db71 authored by Sergey Volk's avatar Sergey Volk Committed by Commit Bot

Fix crashes due to evaluation order

Due to unspecified function argument evaluation order in C++ some
compilers might choose to evaluate base::Passed earlier than subsequent
smart pointer access, so we need to be extra careful and save raw
pointer values before using them. Otherwise they might no longer be
valid by the time we call ptr.get due to the pointer being already
modified by the base::Passed.

BUG=734325

Change-Id: Icb5a06c42c14018c98ab8ddaffcc1fd41f3111ab
Reviewed-on: https://chromium-review.googlesource.com/885091Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarZentaro Kavanagh <zentaro@chromium.org>
Commit-Queue: Sergey Volk <servolk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#532704}
parent 9f82da87
...@@ -210,11 +210,14 @@ void NetworkingPrivateLinux::GetState( ...@@ -210,11 +210,14 @@ void NetworkingPrivateLinux::GetState(
new base::DictionaryValue); new base::DictionaryValue);
// Runs GetCachedNetworkProperties on |dbus_thread|. // Runs GetCachedNetworkProperties on |dbus_thread|.
std::string* error_ptr = error.get();
base::DictionaryValue* network_prop_ptr = network_properties.get();
dbus_thread_.task_runner()->PostTaskAndReply( dbus_thread_.task_runner()->PostTaskAndReply(
FROM_HERE, base::Bind(&NetworkingPrivateLinux::GetCachedNetworkProperties, FROM_HERE,
base::Unretained(this), guid, base::Bind(&NetworkingPrivateLinux::GetCachedNetworkProperties,
base::Unretained(network_properties.get()), base::Unretained(this), guid,
base::Unretained(error.get())), base::Unretained(network_prop_ptr),
base::Unretained(error_ptr)),
base::Bind(&GetCachedNetworkPropertiesCallback, base::Passed(&error), base::Bind(&GetCachedNetworkPropertiesCallback, base::Passed(&error),
base::Passed(&network_properties), success_callback, base::Passed(&network_properties), success_callback,
failure_callback)); failure_callback));
...@@ -297,11 +300,12 @@ void NetworkingPrivateLinux::GetNetworks( ...@@ -297,11 +300,12 @@ void NetworkingPrivateLinux::GetNetworks(
// Runs GetAllWiFiAccessPoints on the dbus_thread and returns the // Runs GetAllWiFiAccessPoints on the dbus_thread and returns the
// results back to OnAccessPointsFound where the callback is fired. // results back to OnAccessPointsFound where the callback is fired.
NetworkMap* network_map_ptr = network_map.get();
dbus_thread_.task_runner()->PostTaskAndReply( dbus_thread_.task_runner()->PostTaskAndReply(
FROM_HERE, FROM_HERE,
base::Bind(&NetworkingPrivateLinux::GetAllWiFiAccessPoints, base::Bind(&NetworkingPrivateLinux::GetAllWiFiAccessPoints,
base::Unretained(this), configured_only, visible_only, limit, base::Unretained(this), configured_only, visible_only, limit,
base::Unretained(network_map.get())), base::Unretained(network_map_ptr)),
base::Bind(&NetworkingPrivateLinux::OnAccessPointsFound, base::Bind(&NetworkingPrivateLinux::OnAccessPointsFound,
base::Unretained(this), base::Passed(&network_map), base::Unretained(this), base::Passed(&network_map),
success_callback, failure_callback)); success_callback, failure_callback));
...@@ -317,11 +321,13 @@ bool NetworkingPrivateLinux::GetNetworksForScanRequest() { ...@@ -317,11 +321,13 @@ bool NetworkingPrivateLinux::GetNetworksForScanRequest() {
// Runs GetAllWiFiAccessPoints on the dbus_thread and returns the // Runs GetAllWiFiAccessPoints on the dbus_thread and returns the
// results back to SendNetworkListChangedEvent to fire the event. No // results back to SendNetworkListChangedEvent to fire the event. No
// callbacks are used in this case. // callbacks are used in this case.
NetworkMap* network_map_ptr = network_map.get();
dbus_thread_.task_runner()->PostTaskAndReply( dbus_thread_.task_runner()->PostTaskAndReply(
FROM_HERE, base::Bind(&NetworkingPrivateLinux::GetAllWiFiAccessPoints, FROM_HERE,
base::Unretained(this), false /* configured_only */, base::Bind(&NetworkingPrivateLinux::GetAllWiFiAccessPoints,
false /* visible_only */, 0 /* limit */, base::Unretained(this), false /* configured_only */,
base::Unretained(network_map.get())), false /* visible_only */, 0 /* limit */,
base::Unretained(network_map_ptr)),
base::Bind(&NetworkingPrivateLinux::OnAccessPointsFoundViaScan, base::Bind(&NetworkingPrivateLinux::OnAccessPointsFoundViaScan,
base::Unretained(this), base::Passed(&network_map))); base::Unretained(this), base::Passed(&network_map)));
...@@ -503,10 +509,11 @@ void NetworkingPrivateLinux::StartConnect( ...@@ -503,10 +509,11 @@ void NetworkingPrivateLinux::StartConnect(
std::unique_ptr<std::string> error(new std::string); std::unique_ptr<std::string> error(new std::string);
// Runs ConnectToNetwork on |dbus_thread|. // Runs ConnectToNetwork on |dbus_thread|.
std::string* error_ptr = error.get();
dbus_thread_.task_runner()->PostTaskAndReply( dbus_thread_.task_runner()->PostTaskAndReply(
FROM_HERE, FROM_HERE,
base::Bind(&NetworkingPrivateLinux::ConnectToNetwork, base::Bind(&NetworkingPrivateLinux::ConnectToNetwork,
base::Unretained(this), guid, base::Unretained(error.get())), base::Unretained(this), guid, base::Unretained(error_ptr)),
base::Bind(&OnNetworkConnectOperationCompleted, base::Passed(&error), base::Bind(&OnNetworkConnectOperationCompleted, base::Passed(&error),
success_callback, failure_callback)); success_callback, failure_callback));
} }
...@@ -521,10 +528,11 @@ void NetworkingPrivateLinux::StartDisconnect( ...@@ -521,10 +528,11 @@ void NetworkingPrivateLinux::StartDisconnect(
std::unique_ptr<std::string> error(new std::string); std::unique_ptr<std::string> error(new std::string);
// Runs DisconnectFromNetwork on |dbus_thread|. // Runs DisconnectFromNetwork on |dbus_thread|.
std::string* error_ptr = error.get();
dbus_thread_.task_runner()->PostTaskAndReply( dbus_thread_.task_runner()->PostTaskAndReply(
FROM_HERE, FROM_HERE,
base::Bind(&NetworkingPrivateLinux::DisconnectFromNetwork, base::Bind(&NetworkingPrivateLinux::DisconnectFromNetwork,
base::Unretained(this), guid, base::Unretained(error.get())), base::Unretained(this), guid, base::Unretained(error_ptr)),
base::Bind(&OnNetworkConnectOperationCompleted, base::Passed(&error), base::Bind(&OnNetworkConnectOperationCompleted, base::Passed(&error),
success_callback, failure_callback)); success_callback, failure_callback));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment