1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

fix(Core): fix use after free of proxyAddrData

This commit is contained in:
sudden6 2018-06-21 15:48:59 +02:00
parent 9896b1b8a0
commit 26b59d3123
No known key found for this signature in database
GPG Key ID: 279509B499E032B9

View File

@ -115,16 +115,45 @@ CoreAV* Core::getAv()
namespace {
class ToxOptionsDeleter
/**
* @brief The ToxOptionsWrapper class wraps the Tox_Options struct and the matching
* proxy address data. This is needed to ensure both have equal lifetime and
* are correctly deleted.
*/
class ToxOptionsWrapper
{
public:
void operator()(Tox_Options* options)
{
tox_options_free(options);
ToxOptionsWrapper(Tox_Options *options, const QByteArray& proxyAddrData) {
this->options = options;
this->proxyAddrData = new QByteArray(proxyAddrData);
}
};
using ToxOptionsPtr = std::unique_ptr<Tox_Options, ToxOptionsDeleter>;
~ToxOptionsWrapper() {
tox_options_free(options);
options = nullptr;
delete proxyAddrData;
proxyAddrData = nullptr;
}
ToxOptionsWrapper (ToxOptionsWrapper && from) {
this->options = from.options;
from.options = nullptr;
this->proxyAddrData = from.proxyAddrData;
from.proxyAddrData = nullptr;
}
operator Tox_Options* () {
return options;
}
const char* getProxyAddrData() {
return this->proxyAddrData->data();
}
private:
Tox_Options *options = nullptr;
QByteArray *proxyAddrData = nullptr;
};
/**
* @brief Map TOX_LOG_LEVEL to a string
@ -179,9 +208,9 @@ void onLogMessage(Tox *tox, TOX_LOG_LEVEL level, const char *file, uint32_t line
/**
* @brief Initializes Tox_Options instance
* @param savedata Previously saved Tox data
* @return Tox_Options instance needed to create Tox instance
* @return ToxOptionsWrapper instance initialized to create Tox instance
*/
ToxOptionsPtr initToxOptions(const QByteArray& savedata, const ICoreSettings* s)
ToxOptionsWrapper initToxOptions(const QByteArray& savedata, const ICoreSettings* s)
{
// IPv6 needed for LAN discovery, but can crash some weird routers. On by default, can be
// disabled in options.
@ -192,7 +221,6 @@ ToxOptionsPtr initToxOptions(const QByteArray& savedata, const ICoreSettings* s)
ICoreSettings::ProxyType proxyType = s->getProxyType();
quint16 proxyPort = s->getProxyPort();
QString proxyAddr = s->getProxyAddr();
QByteArray proxyAddrData = proxyAddr.toUtf8();
if (!enableLanDiscovery) {
qWarning() << "Core starting without LAN discovery. Peers can only be found through DHT.";
@ -203,22 +231,22 @@ ToxOptionsPtr initToxOptions(const QByteArray& savedata, const ICoreSettings* s)
qWarning() << "Core starting with IPv6 disabled. LAN discovery may not work properly.";
}
ToxOptionsPtr toxOptions = ToxOptionsPtr(tox_options_new(nullptr));
ToxOptionsWrapper toxOptions = ToxOptionsWrapper(tox_options_new(nullptr), proxyAddr.toUtf8());
// register log first, to get messages as early as possible
tox_options_set_log_callback(toxOptions.get(), onLogMessage);
tox_options_set_log_callback(toxOptions, onLogMessage);
tox_options_set_ipv6_enabled(toxOptions.get(), enableIPv6);
tox_options_set_udp_enabled(toxOptions.get(), !forceTCP);
tox_options_set_local_discovery_enabled(toxOptions.get(), enableLanDiscovery);
tox_options_set_start_port(toxOptions.get(), 0);
tox_options_set_end_port(toxOptions.get(), 0);
tox_options_set_ipv6_enabled(toxOptions, enableIPv6);
tox_options_set_udp_enabled(toxOptions, !forceTCP);
tox_options_set_local_discovery_enabled(toxOptions, enableLanDiscovery);
tox_options_set_start_port(toxOptions, 0);
tox_options_set_end_port(toxOptions, 0);
// No proxy by default
tox_options_set_proxy_type(toxOptions.get(), TOX_PROXY_TYPE_NONE);
tox_options_set_proxy_host(toxOptions.get(), nullptr);
tox_options_set_proxy_port(toxOptions.get(), 0);
tox_options_set_savedata_type(toxOptions.get(), !savedata.isNull() ? TOX_SAVEDATA_TYPE_TOX_SAVE : TOX_SAVEDATA_TYPE_NONE);
tox_options_set_savedata_data(toxOptions.get(), reinterpret_cast<const uint8_t*>(savedata.data()), savedata.size());
tox_options_set_proxy_type(toxOptions, TOX_PROXY_TYPE_NONE);
tox_options_set_proxy_host(toxOptions, nullptr);
tox_options_set_proxy_port(toxOptions, 0);
tox_options_set_savedata_type(toxOptions, !savedata.isNull() ? TOX_SAVEDATA_TYPE_TOX_SAVE : TOX_SAVEDATA_TYPE_NONE);
tox_options_set_savedata_data(toxOptions, reinterpret_cast<const uint8_t*>(savedata.data()), savedata.size());
if (proxyType != ICoreSettings::ProxyType::ptNone) {
if (proxyAddr.length() > MAX_PROXY_ADDRESS_LENGTH) {
@ -227,13 +255,13 @@ ToxOptionsPtr initToxOptions(const QByteArray& savedata, const ICoreSettings* s)
qDebug() << "using proxy" << proxyAddr << ":" << proxyPort;
// protection against changings in TOX_PROXY_TYPE enum
if (proxyType == ICoreSettings::ProxyType::ptSOCKS5) {
tox_options_set_proxy_type(toxOptions.get(), TOX_PROXY_TYPE_SOCKS5);
tox_options_set_proxy_type(toxOptions, TOX_PROXY_TYPE_SOCKS5);
} else if (proxyType == ICoreSettings::ProxyType::ptHTTP) {
tox_options_set_proxy_type(toxOptions.get(), TOX_PROXY_TYPE_HTTP);
tox_options_set_proxy_type(toxOptions, TOX_PROXY_TYPE_HTTP);
}
tox_options_set_proxy_host(toxOptions.get(), proxyAddrData.data());
tox_options_set_proxy_port(toxOptions.get(), proxyPort);
tox_options_set_proxy_host(toxOptions, toxOptions.getProxyAddrData());
tox_options_set_proxy_port(toxOptions, proxyPort);
}
}
@ -248,7 +276,7 @@ ToxOptionsPtr initToxOptions(const QByteArray& savedata, const ICoreSettings* s)
*/
void Core::makeTox(QByteArray savedata)
{
ToxOptionsPtr toxOptions = initToxOptions(savedata, s);
ToxOptionsWrapper toxOptions = initToxOptions(savedata, s);
if (toxOptions == nullptr) {
qCritical() << "could not allocate Tox Options data structure";
emit failedToStart();
@ -256,7 +284,7 @@ void Core::makeTox(QByteArray savedata)
}
TOX_ERR_NEW tox_err;
tox = tox_new(toxOptions.get(), &tox_err);
tox = tox_new(toxOptions, &tox_err);
switch (tox_err) {
case TOX_ERR_NEW_OK:
@ -269,8 +297,8 @@ void Core::makeTox(QByteArray savedata)
case TOX_ERR_NEW_PORT_ALLOC:
if (s->getEnableIPv6()) {
tox_options_set_ipv6_enabled(toxOptions.get(), false);
tox = tox_new(toxOptions.get(), &tox_err);
tox_options_set_ipv6_enabled(toxOptions, false);
tox = tox_new(toxOptions, &tox_err);
if (tox_err == TOX_ERR_NEW_OK) {
qWarning() << "Core failed to start with IPv6, falling back to IPv4. LAN discovery "
"may not work properly.";