blob: d457e9d0da3c3c4e29d0ce3b70fda211ee620ba0 [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 <lib/fdio/limits.h>
#include <lib/zx/channel.h>
#include <lib/zx/process.h>
#include <zircon/processargs.h>
#include <test-utils/test-utils.h>
#include <zxtest/zxtest.h>
namespace {
// Ensure that the child crashes when given bogus fd handle info.
template <uint32_t... Info>
void BadFdTest() {
const char* const argv[] = {"/pkg/bin/hello-world", nullptr};
zx::channel bs_parent, bs_child;
ASSERT_OK(zx::channel::create(0, &bs_parent, &bs_child));
struct Message {
zx_proc_args_t header;
uint32_t handle_info[sizeof...(Info)];
} msg{};
zx_handle_t handles[sizeof...(Info)];
msg.header.protocol = ZX_PROCARGS_PROTOCOL;
msg.header.version = ZX_PROCARGS_VERSION;
msg.header.handle_info_off = offsetof(Message, handle_info);
zx_handle_t* h = handles;
uint32_t* i = msg.handle_info;
for (uint32_t info : {Info...}) {
zx::channel c0, c1;
ASSERT_OK(zx::channel::create(0, &c0, &c1));
*h++ = c1.release();
*i++ = info;
ASSERT_OK(bs_parent.write(0, &msg, sizeof(msg), handles, sizeof...(Info)));
auto sb = tu_launch_init(ZX_HANDLE_INVALID, nullptr, 1, argv, 0, nullptr, 0, nullptr, nullptr);
springboard_set_bootstrap(sb, bs_child.release());
zx::process proc(tu_launch_fini(sb));
zx_signals_t signals;
ASSERT_OK(proc.wait_one(ZX_PROCESS_TERMINATED, zx::time::infinite(), &signals));
zx_info_process_t pinfo;
ASSERT_OK(proc.get_info(ZX_INFO_PROCESS, &pinfo, sizeof(pinfo), nullptr, nullptr));
EXPECT_NE(pinfo.return_code, 0);
TEST(Startup, InvalidFd) { BadFdTest<PA_HND(PA_FD, FDIO_MAX_FD)>(); }
TEST(Startup, DuplicateFd) { BadFdTest<PA_HND(PA_FD, 0), PA_HND(PA_FD, 0)>(); }
} // namespace