Skip to content
Open
28 changes: 26 additions & 2 deletions src/framework/eventloop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ void EventLoop::signalHandler(int signum) {

#include "socketreceiver.h"
#include "workerprocess.h"
#include <dirent.h>
#include <sys/resource.h>
#include <cstdlib>

#ifdef USE_THREADS
thread_local
Expand Down Expand Up @@ -79,9 +82,30 @@ int EventLoop::externalCommand(Task *owner, const char *const argv[]) {
return -1;
}
if (!chld) {
// TODO: Close all file descriptors in child!
// Close all file descriptors >= 3 in the child before exec
#if defined(__linux__) && !defined(_WIN32)
// Best effort: use /proc/self/fd
{
DIR *d = opendir("/proc/self/fd");
if (d) {
int dirfd_no = dirfd(d);
struct dirent *de;
while ((de = readdir(d))) {
int fd = atoi(de->d_name);
if (fd > 2 && fd != dirfd_no) close(fd);
}
closedir(d);
}
}
#else
// Fallback: close up to RLIMIT_NOFILE
struct rlimit rl;
if (getrlimit(RLIMIT_NOFILE, &rl) == 0) {
for (int fd = 3; fd < (int)rl.rlim_cur; ++fd) close(fd);
}
#endif
int ret = execvp( argv[0], const_cast<char **>(argv) );
exit(ret);
_exit(ret);
}
pidOwner[chld] = owner;
return chld;
Expand Down
4 changes: 2 additions & 2 deletions src/framework/mk.inc
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ CXXFLAGS += --pedantic -Wextra
endif

ifeq ($(GNUTLS),1)
CXXFLAGS += -DUSE_GNUTLS -I/usr/local/include
LIBS += -L/usr/local/lib -lgnutls
CXXFLAGS += -DUSE_GNUTLS $(shell pkg-config --cflags gnutls)
LIBS += $(shell pkg-config --libs gnutls)
endif
ifeq ($(THREADS),1)
CXXFLAGS += -DUSE_THREADS
Expand Down
12 changes: 11 additions & 1 deletion src/framework/socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@
#endif

#include <fcntl.h>

static inline void set_cloexec(int fd) {
if (fd >= 0) {
int flags = fcntl(fd, F_GETFD);
if (flags != -1) fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
}
}

#include <sys/types.h>

#include <cstdlib>
Expand Down Expand Up @@ -56,8 +64,10 @@ Socket::Socket(const std::string &label, Task *owner,
} else {
_socket = pair_sd[0];
unix_domain_peer = pair_sd[1];
set_cloexec(_socket);
set_cloexec(unix_domain_peer);
fcntl(pair_sd[0], F_SETFL, O_NONBLOCK|O_CLOEXEC);
fcntl(pair_sd[1], F_SETFL, O_NONBLOCK);
fcntl(pair_sd[1], F_SETFL, O_NONBLOCK|O_CLOEXEC);
}
return;
}
Expand Down
4 changes: 4 additions & 0 deletions src/framework/socketconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,12 @@ init_tls_client(gnutls_certificate_credentials_t &x509_cred, bool verify_cert) {
gnutls_session_set_verify_cert(session, peer_ip.c_str(), 0);
}

#ifndef ALLOW_BROKEN_TLS
// Do not weaken verification by default
#else
gnutls_certificate_set_verify_flags (x509_cred,
GNUTLS_VERIFY_ALLOW_BROKEN);
#endif

