Skip to content

Commit

Permalink
Update mojo security documentation.
Browse files Browse the repository at this point in the history
One of the general security principles is that syntactically correct
messages are semantically valid. Write that explicitly an include an
example for bitfields.

Change-Id: If17ffe152702eb6441a922dae70bb65063c7592f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2822919
Reviewed-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
Reviewed-by: Robert Sesek <rsesek@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Commit-Queue: Erik Chen <erikchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#874759}
  • Loading branch information
erikchen authored and Chromium LUCI CQ committed Apr 21, 2021
1 parent a6b21e3 commit 14a4bad
Showing 1 changed file with 81 additions and 0 deletions.
81 changes: 81 additions & 0 deletions docs/security/mojo.md
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,87 @@ for (size_t i = 0; i < request->element_size(); ++i) {
```


### All possible message values are semantically valid

When possible, messages should be defined in such a way that all possible values
are semantically valid. As a corollary, avoid having the value of one field
dictate the validity of other fields.

**_Good_**

```c++
union CreateTokenResult {
// Implies success.
string token;

// Implies failure.
string error_message;
};

struct TokenManager {
CreateToken() => (CreateTokenResult result);
};
```
**_Bad_**
```c++
struct TokenManager {
// Requires caller to handle edge case where |success| is set to true, but
// |token| is null.
CreateToken() => (bool success, string? token, string? error_message);
// Requires caller to handle edge case where both |token| and |error_message|
// are set, or both are null.
CreateToken() => (string? token, string? error_message);
};
```

There are some known exceptions to this rule because mojo does not handle
optional primitives.

**_Allowed because mojo has no support for optional primitives_**
```c++
struct Foo {
int32 x;
bool has_x; // does the value of `x` have meaning?
int32 y;
bool has_y; // does the value of `y` have meaning?
};
```
Another common case where we tolerate imperfect message semantics is
with weakly typed integer [bitfields](#handling-bitfields).
### Handling bitfields
Mojom has no native support for bitfields. There are two common approaches: a
type-safe struct of bools which is a bit clunky (preferred) and an integer-based
approach (allowed but not preferred).
**_Type-safe bitfields_**
```c++
struct VehicleBits {
bool has_car;
bool has_bicycle;
bool has_boat;
};
struct Person {
VehicleBits bits;
};
```

**_Integer based approach_**
```c++
struct Person {
const uint64 kHasCar = 1;
const uint64 kHasBicycle = 2;
const uint64 kHasGoat= 4;

uint32 vehicle_bitfield;
};
```
## C++ Best Practices
Expand Down

0 comments on commit 14a4bad

Please sign in to comment.