Asylo
primitive_status.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2019 Asylo authors
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #ifndef ASYLO_PLATFORM_PRIMITIVES_PRIMITIVE_STATUS_H_
20 #define ASYLO_PLATFORM_PRIMITIVES_PRIMITIVE_STATUS_H_
21 
22 #include <algorithm>
23 #include <cstddef>
24 #include <cstdint>
25 #include <cstring>
26 #include <string>
27 #include <type_traits>
28 
29 #include "absl/status/status.h"
30 #include "asylo/util/error_codes.h" // IWYU pragma: export
31 
32 namespace asylo {
33 namespace primitives {
34 
35 // This file declares types shared between between trusted and untrusted code.
36 //
37 // Trusted and untrusted components may be built with different compilers and be
38 // linked against different implementations of the C++ runtime. In general,
39 // these versions are not binary compatible. For example:
40 //
41 // * Types with a virtual function table will be initialized differently
42 // depending on where they were initialized, and an object passed to trusted
43 // code from the untrusted application may try to invoke a untrusted code when
44 // a virtual method is called or visa-versa.
45 //
46 // * Types which do memory allocation in their destructor may attempt to free
47 // themselves from the wrong heap.
48 //
49 // * Types which depend on the implementation of standard types like std::string
50 // may have completely incompatible runtime representation.
51 //
52 // These requirements exist because enclave code is linked against our own
53 // custom C++ runtime. The are not related to SGX per se and hold even for the
54 // simulator and RPC implementations.
55 
56 // Ensure common width for implementation-defined types.
57 static_assert(sizeof(size_t) == 8, "Unexpected size for type size_t");
58 
59 /// This enum of error codes aliases `absl::StatusCode`. These aliases are
60 /// needed because these error codes may be used by low-level runtime components
61 /// which must compile without C++ runtime support. Abseil does not guarantee
62 /// that the file defining `absl::StatusCode` will be supported in such an
63 /// environment.
64 enum AbslStatusCode : int {
65  kOk = 0,
67  kUnknown = 2,
70  kNotFound = 5,
75  kAborted = 10,
78  kInternal = 13,
80  kDataLoss = 15,
82 };
83 
84 /// \class PrimitiveStatus primitive_status.h @primitive_status
85 /// Shared representation of a status code across the enclave boundary.
86 ///
87 /// PrimitiveStatus does not include an error space and always refers to a
88 /// google::GoogleError value.
90  public:
91  /// Maximum error string length in characters.
92  static constexpr size_t kMessageMax = 1024;
93 
94  /// Builds an OK status.
96 
97  /// Builds a status with an error code and an empty message.
98  ///
99  /// \param code An error code that is interpreted as a google::GoogleError
100  /// value.
101  explicit PrimitiveStatus(int code) : error_code_(code) { message_[0] = '\0'; }
102 
103  /// Builds a status with an error code and error message.
104  ///
105  /// \param code An error code that is interpreted as a google::GoogleError
106  /// value.
107  /// \param message A message string that is truncated if longer than
108  /// `kMessageMax - 1` characters. The length is computed with strlen.
109  PrimitiveStatus(int code, const char *message)
111 
112  /// Builds a status with an error code and a message of size `message_size`.
113  ///
114  /// \param code An error code that is interpreted as a google::GoogleError
115  /// value.
116  /// \param message A message string that is truncated if longer than
117  /// `kMessageMax - 1` characters.
118  /// \param message_size The size of the `message` to copy, which will not
119  /// exceed `kMessageMax - 1` characters.
120  PrimitiveStatus(int code, const char *message, size_t message_size)
121  : error_code_(code) {
122  message_size = std::min(message_size, kMessageMax - 1);
123  memcpy(message_, message, message_size);
124  message_[message_size] = '\0';
125  }
126 
127  /// Builds a status with an error code and a message in string format.
128  PrimitiveStatus(int code, const std::string &message)
130 
131  /// Copy constructor.
132  ///
133  /// \param other The status to copy. Strings are memcpy'd.
136 
138  error_code_ = other.error_code_;
139  size_t size = std::min(strlen(other.message_), kMessageMax - 1);
140  memcpy(message_, other.message_, size);
141  message_[size] = '\0';
142  return *this;
143  }
144 
145  /// PrimitiveStatus::OkStatus() is the canonical name for an OK status.
146  /// \returns An OK status object.
148 
149  /// Getter for this object's error code.
150  ///
151  /// \returns The integer error code for this object.
152  int error_code() const { return error_code_; }
153 
154  /// Getter for this object's error message.
155  ///
156  /// returns The string error message for this object.
157  const char *error_message() const { return message_; }
158 
159  /// Predicate for non-error status.
160  ///
161  /// \returns True if and only if this object is OK (indicates no error).
162  bool ok() const { return error_code_ == AbslStatusCode::kOk; }
163 
164  private:
165  // This method is not intended to be called, it is defined only to provide a
166  // scope where offsetof may be applied to private members and PrimitiveStatus
167  // is a complete type.
168  static void CheckLayout() {
169  static_assert(std::is_standard_layout<PrimitiveStatus>::value,
170  "PrimitiveStatus must satisfy std::is_standard_layout");
171  static_assert(offsetof(PrimitiveStatus, error_code_) == 0x0,
172  "Unexpected layout for field PrimitiveStatus::error_code_");
173  static_assert(offsetof(PrimitiveStatus, message_) == sizeof(uint32_t),
174  "Unexpected layout for field PrimitiveStatus::message_");
175  }
176 
177  int32_t error_code_; // An error::GoogleError condition code.
178  char message_[kMessageMax]; // An associated error string.
179 };
180 
181 } // namespace primitives
182 } // namespace asylo
183 
184 #endif // ASYLO_PLATFORM_PRIMITIVES_PRIMITIVE_STATUS_H_
static constexpr size_t kMessageMax
Maximum error string length in characters.
Definition: primitive_status.h:92
const char * error_message() const
Getter for this object&#39;s error message.
Definition: primitive_status.h:157
PrimitiveStatus(int code, const char *message, size_t message_size)
Builds a status with an error code and a message of size message_size.
Definition: primitive_status.h:120
Definition: primitive_status.h:75
Definition: primitive_status.h:70
Definition: primitive_status.h:79
Definition: primitive_status.h:69
Definition: primitive_status.h:74
Shared representation of a status code across the enclave boundary.
Definition: primitive_status.h:89
AbslStatusCode
This enum of error codes aliases absl::StatusCode.
Definition: primitive_status.h:64
Definition: primitive_status.h:67
PrimitiveStatus & operator=(const PrimitiveStatus &other)
Definition: primitive_status.h:137
int error_code() const
Getter for this object&#39;s error code.
Definition: primitive_status.h:152
ABSL_CONST_INIT const char kStatusMoveAssignmentMsg[]
Definition: primitive_status.h:81
PrimitiveStatus(int code, const std::string &message)
Builds a status with an error code and a message in string format.
Definition: primitive_status.h:128
static PrimitiveStatus OkStatus()
PrimitiveStatus::OkStatus() is the canonical name for an OK status.
Definition: primitive_status.h:147
Definition: primitive_status.h:65
Definition: primitive_status.h:72
Definition: primitive_status.h:73
bool ok() const
Predicate for non-error status.
Definition: primitive_status.h:162
Definition: primitive_status.h:76
Definition: primitive_status.h:78
PrimitiveStatus(int code)
Builds a status with an error code and an empty message.
Definition: primitive_status.h:101
Definition: primitive_status.h:80
PrimitiveStatus(const PrimitiveStatus &other)
Copy constructor.
Definition: primitive_status.h:134
Definition: primitive_status.h:71
PrimitiveStatus(int code, const char *message)
Builds a status with an error code and error message.
Definition: primitive_status.h:109
PrimitiveStatus()
Builds an OK status.
Definition: primitive_status.h:95
Definition: primitive_status.h:77
Definition: primitive_status.h:66
Definition: primitive_status.h:68
Definition: extent.h:29