Bug 1782507 - Pin IPC fuzzing to new actor / last port after constructor. r=truber

Depends on D153344

Differential Revision: https://phabricator.services.mozilla.com/D153345
This commit is contained in:
Christian Holler 2022-08-05 17:23:00 +00:00
Родитель 031e7d573d
Коммит 385aa3a622
2 изменённых файлов: 54 добавлений и 10 удалений

Просмотреть файл

@ -127,6 +127,13 @@ void IPCFuzzController::OnActorConnected(IProtocol* protocol) {
MOZ_FUZZING_NYX_DEBUG( MOZ_FUZZING_NYX_DEBUG(
"DEBUG: IPCFuzzController::OnActorConnected() Mutex locked\n"); "DEBUG: IPCFuzzController::OnActorConnected() Mutex locked\n");
actorIds[*portName].emplace_back(protocol->Id(), protocol->GetProtocolId()); actorIds[*portName].emplace_back(protocol->Id(), protocol->GetProtocolId());
// Fix the port we will be using for at least the next 5 messages
useLastPortName = true;
lastActorPortName = *portName;
// Use this actor for the next 5 messages
useLastActor = 5;
} else { } else {
MOZ_FUZZING_NYX_PRINT("WARNING: No port name on actor?!\n"); MOZ_FUZZING_NYX_PRINT("WARNING: No port name on actor?!\n");
} }
@ -356,17 +363,25 @@ bool IPCFuzzController::MakeTargetDecision(
return false; return false;
} }
if (useLastActor) {
useLastActor--;
*name = lastActorPortName;
MOZ_FUZZING_NYX_PRINT("DEBUG: MakeTargetDecision: Pinned to last actor.\n");
// Once we stop pinning to the last actor, we need to decide if we
// want to keep the pinning on the port itself. We use one of the
// unused upper bits of portIndex for this purpose.
if (!useLastActor && (portIndex & (1 << 7))) {
MOZ_FUZZING_NYX_PRINT(
"DEBUG: MakeTargetDecision: Released pinning on last port.\n");
useLastPortName = false;
}
} else if (useLastPortName) {
*name = lastActorPortName;
MOZ_FUZZING_NYX_PRINT("DEBUG: MakeTargetDecision: Pinned to last port.\n");
} else {
*name = portInstances[portInstanceIndex % portInstances.size()]; *name = portInstances[portInstanceIndex % portInstances.size()];
auto seqNos = portSeqNos[*name];
// Hand out the correct sequence numbers
*seqno = seqNos.first - 1;
*fseqno = seqNos.second + 1;
if (update) {
portSeqNos.insert_or_assign(*name,
std::pair<int32_t, uint64_t>(*seqno, *fseqno));
} }
// We should always have at least one actor per port // We should always have at least one actor per port
@ -384,7 +399,23 @@ bool IPCFuzzController::MakeTargetDecision(
return false; return false;
} }
auto seqNos = portSeqNos[*name];
// Hand out the correct sequence numbers
*seqno = seqNos.first - 1;
*fseqno = seqNos.second + 1;
if (update) {
portSeqNos.insert_or_assign(*name,
std::pair<int32_t, uint64_t>(*seqno, *fseqno));
}
if (useLastActor) {
actorIndex = actors.size() - 1;
} else {
actorIndex %= actors.size(); actorIndex %= actors.size();
}
ActorIdPair ids = actors[actorIndex]; ActorIdPair ids = actors[actorIndex];
*actorId = ids.first; *actorId = ids.first;
@ -603,6 +634,9 @@ NS_IMETHODIMP IPCFuzzController::IPCFuzzLoop::Run() {
uint32_t expected_messages = 0; uint32_t expected_messages = 0;
IPCFuzzController::instance().useLastActor = 0;
IPCFuzzController::instance().useLastPortName = false;
for (int i = 0; i < 16; ++i) { for (int i = 0; i < 16; ++i) {
if (!buffer.initLengthUninitialized(maxMsgSize)) { if (!buffer.initLengthUninitialized(maxMsgSize)) {
MOZ_REALLY_CRASH(__LINE__); MOZ_REALLY_CRASH(__LINE__);

Просмотреть файл

@ -124,6 +124,16 @@ class IPCFuzzController {
std::unordered_map<mojo::core::ports::PortName, std::vector<ActorIdPair>> std::unordered_map<mojo::core::ports::PortName, std::vector<ActorIdPair>>
actorIds; actorIds;
// If set, `lastActorPortName` is valid and fuzzing is pinned to this port.
Atomic<bool> useLastPortName;
// Last port where a new actor appeared. Only valid with `useLastPortName`.
mojo::core::ports::PortName lastActorPortName;
// Counter to indicate how long fuzzing should stay pinned to the last
// actor that appeared on `lastActorPortName`.
Atomic<uint32_t> useLastActor;
// This is the deterministic ordering of toplevel actors for fuzzing. // This is the deterministic ordering of toplevel actors for fuzzing.
// In this matrix, each row (toplevel index) corresponds to one toplevel // In this matrix, each row (toplevel index) corresponds to one toplevel
// actor *type* while each entry in that row is an instance of that type, // actor *type* while each entry in that row is an instance of that type,