Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 8 Sep 2024 09:53:57 +0100
From:      David Chisnall <theraven@freebsd.org>
To:        Paul Floyd <paulf2718@gmail.com>
Cc:        freebsd-hackers@freebsd.org
Subject:   CHERIoT RTOS C++ [Re: The Case for Rust (in any system)]
Message-ID:  <D42EC8C5-9100-4209-AB49-091FCE48F8B2@freebsd.org>
In-Reply-To: <5d707cd5-ee31-4cce-98b7-3826e891a2dd@gmail.com>
References:  <5d707cd5-ee31-4cce-98b7-3826e891a2dd@gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help

--Apple-Mail-A0EC2FF2-7F8A-4D21-A958-19E93388C397
Content-Type: text/plain;
	charset=utf-8
Content-Transfer-Encoding: quoted-printable

Changing the title so people who don=E2=80=99t care can easily ignore this t=
angent.

> On 7 Sep 2024, at 20:20, Paul Floyd <paulf2718@gmail.com> wrote:
>=20
> Out of curiosity, did that mean limiting the ABI use (no RTTI or exception=
s). Did it also allow using different compilers (say clang and GCC)?

We=E2=80=99re targeting tiny embedded systems. The total code size for the c=
ore RTOS (scheduler, memory allocator, switcher) is around 10 KiB, so except=
ions are totally infeasible. A stack unwinded would be as big as the total a=
mount of RAM on some of the SoCs we want to be able to support. We also don=E2=
=80=99t use RTTI for a similar reason. We do have a tiny C++ runtime for laz=
y static initialisation.

I wish the C++ standard would lose its allergy to subsetting, because the st=
andard not subsetting does not prevent it happening, it just means everyone d=
oes it differently. In terms of library support, we claim to be a freestandi=
ng implementation and also provide a bunch of things from hosted implementat=
ions. A lot of the normal standard library types are not well suited to envi=
ronments where memory allocation can fail and where exceptions don=E2=80=99t=
 work (the libc++ code calls abort in these cases, we want things that retur=
n std::optional for things that might fail).

We are co-designing the hardware and software. We have some FPGA prototyping=
 platforms (lowRISC has built a really nice one) and the company I cofounded=
 will ship commercial silicon next year. We have some extensions beyond CHER=
I that enable deterministic heap temporal safety as well. As soon as you fre=
e an object, all pointers to it become unusable (and then we have some addit=
ional hardware that makes it possible to safely reuse the memory).=20

So it=E2=80=99s not quite normal C++. We can inspect a pointer and tell what=
 its bounds are, what its permissions are, and whether it=E2=80=99s valid. W=
e can also transform it into a tamper-proof =E2=80=98sealed=E2=80=99 pointer=
 that can be unsealed only if you hold the relevant unsealing token. This ca=
n protect things like socket handles: the TCP/IP stack hands out a sealed po=
inter to the socket state and can check when you pass it back that it is the=
 correct type and can then unseal it, but you everything else that pointer i=
s a value that can be copied around but can=E2=80=99t be used. We can do som=
e fun things (it=E2=80=99s possible to represent all of the state of a std::=
vector with a single pointer, for example) and, in some places, we skip stat=
ic memory safety checks and instead write code that expects to fail and retu=
rn to the calling compartment if it encounters a memory-safety bug.

This set of primitives lets us build a rich compartmentalisation model where=
 communication between compartments looks like a function call and sharing m=
emory is accomplished by passing pointers (which may have restricted permiss=
ions, including shallow or deep immutability and no-capture guarantees). On t=
op of this, we have built auditing tooling that lets you see which compartme=
nts call which entry points in others, which compartments have access to whi=
ch MMIO regions, and so on.

Our ABI defines a bunch of things that are extensions to the Itanium ABI suc=
h as calling conventions for cross-compartment calls, shared libraries (whic=
h, for us, are stateless and don=E2=80=99t involve a security domain crossin=
g, whereas compartments do).

We don=E2=80=99t have support for more than one compiler at the moment becau=
se our extensions are implemented only in clang. There is nothing stopping a=
nyone adding the same support in other compilers though and I=E2=80=99d be h=
appy to help anyone who wanted to do gcc bring up.

More details (code, formal model of the ISA, programmers=E2=80=99 handbook, a=
nd so on here):

https://cheriot.org/

David


--Apple-Mail-A0EC2FF2-7F8A-4D21-A958-19E93388C397
Content-Type: text/html;
	charset=utf-8
Content-Transfer-Encoding: quoted-printable

