From 6ef3e47010676e4e159edb346c219e8d30cabadc Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Thu, 23 May 2024 10:13:32 +0200 Subject: syz-fuzzer: repair leak checking Notify fuzzer from the manager when corpus triage has finished to start leak checking. Fixes #4728 --- pkg/flatrpc/flatrpc.fbs | 7 +++ pkg/flatrpc/flatrpc.go | 83 ++++++++++++++++++++++++++++---- pkg/flatrpc/flatrpc.h | 123 ++++++++++++++++++++++++++++++++++++++++++++++-- pkg/flatrpc/helpers.go | 1 + 4 files changed, 200 insertions(+), 14 deletions(-) (limited to 'pkg/flatrpc') diff --git a/pkg/flatrpc/flatrpc.fbs b/pkg/flatrpc/flatrpc.fbs index cdddef965..5b211bb31 100644 --- a/pkg/flatrpc/flatrpc.fbs +++ b/pkg/flatrpc/flatrpc.fbs @@ -76,6 +76,7 @@ table FeatureInfoRaw { union HostMessagesRaw { ExecRequest :ExecRequestRaw, SignalUpdate :SignalUpdateRaw, + StartLeakChecks :StartLeakChecksRaw } table HostMessageRaw { @@ -160,6 +161,12 @@ table SignalUpdateRaw { drop_max :[uint64]; } +// Leak checking is very slow so we don't do it while triaging the corpus +// (otherwise it takes infinity). This message serves as a signal that +// the corpus was triaged and the fuzzer can start leak checking. +table StartLeakChecksRaw { +} + // Notification from the executor that it started executing the program 'id'. // We want this request to be as small and as fast as possible b/c we need it // to reach the host (or at least leave the VM) before the VM crashes diff --git a/pkg/flatrpc/flatrpc.go b/pkg/flatrpc/flatrpc.go index 2ef9b2595..89172feeb 100644 --- a/pkg/flatrpc/flatrpc.go +++ b/pkg/flatrpc/flatrpc.go @@ -89,21 +89,24 @@ func (v Feature) String() string { type HostMessagesRaw byte const ( - HostMessagesRawNONE HostMessagesRaw = 0 - HostMessagesRawExecRequest HostMessagesRaw = 1 - HostMessagesRawSignalUpdate HostMessagesRaw = 2 + HostMessagesRawNONE HostMessagesRaw = 0 + HostMessagesRawExecRequest HostMessagesRaw = 1 + HostMessagesRawSignalUpdate HostMessagesRaw = 2 + HostMessagesRawStartLeakChecks HostMessagesRaw = 3 ) var EnumNamesHostMessagesRaw = map[HostMessagesRaw]string{ - HostMessagesRawNONE: "NONE", - HostMessagesRawExecRequest: "ExecRequest", - HostMessagesRawSignalUpdate: "SignalUpdate", + HostMessagesRawNONE: "NONE", + HostMessagesRawExecRequest: "ExecRequest", + HostMessagesRawSignalUpdate: "SignalUpdate", + HostMessagesRawStartLeakChecks: "StartLeakChecks", } var EnumValuesHostMessagesRaw = map[string]HostMessagesRaw{ - "NONE": HostMessagesRawNONE, - "ExecRequest": HostMessagesRawExecRequest, - "SignalUpdate": HostMessagesRawSignalUpdate, + "NONE": HostMessagesRawNONE, + "ExecRequest": HostMessagesRawExecRequest, + "SignalUpdate": HostMessagesRawSignalUpdate, + "StartLeakChecks": HostMessagesRawStartLeakChecks, } func (v HostMessagesRaw) String() string { @@ -127,6 +130,8 @@ func (t *HostMessagesRawT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffse return t.Value.(*ExecRequestRawT).Pack(builder) case HostMessagesRawSignalUpdate: return t.Value.(*SignalUpdateRawT).Pack(builder) + case HostMessagesRawStartLeakChecks: + return t.Value.(*StartLeakChecksRawT).Pack(builder) } return 0 } @@ -139,6 +144,9 @@ func (rcv HostMessagesRaw) UnPack(table flatbuffers.Table) *HostMessagesRawT { case HostMessagesRawSignalUpdate: x := SignalUpdateRaw{_tab: table} return &HostMessagesRawT{Type: HostMessagesRawSignalUpdate, Value: x.UnPack()} + case HostMessagesRawStartLeakChecks: + x := StartLeakChecksRaw{_tab: table} + return &HostMessagesRawT{Type: HostMessagesRawStartLeakChecks, Value: x.UnPack()} } return nil } @@ -2080,6 +2088,63 @@ func SignalUpdateRawEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { return builder.EndObject() } +type StartLeakChecksRawT struct { +} + +func (t *StartLeakChecksRawT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT { + if t == nil { + return 0 + } + StartLeakChecksRawStart(builder) + return StartLeakChecksRawEnd(builder) +} + +func (rcv *StartLeakChecksRaw) UnPackTo(t *StartLeakChecksRawT) { +} + +func (rcv *StartLeakChecksRaw) UnPack() *StartLeakChecksRawT { + if rcv == nil { + return nil + } + t := &StartLeakChecksRawT{} + rcv.UnPackTo(t) + return t +} + +type StartLeakChecksRaw struct { + _tab flatbuffers.Table +} + +func GetRootAsStartLeakChecksRaw(buf []byte, offset flatbuffers.UOffsetT) *StartLeakChecksRaw { + n := flatbuffers.GetUOffsetT(buf[offset:]) + x := &StartLeakChecksRaw{} + x.Init(buf, n+offset) + return x +} + +func GetSizePrefixedRootAsStartLeakChecksRaw(buf []byte, offset flatbuffers.UOffsetT) *StartLeakChecksRaw { + n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:]) + x := &StartLeakChecksRaw{} + x.Init(buf, n+offset+flatbuffers.SizeUint32) + return x +} + +func (rcv *StartLeakChecksRaw) Init(buf []byte, i flatbuffers.UOffsetT) { + rcv._tab.Bytes = buf + rcv._tab.Pos = i +} + +func (rcv *StartLeakChecksRaw) Table() flatbuffers.Table { + return rcv._tab +} + +func StartLeakChecksRawStart(builder *flatbuffers.Builder) { + builder.StartObject(0) +} +func StartLeakChecksRawEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { + return builder.EndObject() +} + type ExecutingMessageRawT struct { Id int64 `json:"id"` ProcId int32 `json:"proc_id"` diff --git a/pkg/flatrpc/flatrpc.h b/pkg/flatrpc/flatrpc.h index 649319e08..aa42c41d2 100644 --- a/pkg/flatrpc/flatrpc.h +++ b/pkg/flatrpc/flatrpc.h @@ -61,6 +61,10 @@ struct SignalUpdateRaw; struct SignalUpdateRawBuilder; struct SignalUpdateRawT; +struct StartLeakChecksRaw; +struct StartLeakChecksRawBuilder; +struct StartLeakChecksRawT; + struct ExecutingMessageRaw; struct ExecutingMessageRawBuilder; struct ExecutingMessageRawT; @@ -161,31 +165,34 @@ enum class HostMessagesRaw : uint8_t { NONE = 0, ExecRequest = 1, SignalUpdate = 2, + StartLeakChecks = 3, MIN = NONE, - MAX = SignalUpdate + MAX = StartLeakChecks }; -inline const HostMessagesRaw (&EnumValuesHostMessagesRaw())[3] { +inline const HostMessagesRaw (&EnumValuesHostMessagesRaw())[4] { static const HostMessagesRaw values[] = { HostMessagesRaw::NONE, HostMessagesRaw::ExecRequest, - HostMessagesRaw::SignalUpdate + HostMessagesRaw::SignalUpdate, + HostMessagesRaw::StartLeakChecks }; return values; } inline const char * const *EnumNamesHostMessagesRaw() { - static const char * const names[4] = { + static const char * const names[5] = { "NONE", "ExecRequest", "SignalUpdate", + "StartLeakChecks", nullptr }; return names; } inline const char *EnumNameHostMessagesRaw(HostMessagesRaw e) { - if (flatbuffers::IsOutRange(e, HostMessagesRaw::NONE, HostMessagesRaw::SignalUpdate)) return ""; + if (flatbuffers::IsOutRange(e, HostMessagesRaw::NONE, HostMessagesRaw::StartLeakChecks)) return ""; const size_t index = static_cast(e); return EnumNamesHostMessagesRaw()[index]; } @@ -202,6 +209,10 @@ template<> struct HostMessagesRawTraits { static const HostMessagesRaw enum_value = HostMessagesRaw::SignalUpdate; }; +template<> struct HostMessagesRawTraits { + static const HostMessagesRaw enum_value = HostMessagesRaw::StartLeakChecks; +}; + template struct HostMessagesRawUnionTraits { static const HostMessagesRaw enum_value = HostMessagesRaw::NONE; }; @@ -214,6 +225,10 @@ template<> struct HostMessagesRawUnionTraits { static const HostMessagesRaw enum_value = HostMessagesRaw::SignalUpdate; }; +template<> struct HostMessagesRawUnionTraits { + static const HostMessagesRaw enum_value = HostMessagesRaw::StartLeakChecks; +}; + struct HostMessagesRawUnion { HostMessagesRaw type; void *value; @@ -260,6 +275,14 @@ struct HostMessagesRawUnion { return type == HostMessagesRaw::SignalUpdate ? reinterpret_cast(value) : nullptr; } + rpc::StartLeakChecksRawT *AsStartLeakChecks() { + return type == HostMessagesRaw::StartLeakChecks ? + reinterpret_cast(value) : nullptr; + } + const rpc::StartLeakChecksRawT *AsStartLeakChecks() const { + return type == HostMessagesRaw::StartLeakChecks ? + reinterpret_cast(value) : nullptr; + } }; bool VerifyHostMessagesRaw(flatbuffers::Verifier &verifier, const void *obj, HostMessagesRaw type); @@ -1322,6 +1345,9 @@ struct HostMessageRaw FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const rpc::SignalUpdateRaw *msg_as_SignalUpdate() const { return msg_type() == rpc::HostMessagesRaw::SignalUpdate ? static_cast(msg()) : nullptr; } + const rpc::StartLeakChecksRaw *msg_as_StartLeakChecks() const { + return msg_type() == rpc::HostMessagesRaw::StartLeakChecks ? static_cast(msg()) : nullptr; + } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_MSG_TYPE, 1) && @@ -1342,6 +1368,10 @@ template<> inline const rpc::SignalUpdateRaw *HostMessageRaw::msg_as inline const rpc::StartLeakChecksRaw *HostMessageRaw::msg_as() const { + return msg_as_StartLeakChecks(); +} + struct HostMessageRawBuilder { typedef HostMessageRaw Table; flatbuffers::FlatBufferBuilder &fbb_; @@ -1676,6 +1706,45 @@ inline flatbuffers::Offset CreateSignalUpdateRawDirect( flatbuffers::Offset CreateSignalUpdateRaw(flatbuffers::FlatBufferBuilder &_fbb, const SignalUpdateRawT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +struct StartLeakChecksRawT : public flatbuffers::NativeTable { + typedef StartLeakChecksRaw TableType; +}; + +struct StartLeakChecksRaw FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef StartLeakChecksRawT NativeTableType; + typedef StartLeakChecksRawBuilder Builder; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + StartLeakChecksRawT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(StartLeakChecksRawT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const StartLeakChecksRawT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct StartLeakChecksRawBuilder { + typedef StartLeakChecksRaw Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit StartLeakChecksRawBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateStartLeakChecksRaw( + flatbuffers::FlatBufferBuilder &_fbb) { + StartLeakChecksRawBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateStartLeakChecksRaw(flatbuffers::FlatBufferBuilder &_fbb, const StartLeakChecksRawT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + struct ExecutingMessageRawT : public flatbuffers::NativeTable { typedef ExecutingMessageRaw TableType; int64_t id = 0; @@ -2494,6 +2563,29 @@ inline flatbuffers::Offset CreateSignalUpdateRaw(flatbuffers::F _drop_max); } +inline StartLeakChecksRawT *StartLeakChecksRaw::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = std::unique_ptr(new StartLeakChecksRawT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void StartLeakChecksRaw::UnPackTo(StartLeakChecksRawT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset StartLeakChecksRaw::Pack(flatbuffers::FlatBufferBuilder &_fbb, const StartLeakChecksRawT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateStartLeakChecksRaw(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateStartLeakChecksRaw(flatbuffers::FlatBufferBuilder &_fbb, const StartLeakChecksRawT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const StartLeakChecksRawT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return rpc::CreateStartLeakChecksRaw( + _fbb); +} + inline ExecutingMessageRawT *ExecutingMessageRaw::UnPack(const flatbuffers::resolver_function_t *_resolver) const { auto _o = std::unique_ptr(new ExecutingMessageRawT()); UnPackTo(_o.get(), _resolver); @@ -2681,6 +2773,10 @@ inline bool VerifyHostMessagesRaw(flatbuffers::Verifier &verifier, const void *o auto ptr = reinterpret_cast(obj); return verifier.VerifyTable(ptr); } + case HostMessagesRaw::StartLeakChecks: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } default: return true; } } @@ -2708,6 +2804,10 @@ inline void *HostMessagesRawUnion::UnPack(const void *obj, HostMessagesRaw type, auto ptr = reinterpret_cast(obj); return ptr->UnPack(resolver); } + case HostMessagesRaw::StartLeakChecks: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } default: return nullptr; } } @@ -2723,6 +2823,10 @@ inline flatbuffers::Offset HostMessagesRawUnion::Pack(flatbuffers::FlatBuf auto ptr = reinterpret_cast(value); return CreateSignalUpdateRaw(_fbb, ptr, _rehasher).Union(); } + case HostMessagesRaw::StartLeakChecks: { + auto ptr = reinterpret_cast(value); + return CreateStartLeakChecksRaw(_fbb, ptr, _rehasher).Union(); + } default: return 0; } } @@ -2737,6 +2841,10 @@ inline HostMessagesRawUnion::HostMessagesRawUnion(const HostMessagesRawUnion &u) value = new rpc::SignalUpdateRawT(*reinterpret_cast(u.value)); break; } + case HostMessagesRaw::StartLeakChecks: { + value = new rpc::StartLeakChecksRawT(*reinterpret_cast(u.value)); + break; + } default: break; } @@ -2754,6 +2862,11 @@ inline void HostMessagesRawUnion::Reset() { delete ptr; break; } + case HostMessagesRaw::StartLeakChecks: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } default: break; } value = nullptr; diff --git a/pkg/flatrpc/helpers.go b/pkg/flatrpc/helpers.go index 4ee5ad76b..22dc893fe 100644 --- a/pkg/flatrpc/helpers.go +++ b/pkg/flatrpc/helpers.go @@ -26,6 +26,7 @@ type ExecutorMessages = ExecutorMessagesRawT type ExecutorMessage = ExecutorMessageRawT type ExecRequest = ExecRequestRawT type SignalUpdate = SignalUpdateRawT +type StartLeakChecks = StartLeakChecksRawT type ExecutingMessage = ExecutingMessageRawT type CallInfo = CallInfoRawT type Comparison = ComparisonRawT -- cgit mrf-deployment