Skip to content

Commit 827fd6e

Browse files
authored
Fix two address sanitizer bugs (#2078)
* Fix two address sanitizer bugs - NetworkSignalHandler attempts to read int64_t from unaligned memory. - Wrong destructor being called for SignalHandlers. * Add FIELD_RAW_SAFE This macro acts the same way FIELD_RAW, except it will use a std::optional rather than a raw pointer. Values extracted with this new macro need to be trivially copyable so they can be moved to a variable with proper alignment.
1 parent 4de6015 commit 827fd6e

File tree

6 files changed

+48
-9
lines changed

6 files changed

+48
-9
lines changed

collector/lib/NetworkSignalHandler.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "NetworkSignalHandler.h"
22

3+
#include <cstring>
34
#include <optional>
45

56
#include <libsinsp/sinsp.h>
@@ -88,8 +89,8 @@ std::optional<Connection> NetworkSignalHandler::GetConnection(sinsp_evt* evt) {
8889
}
8990
}
9091

91-
const int64_t* res = event_extractor_->get_event_rawres(evt);
92-
if (!res || *res < 0) {
92+
auto res = event_extractor_->get_event_rawres(evt);
93+
if (!res.has_value() || res.value() < 0) {
9394
// ignore unsuccessful events for now.
9495
return std::nullopt;
9596
}

collector/lib/NetworkSignalHandler.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class EventExtractor;
2020
class NetworkSignalHandler final : public SignalHandler {
2121
public:
2222
explicit NetworkSignalHandler(sinsp* inspector, std::shared_ptr<ConnectionTracker> conn_tracker, system_inspector::Stats* stats);
23-
~NetworkSignalHandler();
23+
~NetworkSignalHandler() override;
2424

2525
std::string GetName() override { return "NetworkSignalHandler"; }
2626
Result HandleSignal(sinsp_evt* evt) override;

collector/lib/ProcessSignalHandler.h

+6
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ class ProcessSignalHandler : public SignalHandler {
3030
stats_(stats),
3131
config_(config) {}
3232

33+
ProcessSignalHandler(const ProcessSignalHandler&) = delete;
34+
ProcessSignalHandler(ProcessSignalHandler&&) = delete;
35+
ProcessSignalHandler& operator=(const ProcessSignalHandler&) = delete;
36+
ProcessSignalHandler& operator=(ProcessSignalHandler&&) = delete;
37+
~ProcessSignalHandler() override = default;
38+
3339
bool Start() override;
3440
bool Stop() override;
3541
Result HandleSignal(sinsp_evt* evt) override;

collector/lib/SelfCheckHandler.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@ SignalHandler::Result SelfCheckNetworkHandler::HandleSignal(sinsp_evt* evt) {
5656
return IGNORED;
5757
}
5858

59-
const uint16_t* server_port = event_extractor_->get_server_port(evt);
60-
const uint16_t* client_port = event_extractor_->get_client_port(evt);
59+
auto server_port = event_extractor_->get_server_port(evt);
60+
auto client_port = event_extractor_->get_client_port(evt);
6161

62-
if (server_port == nullptr || client_port == nullptr) {
62+
if (!server_port.has_value() | !client_port.has_value()) {
6363
return IGNORED;
6464
}
6565

collector/lib/SignalHandler.h

+7
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ class SignalHandler {
2525
FINISHED,
2626
};
2727

28+
SignalHandler() = default;
29+
SignalHandler(const SignalHandler&) = default;
30+
SignalHandler(SignalHandler&&) = delete;
31+
SignalHandler& operator=(const SignalHandler&) = default;
32+
SignalHandler& operator=(SignalHandler&&) = delete;
33+
virtual ~SignalHandler() = default;
34+
2835
virtual std::string GetName() = 0;
2936
virtual bool Start() { return true; }
3037
virtual bool Stop() { return true; }

collector/lib/system-inspector/EventExtractor.h

+28-3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,30 @@ class EventExtractor {
5757
private: \
5858
DECLARE_FILTER_CHECK(id, fieldname)
5959

60+
// When using FIELD_RAW_SAFE, type needs to be trivially copyable so we
61+
// can move it to a properly aligned variable.
62+
#define FIELD_RAW_SAFE(id, fieldname, type) \
63+
public: \
64+
const std::optional<type> get_##id(sinsp_evt* event) { \
65+
static_assert(std::is_trivially_copyable_v<type>, \
66+
"Attempted to create FIELD_RAW_SAFE on non trivial type"); \
67+
uint32_t len; \
68+
auto buf = filter_check_##id##_->extract_single(event, &len); \
69+
if (!buf) return {}; \
70+
if (len != sizeof(type)) { \
71+
CLOG_THROTTLED(WARNING, std::chrono::seconds(30)) \
72+
<< "Failed to extract value for field " << fieldname << ": expected type " << #type << " (size " \
73+
<< sizeof(type) << "), but returned value has size " << len; \
74+
return {}; \
75+
} \
76+
type val; \
77+
std::memcpy(&val, buf, sizeof(type)); \
78+
return {val}; \
79+
} \
80+
\
81+
private: \
82+
DECLARE_FILTER_CHECK(id, fieldname)
83+
6084
#define FIELD_CSTR(id, fieldname) \
6185
public: \
6286
const char* get_##id(sinsp_evt* event) { \
@@ -100,6 +124,7 @@ class EventExtractor {
100124
// - FIELD_CSTR(id, fieldname): exposes the system inspector field <fieldname> via get_<id>(), returning a null-terminated
101125
// const char*.
102126
// - FIELD_RAW(id, fieldname, type): exposes the system inspector field <fieldname> via get_<id>(), returning a const <type>*.
127+
// - FIELD_RAW_SAFE(id, fieldname, type): exposes the system inspector field <fieldname> via get_<id>(), returning a std::optional<type>.
103128
// - EVT_ARG(argname): shorthand for FIELD_CSTR(evt_arg_<argname>, "evt.arg.<argname>")
104129
// - EVT_ARG_RAW(argname, type): shorthand for FIELD_RAW(evt_arg_<argname>, "evt.rawarg.<argname>", <type>)
105130
//
@@ -118,11 +143,11 @@ class EventExtractor {
118143
FIELD_CSTR(proc_args, "proc.args");
119144

120145
// General event information
121-
FIELD_RAW(event_rawres, "evt.rawres", int64_t);
146+
FIELD_RAW_SAFE(event_rawres, "evt.rawres", int64_t);
122147

123148
// File/network related
124-
FIELD_RAW(client_port, "fd.cport", uint16_t);
125-
FIELD_RAW(server_port, "fd.sport", uint16_t);
149+
FIELD_RAW_SAFE(client_port, "fd.cport", uint16_t);
150+
FIELD_RAW_SAFE(server_port, "fd.sport", uint16_t);
126151

127152
// k8s metadata
128153
FIELD_CSTR(k8s_namespace, "k8s.ns.name");

0 commit comments

Comments
 (0)