elf_runner/
error.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use clonable_error::ClonableError;
6
7use thiserror::Error;
8
9/// Errors produced when starting a component.
10#[derive(Debug, Clone, Error)]
11pub enum StartComponentError {
12    #[error("failed to register as exception handler: {_0}")]
13    ExceptionRegistrationFailed(#[source] zx::Status),
14    #[error("failed to get process koid: {_0}")]
15    ProcessGetKoidFailed(#[source] zx::Status),
16    #[error("failed to get process info: {_0}")]
17    ProcessInfoFailed(#[source] zx::Status),
18    #[error("failed to mark main process as critical: {_0}")]
19    ProcessMarkCriticalFailed(#[source] zx::Status),
20    #[error("could not create job: {_0}")]
21    JobError(#[from] JobError),
22    #[error("failed to duplicate job: {_0}")]
23    JobDuplicateFailed(#[source] zx::Status),
24    #[error("failed to get job koid: {_0}")]
25    JobGetKoidFailed(#[source] zx::Status),
26    #[error("failed to get vDSO: {_0}")]
27    VdsoError(#[from] VdsoError),
28    #[error("error connecting to fuchsia.process.Launcher protocol: {_0}")]
29    ProcessLauncherConnectError(#[source] ClonableError),
30    #[error("fidl error in fuchsia.process.Launcher protocol: {_0}")]
31    ProcessLauncherFidlError(#[source] fidl::Error),
32    #[error("fuchsia.process.Launcher failed to create process: {_0}")]
33    CreateProcessFailed(#[source] zx::Status),
34    #[error("failed to duplicate UTC clock: {_0}")]
35    UtcClockDuplicateFailed(#[source] zx::Status),
36    #[error("failed to process the component's config data: {_0}")]
37    ConfigDataError(#[from] runner::ConfigDataError),
38    #[error("could not create component namespace, {_0}")]
39    NamespaceError(#[from] namespace::NamespaceError),
40    #[error("error configuring process launcher: {_0}")]
41    LaunchError(#[from] runner::component::LaunchError),
42    #[error("invalid start info: {_0}")]
43    StartInfoError(#[from] StartInfoError),
44    #[error("failed to create boot clock: {_0}")]
45    BootClockCreateFailed(#[source] zx::Status),
46}
47
48impl StartComponentError {
49    /// Convert this error into its approximate `zx::Status` equivalent.
50    pub fn as_zx_status(&self) -> zx::Status {
51        match self {
52            StartComponentError::NamespaceError(_) => zx::Status::INVALID_ARGS,
53            StartComponentError::LaunchError(_) => zx::Status::UNAVAILABLE,
54            StartComponentError::StartInfoError(err) => err.as_zx_status(),
55            _ => zx::Status::INTERNAL,
56        }
57    }
58}
59
60/// Errors from creating and initializing a component's job.
61#[derive(Debug, Clone, Error)]
62pub enum JobError {
63    #[error("failed to set job policy: {_0}")]
64    SetPolicy(#[source] zx::Status),
65    #[error("failed to create child job: {_0}")]
66    CreateChild(#[source] zx::Status),
67}
68
69/// Errors from parsing ComponentStartInfo.
70#[derive(Debug, Clone, Error)]
71pub enum StartInfoError {
72    #[error(transparent)]
73    StartInfoError(#[from] runner::StartInfoError),
74    #[error("missing outgoing dir")]
75    MissingOutgoingDir,
76    #[error("missing runtime dir")]
77    MissingRuntimeDir,
78    #[error("missing component instance token")]
79    MissingComponentInstanceToken,
80    #[error("component resolved URL is malformed: {_0}")]
81    BadResolvedUrl(String),
82    #[error("program is invalid: {_0}")]
83    ProgramError(#[from] ProgramError),
84}
85
86impl StartInfoError {
87    /// Convert this error into its approximate `zx::Status` equivalent.
88    pub fn as_zx_status(&self) -> zx::Status {
89        match self {
90            StartInfoError::StartInfoError(err) => err.as_zx_status(),
91            StartInfoError::MissingOutgoingDir => zx::Status::INVALID_ARGS,
92            StartInfoError::MissingRuntimeDir => zx::Status::INVALID_ARGS,
93            StartInfoError::MissingComponentInstanceToken => zx::Status::INVALID_ARGS,
94            StartInfoError::BadResolvedUrl(_) => zx::Status::INVALID_ARGS,
95            StartInfoError::ProgramError(err) => err.as_zx_status(),
96        }
97    }
98}
99
100/// Errors from parsing the component `program` section to `ElfProgramConfig`.
101#[derive(Debug, Clone, Error)]
102pub enum ProgramError {
103    #[error(
104        "`is_shared_process` cannot be enabled without also enabling `job_policy_create_raw_processes`"
105    )]
106    SharedProcessRequiresJobPolicy,
107    #[error("failed to parse: {_0}")]
108    Parse(#[source] runner::StartInfoProgramError),
109    #[error("configuration violates policy: {_0}")]
110    Policy(#[source] routing::policy::PolicyError),
111}
112
113impl ProgramError {
114    /// Convert this error into its approximate `zx::Status` equivalent.
115    pub fn as_zx_status(&self) -> zx::Status {
116        match self {
117            ProgramError::SharedProcessRequiresJobPolicy => zx::Status::INVALID_ARGS,
118            ProgramError::Parse(_) => zx::Status::INVALID_ARGS,
119            ProgramError::Policy(_) => zx::Status::ACCESS_DENIED,
120        }
121    }
122}
123
124/// Errors from exception handling.
125#[derive(Debug, Clone, Error)]
126pub enum ExceptionError {
127    #[error("failed to get thread koid: {_0}")]
128    GetThreadKoid(#[source] zx::Status),
129    #[error("failed to set exception state: {_0}")]
130    SetState(#[source] zx::Status),
131}
132
133#[derive(Debug, Clone, Error)]
134pub enum VdsoError {
135    #[error("Could not duplicate VMO handle for vDSO with name \"{name}\": {status}")]
136    CouldNotDuplicate {
137        name: zx::Name,
138        #[source]
139        status: zx::Status,
140    },
141    #[error("No vDSO VMO found with name \"{_0}\"")]
142    NotFound(zx::Name),
143    #[error("failed to get vDSO name: {_0}")]
144    GetName(#[source] zx::Status),
145}