blob: c1dfb674fd30a0137d32cd6f5bff3bc3e29b8cd8 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fuchsia/sysmem/c/fidl.h>
#include <fuchsia/sysmem/llcpp/fidl.h>
#include <lib/fake-bti/bti.h>
#include <lib/fake_ddk/fake_ddk.h>
#include <lib/fidl-async-2/fidl_struct.h>
#include <ddktl/protocol/platform/bus.h>
#include <src/devices/sysmem/drivers/sysmem/device.h>
#include <src/devices/sysmem/drivers/sysmem/driver.h>
#include "src/devices/sysmem/tests/sysmem/fuzz/sysmem_fuzz_common.h"
using BufferCollectionConstraints = FidlStruct<fuchsia_sysmem_BufferCollectionConstraints,
llcpp::fuchsia::sysmem::BufferCollectionConstraints>;
using BufferCollectionInfo = FidlStruct<fuchsia_sysmem_BufferCollectionInfo_2,
llcpp::fuchsia::sysmem::BufferCollectionInfo_2>;
#define DBGRTN 0
#define LOGRTN(status, ...) \
{ \
if (status != ZX_OK) { \
if (DBGRTN) { \
fprintf(stderr, __VA_ARGS__); \
fflush(stderr); \
} \
return 0; \
} \
}
#define LOGRTNC(condition, ...) \
{ \
if ((condition)) { \
if (DBGRTN) { \
fprintf(stderr, __VA_ARGS__); \
fflush(stderr); \
} \
return 0; \
} \
}
extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
const size_t kRequiredFuzzingBytes = sizeof(fuchsia_sysmem_BufferCollectionConstraints);
LOGRTNC(size != kRequiredFuzzingBytes, "size: %zu != kRequiredFuzzingBytes: %zu\n", size,
kRequiredFuzzingBytes);
FakeDdkSysmem fake_sysmem;
LOGRTNC(!fake_sysmem.Init(), "Failed FakeDdkSysmem::Init()\n");
zx::channel allocator_client;
zx_status_t status =
connect_to_sysmem_driver(fake_sysmem.ddk().FidlClient().get(), &allocator_client);
LOGRTN(status, "Failed to connect to sysmem driver.\n");
zx::channel token_server, token_client;
status = zx::channel::create(0u, &token_server, &token_client);
LOGRTN(status, "Failed token channel create.\n");
status = fuchsia_sysmem_AllocatorAllocateSharedCollection(allocator_client.get(),
token_server.release());
LOGRTN(status, "Failed to allocate shared collection.\n");
zx::channel collection_server, collection_client;
status = zx::channel::create(0, &collection_client, &collection_server);
LOGRTN(status, "Failed collection channel create.\n");
LOGRTNC(token_client.get() == ZX_HANDLE_INVALID, "Invalid token_client handle.\n");
status = fuchsia_sysmem_AllocatorBindSharedCollection(
allocator_client.get(), token_client.release(), collection_server.release());
LOGRTN(status, "Failed to bind shared collection.\n");
BufferCollectionConstraints constraints(BufferCollectionConstraints::Default);
memcpy(constraints.get(), data, kRequiredFuzzingBytes);
status = fuchsia_sysmem_BufferCollectionSetConstraints(collection_client.get(), true,
constraints.release());
LOGRTN(status, "Failed to set buffer collection constraints.\n");
zx_status_t allocation_status;
BufferCollectionInfo buffer_collection_info(BufferCollectionInfo::Default);
status = fuchsia_sysmem_BufferCollectionWaitForBuffersAllocated(
collection_client.get(), &allocation_status, buffer_collection_info.get());
// This is the first round-trip to/from sysmem. A failure here can be due
// to any step above failing async.
LOGRTN(status, "Failed on WaitForBuffersAllocated.\n");
LOGRTN(allocation_status, "Bad allocation_status on WaitForBuffersAllocated.\n");
return 0;
}