<html><head><meta http-equiv=3D"content-type" content=3D"text/html; charset=3D=
utf-8"></head><body dir=3D"auto"><div dir=3D"ltr"></div><div dir=3D"ltr">Cha=
nging the title so people who don=E2=80=99t care can easily ignore this tang=
ent.</div><div dir=3D"ltr"><br><div dir=3D"ltr"></div><blockquote type=3D"ci=
te">On 7 Sep 2024, at 20:20, Paul Floyd &lt;paulf2718@gmail.com&gt; wrote:<b=
r><br></blockquote></div><blockquote type=3D"cite"><div dir=3D"ltr">Out of c=
uriosity, did that mean limiting the ABI use (no RTTI or exceptions). Did it=
 also allow using different compilers (say clang and GCC)?</div></blockquote=
><br><div>We=E2=80=99re targeting tiny embedded systems. The total code size=
 for the core RTOS (scheduler, memory allocator, switcher) is around 10 KiB,=
 so exceptions are totally infeasible. A stack unwinded would be as big as t=
he total amount of RAM on some of the SoCs we want to be able to support. We=
 also don=E2=80=99t use RTTI for a similar reason. We do have a tiny C++ run=
time for lazy static initialisation.</div><div><br></div><div>I wish the C++=
 standard would lose its allergy to subsetting, because the standard not sub=
setting does not prevent it happening, it just means everyone does it differ=
ently. In terms of library support, we claim to be a freestanding implementa=
tion and also provide a bunch of things from hosted implementations. A lot o=
f the normal standard library types are not well suited to environments wher=
e memory allocation can fail and where exceptions don=E2=80=99t work (the li=
bc++ code calls abort in these cases, we want things that return std::option=
al for things that might fail).</div><div><br></div><div>We are co-designing=
 the hardware and software. We have some FPGA prototyping platforms (lowRISC=
 has built a really nice one) and the company I cofounded will ship commerci=
al silicon next year. We have some extensions beyond CHERI that enable deter=
ministic heap temporal safety as well. As soon as you free an object, all po=
inters to it become unusable (and then we have some additional hardware that=
 makes it possible to safely reuse the memory).&nbsp;</div><div><br></div><d=
iv>So it=E2=80=99s not quite normal C++. We can inspect a pointer and tell w=
hat its bounds are, what its permissions are, and whether it=E2=80=99s valid=
. We can also transform it into a tamper-proof =E2=80=98sealed=E2=80=99 poin=
ter that can be unsealed only if you hold the relevant unsealing token. This=
 can protect things like socket handles: the TCP/IP stack hands out a sealed=
 pointer to the socket state and can check when you pass it back that it is t=
he correct type and can then unseal it, but you everything else that pointer=
 is a value that can be copied around but can=E2=80=99t be used. We can do s=
ome fun things (it=E2=80=99s possible to represent all of the state of a std=
::vector with a single pointer, for example) and, in some places, we skip st=
atic memory safety checks and instead write code that expects to fail and re=
turn to the calling compartment if it encounters a memory-safety bug.</div><=
div><br></div><div>This set of primitives lets us build a rich compartmental=
isation model where communication between compartments looks like a function=
 call and sharing memory is accomplished by passing pointers (which may have=
 restricted permissions, including shallow or deep immutability and no-captu=
re guarantees). On top of this, we have built auditing tooling that lets you=
 see which compartments call which entry points in others, which compartment=
s have access to which MMIO regions, and so on.</div><div><br></div><div>Our=
 ABI defines a bunch of things that are extensions to the Itanium ABI such a=
s calling conventions for cross-compartment calls, shared libraries (which, f=
or us, are stateless and don=E2=80=99t involve a security domain crossing, w=
hereas compartments do).</div><div><br></div><div>We don=E2=80=99t have supp=
ort for more than one compiler at the moment because our extensions are impl=
emented only in clang. There is nothing stopping anyone adding the same supp=
ort in other compilers though and I=E2=80=99d be happy to help anyone who wa=
nted to do gcc bring up.</div><div><br></div><div>More details (code, formal=
 model of the ISA, programmers=E2=80=99 handbook, and so on here):</div><div=
><br></div><div><a href=3D"https://cheriot.org/">https://cheriot.org/</a></d=
iv><div><br></div><div>David</div><div><br></div></body></html>=

--Apple-Mail-A0EC2FF2-7F8A-4D21-A958-19E93388C397--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?D42EC8C5-9100-4209-AB49-091FCE48F8B2>