Fix data race in WebSocket where _url is accessed without protection in setThreadName

Also fix with url usage + docker container uses fedora and works with tsan
This commit is contained in:
Benjamin Sergeant 2019-04-25 16:07:49 -07:00
parent 7f96c43d6f
commit f6ae490723
7 changed files with 34 additions and 45 deletions

View File

@ -1 +1 @@
1.4.2 1.4.3

View File

@ -1,42 +1,32 @@
# Build time FROM fedora:30 as build
FROM debian:buster as build
ENV DEBIAN_FRONTEND noninteractive RUN yum install -y gcc-g++
RUN apt-get update RUN yum install -y cmake
RUN apt-get -y install wget RUN yum install -y make
RUN yum install -y openssl-devel
RUN yum install -y wget
RUN mkdir -p /tmp/cmake RUN mkdir -p /tmp/cmake
WORKDIR /tmp/cmake WORKDIR /tmp/cmake
RUN wget https://github.com/Kitware/CMake/releases/download/v3.14.0/cmake-3.14.0-Linux-x86_64.tar.gz RUN wget https://github.com/Kitware/CMake/releases/download/v3.14.0/cmake-3.14.0-Linux-x86_64.tar.gz
RUN tar zxf cmake-3.14.0-Linux-x86_64.tar.gz RUN tar zxf cmake-3.14.0-Linux-x86_64.tar.gz
RUN apt-get -y install g++
RUN apt-get -y install libssl-dev
RUN apt-get -y install libz-dev
RUN apt-get -y install make
COPY . .
ARG CMAKE_BIN_PATH=/tmp/cmake/cmake-3.14.0-Linux-x86_64/bin ARG CMAKE_BIN_PATH=/tmp/cmake/cmake-3.14.0-Linux-x86_64/bin
ENV PATH="${CMAKE_BIN_PATH}:${PATH}" ENV PATH="${CMAKE_BIN_PATH}:${PATH}"
RUN yum install -y python
RUN yum install -y libtsan
COPY . .
# RUN ["make", "test"]
RUN ["make"] RUN ["make"]
# Runtime # Runtime
FROM debian:buster as runtime FROM fedora:30 as runtime
ENV DEBIAN_FRONTEND noninteractive RUN yum install -y libtsan
RUN apt-get update
# Runtime
RUN apt-get install -y libssl1.1
RUN apt-get install -y ca-certificates
RUN ["update-ca-certificates"]
# Debugging RUN groupadd app && useradd -g app app
RUN apt-get install -y strace
RUN apt-get install -y procps
RUN apt-get install -y htop
RUN adduser --disabled-password --gecos '' app
COPY --chown=app:app --from=build /usr/local/bin/ws /usr/local/bin/ws COPY --chown=app:app --from=build /usr/local/bin/ws /usr/local/bin/ws
RUN chmod +x /usr/local/bin/ws RUN chmod +x /usr/local/bin/ws
RUN ldd /usr/local/bin/ws RUN ldd /usr/local/bin/ws

View File

@ -257,7 +257,7 @@ namespace ix
void WebSocket::run() void WebSocket::run()
{ {
setThreadName(_url); setThreadName(getUrl());
while (true) while (true)
{ {

View File

@ -8,6 +8,9 @@ project (ixwebsocket_unittest)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../third_party/sanitizers-cmake/cmake" ${CMAKE_MODULE_PATH}) set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../third_party/sanitizers-cmake/cmake" ${CMAKE_MODULE_PATH})
find_package(Sanitizers) find_package(Sanitizers)
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
# set(CMAKE_LD_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
set (CMAKE_CXX_STANDARD 14) set (CMAKE_CXX_STANDARD 14)
if (NOT WIN32) if (NOT WIN32)

View File

@ -61,6 +61,6 @@ protected:
const uint64_t max_batching_size = 32768; const uint64_t max_batching_size = 32768;
}; };
}; // end namespace } // end namespace
#endif #endif

View File

@ -205,20 +205,18 @@ namespace ix
} }
void CobraConnection::configure(const std::string& appkey, void CobraConnection::configure(const std::string& appkey,
const std::string& endpoint, const std::string& endpoint,
const std::string& rolename, const std::string& rolename,
const std::string& rolesecret, const std::string& rolesecret,
WebSocketPerMessageDeflateOptions webSocketPerMessageDeflateOptions) const WebSocketPerMessageDeflateOptions& webSocketPerMessageDeflateOptions)
{ {
_appkey = appkey; _roleName = rolename;
_endpoint = endpoint; _roleSecret = rolesecret;
_role_name = rolename;
_role_secret = rolesecret;
std::stringstream ss; std::stringstream ss;
ss << _endpoint; ss << endpoint;
ss << "/v2?appkey="; ss << "/v2?appkey=";
ss << _appkey; ss << appkey;
std::string url = ss.str(); std::string url = ss.str();
_webSocket->setUrl(url); _webSocket->setUrl(url);
@ -242,7 +240,7 @@ namespace ix
bool CobraConnection::sendHandshakeMessage() bool CobraConnection::sendHandshakeMessage()
{ {
Json::Value data; Json::Value data;
data["role"] = _role_name; data["role"] = _roleName;
Json::Value body; Json::Value body;
body["data"] = data; body["data"] = data;
@ -304,7 +302,7 @@ namespace ix
bool CobraConnection::sendAuthMessage(const std::string& nonce) bool CobraConnection::sendAuthMessage(const std::string& nonce)
{ {
Json::Value credentials; Json::Value credentials;
credentials["hash"] = hmac(nonce, _role_secret); credentials["hash"] = hmac(nonce, _roleSecret);
Json::Value body; Json::Value body;
body["credentials"] = credentials; body["credentials"] = credentials;

View File

@ -56,7 +56,7 @@ namespace ix
const std::string& endpoint, const std::string& endpoint,
const std::string& rolename, const std::string& rolename,
const std::string& rolesecret, const std::string& rolesecret,
WebSocketPerMessageDeflateOptions webSocketPerMessageDeflateOptions); const WebSocketPerMessageDeflateOptions& webSocketPerMessageDeflateOptions);
static void setTrafficTrackerCallback(const TrafficTrackerCallback& callback); static void setTrafficTrackerCallback(const TrafficTrackerCallback& callback);
@ -135,10 +135,8 @@ namespace ix
std::unique_ptr<WebSocket> _webSocket; std::unique_ptr<WebSocket> _webSocket;
/// Configuration data /// Configuration data
std::string _appkey; std::string _roleName;
std::string _endpoint; std::string _roleSecret;
std::string _role_name;
std::string _role_secret;
std::atomic<CobraConnectionPublishMode> _publishMode; std::atomic<CobraConnectionPublishMode> _publishMode;
// Can be set on control+background thread, protecting with an atomic // Can be set on control+background thread, protecting with an atomic