gnutls_handshake_set_timeout(session,
GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
Expand Down
25 changes: 21 additions & 4 deletions src/http/httpclientconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
#include "httpclienttask.h"
#include "http_common.h"
#include "sha1.h"
#include <array>
#include <unistd.h>
#include <fcntl.h>
#ifdef USE_GNUTLS
#include <gnutls/crypto.h>
#endif

HttpClientConnection::HttpClientConnection(const std::string &label,
HttpClientTask *task,
Expand Down Expand Up @@ -342,10 +348,21 @@ void HttpClientConnection::ws_get(const std::string &url) {
static char dst[] {
"01234567890123456789====258EAFA5-E914-47DA-95CA-C5AB0DC85B11" };

// 16 byte random data, convert to 24 base64 chars:
int32_t rnd[4] = { rand(), rand(), rand(), rand() };
const unsigned char *src = reinterpret_cast<const unsigned char *>(rnd);
base64_encode(src, sizeof(rnd), dst);
// 16-byte random data, convert to 24 base64 chars (RFC 6455)
std::array<unsigned char, 16> rnd{};
#ifdef USE_GNUTLS
gnutls_rnd(GNUTLS_RND_NONCE, rnd.data(), rnd.size());
#else
int fd = open("/dev/urandom", O_RDONLY);
if (fd >= 0) {
ssize_t n = read(fd, rnd.data(), rnd.size());
(void)n;
close(fd);
} else {
for (size_t i = 0; i < rnd.size(); ++i) rnd[i] = static_cast<unsigned char>(rand());
}
#endif
base64_encode(rnd.data(), rnd.size(), dst);

current_uri = url;
current_request = "GET " + proto_hostname +
Expand Down
9 changes: 6 additions & 3 deletions src/json11/json11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
// Modified by Göran Andersson <[email protected]>

#include "json11.hpp"
#include <cstdint>
#include <cassert>
#include <cmath>
#include <cstdlib>
Expand Down Expand Up @@ -98,13 +99,15 @@ static void dump(const string &value, string &out) {
out += "\\t";
} else if (static_cast<uint8_t>(ch) <= 0x1f) {
char buf[8];
snprintf(buf, sizeof buf, "\\u%04x", ch);
snprintf(buf, sizeof buf, "\\u%04x", static_cast<unsigned int>(static_cast<unsigned char>(ch)));
out += buf;
} else if (static_cast<uint8_t>(ch) == 0xe2 && static_cast<uint8_t>(value[i+1]) == 0x80
} else if (i + 2 < value.size()
&& static_cast<uint8_t>(ch) == 0xe2 && static_cast<uint8_t>(value[i+1]) == 0x80
&& static_cast<uint8_t>(value[i+2]) == 0xa8) {
out += "\\u2028";
i += 2;
} else if (static_cast<uint8_t>(ch) == 0xe2 && static_cast<uint8_t>(value[i+1]) == 0x80
} else if (i + 2 < value.size()
&& static_cast<uint8_t>(ch) == 0xe2 && static_cast<uint8_t>(value[i+1]) == 0x80
&& static_cast<uint8_t>(value[i+2]) == 0xa9) {
out += "\\u2029";
i += 2;
Expand Down
13 changes: 13 additions & 0 deletions src/measurement/defs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,20 @@ namespace {
#ifdef _WIN32
std::shared_ptr<FILE> pipe(_popen(cmd, "r"), _pclose);
#else
#ifdef NO_EXTERNAL_CMD
(void)cmd;
return std::string();
#else
// Basic guard: reject characters that imply shell metacharacters
for (const char *p = cmd; *p; ++p) {
switch (*p) {
case ';': case '|': case '&': case '`': case '$':
case '>': case '<': case '\n': case '\r':
return std::string();
}
}
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
#endif
#endif
if (pipe) {
while (!feof(pipe.get()))
Expand Down
18 changes: 17 additions & 1 deletion src/measurement/wsuploadtask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@

#include "wsuploadtask.h"
#include <vector>
#include <fcntl.h>
#include <unistd.h>
#ifdef USE_GNUTLS
#include <gnutls/crypto.h>
#endif
#include <array>

WsUploadTask::WsUploadTask(const std::string &ticket, const HttpHost &server,
unsigned int no_conn, unsigned int max_conn,
Expand All @@ -27,7 +33,17 @@ namespace {
std::vector<char> buf;
// Fill the buffer with dummy data that cannot cause data compression
while (len) {
buf.push_back(static_cast<char>(rand()));
#ifdef USE_GNUTLS
unsigned char x;
gnutls_rnd(GNUTLS_RND_NONCE, &x, 1);
buf.push_back(static_cast<char>(x));
#else
int fd = open("/dev/urandom", O_RDONLY);
unsigned char x;
if (fd >= 0) { read(fd, &x, 1); close(fd); }
else { x = static_cast<unsigned char>(rand()); }
buf.push_back(static_cast<char>(x));
#endif
--len;
}
return buf;
Expand Down