diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2024-11-27 17:23:09 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2024-12-11 15:22:17 +0000 |
| commit | 299ee674e6c124a35f1cf258df4f0f3c6e1db1f3 (patch) | |
| tree | 416b515e959a1d0a64a9516b1524a062ae63ba7d /executor/executor.cc | |
| parent | ff949d2512c5ac33d0407d26d80f1df77b2de0e7 (diff) | |
executor: query globs in the test program context
We query globs for 2 reasons:
1. Expand glob types in syscall descriptions.
2. Dynamic file probing for automatic descriptions generation.
In both of these contexts are are interested in files
that will be present during test program execution
(rather than normal unsandboxed execution).
For example, some files may not be accessible to test programs
after pivot root. On the other hand, we create and link
some additional files for the test program that don't
normally exist.
Add a new request type for querying of globs that are
executed in the test program context.
Diffstat (limited to 'executor/executor.cc')
| -rw-r--r-- | executor/executor.cc | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/executor/executor.cc b/executor/executor.cc index e8e1cb000..702f8c3b4 100644 --- a/executor/executor.cc +++ b/executor/executor.cc @@ -146,6 +146,7 @@ struct alignas(8) OutputData { std::atomic<uint32> consumed; std::atomic<uint32> completed; std::atomic<uint32> num_calls; + std::atomic<flatbuffers::Offset<flatbuffers::Vector<uint8_t>>> result_offset; struct { // Call index in the test program (they may be out-of-order is some syscalls block). int index; @@ -159,6 +160,7 @@ struct alignas(8) OutputData { consumed.store(0, std::memory_order_relaxed); completed.store(0, std::memory_order_relaxed); num_calls.store(0, std::memory_order_relaxed); + result_offset.store(0, std::memory_order_relaxed); } }; @@ -280,6 +282,7 @@ static bool flag_threaded; static bool flag_comparisons; static uint64 request_id; +static rpc::RequestType request_type; static uint64 all_call_signal; static bool all_extra_signal; @@ -417,6 +420,7 @@ struct handshake_req { struct execute_req { uint64 magic; uint64 id; + rpc::RequestType type; uint64 exec_flags; uint64 all_call_signal; bool all_extra_signal; @@ -791,6 +795,7 @@ void receive_execute() void parse_execute(const execute_req& req) { request_id = req.id; + request_type = req.type; flag_collect_signal = req.exec_flags & (1 << 0); flag_collect_cover = req.exec_flags & (1 << 1); flag_dedup_cover = req.exec_flags & (1 << 2); @@ -799,9 +804,9 @@ void parse_execute(const execute_req& req) all_call_signal = req.all_call_signal; all_extra_signal = req.all_extra_signal; - debug("[%llums] exec opts: procid=%llu threaded=%d cover=%d comps=%d dedup=%d signal=%d " + debug("[%llums] exec opts: reqid=%llu type=%llu procid=%llu threaded=%d cover=%d comps=%d dedup=%d signal=%d " " sandbox=%d/%d/%d/%d timeouts=%llu/%llu/%llu kernel_64_bit=%d\n", - current_time_ms() - start_time_ms, procid, flag_threaded, flag_collect_cover, + current_time_ms() - start_time_ms, request_id, (uint64)request_type, procid, flag_threaded, flag_collect_cover, flag_comparisons, flag_dedup_cover, flag_collect_signal, flag_sandbox_none, flag_sandbox_setuid, flag_sandbox_namespace, flag_sandbox_android, syscall_timeout_ms, program_timeout_ms, slowdown_scale, is_kernel_64_bit); @@ -837,9 +842,35 @@ void realloc_output_data() #endif } +void execute_glob() +{ + const char* pattern = (const char*)input_data; + const auto& files = Glob(pattern); + size_t size = 0; + for (const auto& file : files) + size += file.size() + 1; + mmap_output(kMaxOutput); + ShmemBuilder fbb(output_data, kMaxOutput, true); + uint8_t* pos = nullptr; + auto off = fbb.CreateUninitializedVector(size, &pos); + for (const auto& file : files) { + memcpy(pos, file.c_str(), file.size() + 1); + pos += file.size() + 1; + } + output_data->consumed.store(fbb.GetSize(), std::memory_order_release); + output_data->result_offset.store(off, std::memory_order_release); +} + // execute_one executes program stored in input_data. void execute_one() { + if (request_type == rpc::RequestType::Glob) { + execute_glob(); + return; + } + if (request_type != rpc::RequestType::Program) + failmsg("bad request type", "type=%llu", (uint64)request_type); + in_execute_one = true; #if GOOS_linux char buf[64]; @@ -1382,8 +1413,9 @@ flatbuffers::span<uint8_t> finish_output(OutputData* output, int proc_id, uint64 flatbuffers::Offset<flatbuffers::String> error_off = 0; if (status == kFailStatus) error_off = fbb.CreateString("process failed"); - flatbuffers::Offset<flatbuffers::Vector<uint8_t>> output_off = 0; - if (process_output) + // If the request wrote binary result (currently glob requests do this), use it instead of the output. + auto output_off = output->result_offset.load(std::memory_order_relaxed); + if (output_off.IsNull() && process_output) output_off = fbb.CreateVector(*process_output); auto exec_off = rpc::CreateExecResultRaw(fbb, req_id, proc_id, output_off, hanged, error_off, prog_info_off); auto msg_off = rpc::CreateExecutorMessageRaw(fbb, rpc::ExecutorMessagesRaw::ExecResult, |
