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