summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorJan-Arve Sæther <jan-arve.saether@nokia.com>2010-08-31 08:23:30 (GMT)
committerJan-Arve Sæther <jan-arve.saether@nokia.com>2010-09-03 08:22:25 (GMT)
commit5738dcd705e7edde816940f9c0ab2c364c81ad20 (patch)
treee6be0a4b0f11289a7f0e8f6b4d4cce1de28aee8e /src/network
parentdac9e5dd5644d29d6a8dde752e7c594727f16661 (diff)
downloadQt-5738dcd705e7edde816940f9c0ab2c364c81ad20.zip
Qt-5738dcd705e7edde816940f9c0ab2c364c81ad20.tar.gz
Qt-5738dcd705e7edde816940f9c0ab2c364c81ad20.tar.bz2
Ensure that we load system libraries from the correct location.
This was a security hole that has been there for a while, but the public awareness have recently rised so the threat is more imminent now. The solution is to fix all places where we dynamically load system libraries. More specifically, we now load all system libraries with an absolute path that points to a library in the system directory (usually c:\windows\system32). We therefore introduce a small class named QSystemLibrary that only loads libraries located in the system path. This shares some of the API with QLibrary (in order to make the patch as small as possible). We don't fix QLibrary due to risk of regressions. In addition, applications can fix the code that calls QLibrary themselves. The problem does not apply to Windows CE, since the search order is documented as not searching in the current directory. However, it touches some CE-specific code - therefore QSystemLibrary is sometimes used on WinCE (however, it will just do a normal LoadLibrary() since its safe anyway). This change does not affect the testability plugin (it is not clearly documented where that plugin is located, and the plugin should never be used in production code anyway) Loading OpenSSL libraries The ssl libraries are handled specially, and searched in this order (we cannot expect them to always be in the system folder): 1. Application path 2. System libraries path 3. Trying all paths inside the PATH environment variable Task-number: QT-3825 Reviewed-by: Thiago Macieira Reviewed-by: Peter Hartmann
Diffstat (limited to 'src/network')
-rw-r--r--src/network/kernel/qhostinfo_win.cpp14
-rw-r--r--src/network/kernel/qnetworkinterface_win.cpp3
-rw-r--r--src/network/kernel/qnetworkproxy_win.cpp15
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp36
4 files changed, 44 insertions, 24 deletions
diff --git a/src/network/kernel/qhostinfo_win.cpp b/src/network/kernel/qhostinfo_win.cpp
index b30204b..8241c84 100644
--- a/src/network/kernel/qhostinfo_win.cpp
+++ b/src/network/kernel/qhostinfo_win.cpp
@@ -49,7 +49,7 @@
#include "qhostinfo_p.h"
#include "private/qnativesocketengine_p.h"
#include <ws2tcpip.h>
-#include <qlibrary.h>
+#include <private/qsystemlibrary_p.h>
#include <qmutex.h>
#include <qurl.h>
#include <private/qmutexpool_p.h>
@@ -90,13 +90,13 @@ static void resolveLibrary()
// Attempt to resolve getaddrinfo(); without it we'll have to fall
// back to gethostbyname(), which has no IPv6 support.
#if !defined(Q_OS_WINCE)
- local_getaddrinfo = (getaddrinfoProto) QLibrary::resolve(QLatin1String("ws2_32.dll"), "getaddrinfo");
- local_freeaddrinfo = (freeaddrinfoProto) QLibrary::resolve(QLatin1String("ws2_32.dll"), "freeaddrinfo");
- local_getnameinfo = (getnameinfoProto) QLibrary::resolve(QLatin1String("ws2_32.dll"), "getnameinfo");
+ local_getaddrinfo = (getaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getaddrinfo");
+ local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "freeaddrinfo");
+ local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getnameinfo");
#else
- local_getaddrinfo = (getaddrinfoProto) QLibrary::resolve(QLatin1String("ws2.dll"), "getaddrinfo");
- local_freeaddrinfo = (freeaddrinfoProto) QLibrary::resolve(QLatin1String("ws2.dll"), "freeaddrinfo");
- local_getnameinfo = (getnameinfoProto) QLibrary::resolve(QLatin1String("ws2.dll"), "getnameinfo");
+ local_getaddrinfo = (getaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2"), "getaddrinfo");
+ local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2"), "freeaddrinfo");
+ local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2"), "getnameinfo");
#endif
}
diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp
index 056650d..a1d1df6 100644
--- a/src/network/kernel/qnetworkinterface_win.cpp
+++ b/src/network/kernel/qnetworkinterface_win.cpp
@@ -48,6 +48,7 @@
#include <qhostinfo.h>
#include <qhash.h>
#include <qurl.h>
+#include <private/qsystemlibrary_p.h>
QT_BEGIN_NAMESPACE
@@ -66,7 +67,7 @@ static void resolveLibs()
if (!done) {
done = true;
- HINSTANCE iphlpapiHnd = LoadLibrary(L"iphlpapi");
+ HINSTANCE iphlpapiHnd = QSystemLibrary::load(L"iphlpapi");
if (iphlpapiHnd == NULL)
return;
diff --git a/src/network/kernel/qnetworkproxy_win.cpp b/src/network/kernel/qnetworkproxy_win.cpp
index e801738..de7c245 100644
--- a/src/network/kernel/qnetworkproxy_win.cpp
+++ b/src/network/kernel/qnetworkproxy_win.cpp
@@ -51,6 +51,7 @@
#include <string.h>
#include <qt_windows.h>
#include <wininet.h>
+#include <private/qsystemlibrary_p.h>
/*
* Information on the WinHTTP DLL:
@@ -273,15 +274,15 @@ void QWindowsSystemProxy::init()
return;
#else
// load the winhttp.dll library
- HINSTANCE winhttpHnd = LoadLibrary(L"winhttp");
- if (!winhttpHnd)
+ QSystemLibrary lib(L"winhttp");
+ if (!lib.load())
return; // failed to load
- ptrWinHttpOpen = (PtrWinHttpOpen)GetProcAddress(winhttpHnd, "WinHttpOpen");
- ptrWinHttpCloseHandle = (PtrWinHttpCloseHandle)GetProcAddress(winhttpHnd, "WinHttpCloseHandle");
- ptrWinHttpGetProxyForUrl = (PtrWinHttpGetProxyForUrl)GetProcAddress(winhttpHnd, "WinHttpGetProxyForUrl");
- ptrWinHttpGetDefaultProxyConfiguration = (PtrWinHttpGetDefaultProxyConfiguration)GetProcAddress(winhttpHnd, "WinHttpGetDefaultProxyConfiguration");
- ptrWinHttpGetIEProxyConfigForCurrentUser = (PtrWinHttpGetIEProxyConfigForCurrentUser)GetProcAddress(winhttpHnd, "WinHttpGetIEProxyConfigForCurrentUser");
+ ptrWinHttpOpen = (PtrWinHttpOpen)lib.resolve("WinHttpOpen");
+ ptrWinHttpCloseHandle = (PtrWinHttpCloseHandle)lib.resolve("WinHttpCloseHandle");
+ ptrWinHttpGetProxyForUrl = (PtrWinHttpGetProxyForUrl)lib.resolve("WinHttpGetProxyForUrl");
+ ptrWinHttpGetDefaultProxyConfiguration = (PtrWinHttpGetDefaultProxyConfiguration)lib.resolve("WinHttpGetDefaultProxyConfiguration");
+ ptrWinHttpGetIEProxyConfigForCurrentUser = (PtrWinHttpGetIEProxyConfigForCurrentUser)lib.resolve("WinHttpGetIEProxyConfigForCurrentUser");
// Try to obtain the Internet Explorer configuration.
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxyConfig;
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index 8620e00..9e550ae 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -42,7 +42,11 @@
#include "qsslsocket_openssl_symbols_p.h"
-#include <QtCore/qlibrary.h>
+#ifdef Q_OS_WIN
+# include <private/qsystemlibrary_p.h>
+#else
+# include <QtCore/qlibrary.h>
+#endif
#include <QtCore/qmutex.h>
#include <private/qmutexpool_p.h>
#include <QtCore/qdatetime.h>
@@ -343,22 +347,22 @@ static QStringList findAllLibSsl()
}
# endif
-static QPair<QLibrary*, QLibrary*> loadOpenSsl()
+#ifdef Q_OS_WIN
+static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32()
{
- QPair<QLibrary*,QLibrary*> pair;
+ QPair<QSystemLibrary*,QSystemLibrary*> pair;
pair.first = 0;
pair.second = 0;
-# ifdef Q_OS_WIN
- QLibrary *ssleay32 = new QLibrary(QLatin1String("ssleay32"));
- if (!ssleay32->load()) {
+ QSystemLibrary *ssleay32 = new QSystemLibrary(QLatin1String("ssleay32"));
+ if (!ssleay32->load(false)) {
// Cannot find ssleay32.dll
delete ssleay32;
return pair;
}
- QLibrary *libeay32 = new QLibrary(QLatin1String("libeay32"));
- if (!libeay32->load()) {
+ QSystemLibrary *libeay32 = new QSystemLibrary(QLatin1String("libeay32"));
+ if (!libeay32->load(false)) {
delete ssleay32;
delete libeay32;
return pair;
@@ -367,7 +371,16 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl()
pair.first = ssleay32;
pair.second = libeay32;
return pair;
-# elif defined(Q_OS_SYMBIAN)
+}
+#else
+
+static QPair<QLibrary*, QLibrary*> loadOpenSsl()
+{
+ QPair<QLibrary*,QLibrary*> pair;
+ pair.first = 0;
+ pair.second = 0;
+
+# if defined(Q_OS_SYMBIAN)
QLibrary *libssl = new QLibrary(QLatin1String("libssl"));
if (!libssl->load()) {
// Cannot find ssleay32.dll
@@ -467,6 +480,7 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl()
return pair;
# endif
}
+#endif
bool q_resolveOpenSslSymbols()
{
@@ -481,7 +495,11 @@ bool q_resolveOpenSslSymbols()
return false;
triedToResolveSymbols = true;
+#ifdef Q_OS_WIN
+ QPair<QSystemLibrary *, QSystemLibrary *> libs = loadOpenSslWin32();
+#else
QPair<QLibrary *, QLibrary *> libs = loadOpenSsl();
+#endif
if (!libs.first || !libs.second)
// failed to load them
return false;