Skip to content

Commit a1c64c0

Browse files
authored
Merge pull request #18 from pedropark99/safety
Add section that lists the safety features of Zig
2 parents b76d266 + d78286b commit a1c64c0

File tree

6 files changed

+132
-9
lines changed

6 files changed

+132
-9
lines changed

Chapters/01-zig-weird.qmd

+68
Original file line numberDiff line numberDiff line change
@@ -1215,6 +1215,74 @@ got codepoint E382AB
12151215

12161216

12171217

1218+
## Safety in Zig
1219+
1220+
A general trend in modern low-level programming languages is safety. As our modern world
1221+
become more interconnected with techology and computers,
1222+
the data produced by all of this technology becomes one of the most important
1223+
(and also, one of the most dangerous) assets that we have.
1224+
1225+
This is probably the main reason why modern low-level programming languages
1226+
have been giving great attention to safety, specially memory safety, because
1227+
memory corruption is still the main target for hackers to exploit.
1228+
The reality is that we don't have an easy solution for this problem.
1229+
For now, we only have techniques and strategies that mitigates these
1230+
problems.
1231+
1232+
As Richard Feldman explains on his [most recent GOTO conference talk](https://www.youtube.com/watch?v=jIZpKpLCOiU&ab_channel=GOTOConferences)[^gotop]
1233+
, we haven't figured it out yet a way to achieve **true safety in technology**.
1234+
In other words, we haven't found a way to build software that won't be exploited
1235+
with 100% certainty. We can greatly reduce the risks of our software being
1236+
exploited, by ensuring memory safety for example. But this is not enough
1237+
to achieve "true safety" territory.
1238+
1239+
Because even if you write your program in a "safe language", hackers can still
1240+
exploit failures in the operational system where your program is running (e.g. maybe the
1241+
system where your code is running have a "backdoor exploit" that can still
1242+
affect your code in unexpected ways), or also, they can exploit the features
1243+
from the architecture of your computer. A recently found exploit
1244+
that involves memory invalidation through a feature of "memory tags"
1245+
present in ARM chips is an example of that [@exploit1].
1246+
1247+
[^gotop]: <https://www.youtube.com/watch?v=jIZpKpLCOiU&ab_channel=GOTOConferences>
1248+
1249+
The question is: what Zig and other languages have been doing to mitigate this problem?
1250+
If we take Rust as an example, Rust is, for the most part[^rust-safe], a memory safe
1251+
language by enforcing specific rules to the developer. In other words, the key feature
1252+
of Rust, the *borrow checker*, forces you to follow a specific logic when you are writing
1253+
your Rust code, and the Rust compiler will always complain everytime you try to go out of this
1254+
pattern.
1255+
1256+
[^rust-safe]: Actually, a lot of existing Rust code is still memory unsafe, because they communicate with external libraries through FFI (*foreign function interface*), which disables the borrow-checker features through the `unsafe` keyword.
1257+
1258+
1259+
In contrast, the Zig language is not a memory safe language by default.
1260+
Instead of forcing the developer to follow a specific rule, the Zig language
1261+
achieves memory safety by offering tools that the developer can use for this purpose.
1262+
In other words, the `zig` compiler does not obligates you to use such tools.
1263+
But there is often no reason to not use these tools in your Zig code,
1264+
so you often achieve a similar level of memory safety of Rust in Zig
1265+
by simply using these tools.
1266+
1267+
The tools listed below are related to memory safety in Zig. That is, they help you to achieve
1268+
memory safety in your Zig code:
1269+
1270+
- `defer` allows you to keep free operations phisically close to allocations. This helps you to avoid memory leaks, "use after free", and also "double-free" problems. Furthermore, it also keeps free operations logically tied to the end of the current scope, which greatly reduces the mental overhead about object lifetime.
1271+
- `errdefer` helps you to garantee that your program frees the allocated memory, even if a runtime error occurs.
1272+
- pointers and object are non-nullable by default. This helps you to avoid memory problems that might arise from de-referencing null pointers.
1273+
- Zig offers some native types of allocators (called "testing allocators") that can detect memory leaks and double-frees. These types of allocators are widely used on unit tests, so they make your unit tests a weapon that you can use to detect memory problems in your code.
1274+
- arrays and slices in Zig have their lengths embedded in the object itself, which makes the `zig` compiler very effective on detecting "index out-of-range" type of errors, and avoiding buffer overflows.
1275+
1276+
1277+
Despite these features that Zig offers that are related to memory safety issues, the language
1278+
also have some rules that help you to achieve another type of safety, which is more related to
1279+
program logic safety. These rules are:
1280+
1281+
- pointers and objects are non-nullable by default. Which eliminates an edge case that might break the logic of your program.
1282+
- switch statements must exaust all possible options.
1283+
- the `zig` compiler forces you to handle every possible error.
1284+
1285+
12181286
## Other parts of Zig
12191287

12201288
We already learned a lot about Zig's syntax, and also, some pretty technical

_freeze/Chapters/01-zig-weird/execute-results/html.json

+2-2
Large diffs are not rendered by default.

docs/Chapters/01-zig-weird.html

+32-3
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,8 @@ <h2 id="toc-title">Table of contents</h2>
279279
<li><a href="#a-better-look-at-the-object-type" id="toc-a-better-look-at-the-object-type" class="nav-link" data-scroll-target="#a-better-look-at-the-object-type"><span class="header-section-number">1.8.2</span> A better look at the object type</a></li>
280280
<li><a href="#byte-vs-unicode-points" id="toc-byte-vs-unicode-points" class="nav-link" data-scroll-target="#byte-vs-unicode-points"><span class="header-section-number">1.8.3</span> Byte vs unicode points</a></li>
281281
</ul></li>
282-
<li><a href="#other-parts-of-zig" id="toc-other-parts-of-zig" class="nav-link" data-scroll-target="#other-parts-of-zig"><span class="header-section-number">1.9</span> Other parts of Zig</a></li>
282+
<li><a href="#safety-in-zig" id="toc-safety-in-zig" class="nav-link" data-scroll-target="#safety-in-zig"><span class="header-section-number">1.9</span> Safety in Zig</a></li>
283+
<li><a href="#other-parts-of-zig" id="toc-other-parts-of-zig" class="nav-link" data-scroll-target="#other-parts-of-zig"><span class="header-section-number">1.10</span> Other parts of Zig</a></li>
283284
</ul>
284285
</nav>
285286
</div>
@@ -825,8 +826,31 @@ <h3 data-number="1.8.3" class="anchored" data-anchor-id="byte-vs-unicode-points"
825826
got codepoint E382AB</code></pre>
826827
</section>
827828
</section>
828-
<section id="other-parts-of-zig" class="level2" data-number="1.9">
829-
<h2 data-number="1.9" class="anchored" data-anchor-id="other-parts-of-zig"><span class="header-section-number">1.9</span> Other parts of Zig</h2>
829+
<section id="safety-in-zig" class="level2" data-number="1.9">
830+
<h2 data-number="1.9" class="anchored" data-anchor-id="safety-in-zig"><span class="header-section-number">1.9</span> Safety in Zig</h2>
831+
<p>A general trend in modern low-level programming languages is safety. As our modern world become more interconnected with techology and computers, the data produced by all of this technology becomes one of the most important (and also, one of the most dangerous) assets that we have.</p>
832+
<p>This is probably the main reason why modern low-level programming languages have been giving great attention to safety, specially memory safety, because memory corruption is still the main target for hackers to exploit. The reality is that we don’t have an easy solution for this problem. For now, we only have techniques and strategies that mitigates these problems.</p>
833+
<p>As Richard Feldman explains on his <a href="https://www.youtube.com/watch?v=jIZpKpLCOiU&amp;ab_channel=GOTOConferences">most recent GOTO conference talk</a><a href="#fn18" class="footnote-ref" id="fnref18" role="doc-noteref"><sup>18</sup></a> , we haven’t figured it out yet a way to achieve <strong>true safety in technology</strong>. In other words, we haven’t found a way to build software that won’t be exploited with 100% certainty. We can greatly reduce the risks of our software being exploited, by ensuring memory safety for example. But this is not enough to achieve “true safety” territory.</p>
834+
<p>Because even if you write your program in a “safe language”, hackers can still exploit failures in the operational system where your program is running (e.g.&nbsp;maybe the system where your code is running have a “backdoor exploit” that can still affect your code in unexpected ways), or also, they can exploit the features from the architecture of your computer. A recently found exploit that involves memory invalidation through a feature of “memory tags” present in ARM chips is an example of that <span class="citation" data-cites="exploit1">(<a href="../references.html#ref-exploit1" role="doc-biblioref">Kim et al. 2024</a>)</span>.</p>
835+
<p>The question is: what Zig and other languages have been doing to mitigate this problem? If we take Rust as an example, Rust is, for the most part<a href="#fn19" class="footnote-ref" id="fnref19" role="doc-noteref"><sup>19</sup></a>, a memory safe language by enforcing specific rules to the developer. In other words, the key feature of Rust, the <em>borrow checker</em>, forces you to follow a specific logic when you are writing your Rust code, and the Rust compiler will always complain everytime you try to go out of this pattern.</p>
836+
<p>In contrast, the Zig language is not a memory safe language by default. Instead of forcing the developer to follow a specific rule, the Zig language achieves memory safety by offering tools that the developer can use for this purpose. In other words, the <code>zig</code> compiler does not obligates you to use such tools. But there is often no reason to not use these tools in your Zig code, so you often achieve a similar level of memory safety of Rust in Zig by simply using these tools.</p>
837+
<p>The tools listed below are related to memory safety in Zig. That is, they help you to achieve memory safety in your Zig code:</p>
838+
<ul>
839+
<li><code>defer</code> allows you to keep free operations phisically close to allocations. This helps you to avoid memory leaks, “use after free”, and also “double-free” problems. Furthermore, it also keeps free operations logically tied to the end of the current scope, which greatly reduces the mental overhead about object lifetime.</li>
840+
<li><code>errdefer</code> helps you to garantee that your program frees the allocated memory, even if a runtime error occurs.</li>
841+
<li>pointers and object are non-nullable by default. This helps you to avoid memory problems that might arise from de-referencing null pointers.</li>
842+
<li>Zig offers some native types of allocators (called “testing allocators”) that can detect memory leaks and double-frees. These types of allocators are widely used on unit tests, so they make your unit tests a weapon that you can use to detect memory problems in your code.</li>
843+
<li>arrays and slices in Zig have their lengths embedded in the object itself, which makes the <code>zig</code> compiler very effective on detecting “index out-of-range” type of errors, and avoiding buffer overflows.</li>
844+
</ul>
845+
<p>Despite these features that Zig offers that are related to memory safety issues, the language also have some rules that help you to achieve another type of safety, which is more related to program logic safety. These rules are:</p>
846+
<ul>
847+
<li>pointers and objects are non-nullable by default. Which eliminates an edge case that might break the logic of your program.</li>
848+
<li>switch statements must exaust all possible options.</li>
849+
<li>the <code>zig</code> compiler forces you to handle every possible error.</li>
850+
</ul>
851+
</section>
852+
<section id="other-parts-of-zig" class="level2" data-number="1.10">
853+
<h2 data-number="1.10" class="anchored" data-anchor-id="other-parts-of-zig"><span class="header-section-number">1.10</span> Other parts of Zig</h2>
830854
<p>We already learned a lot about Zig’s syntax, and also, some pretty technical details about it. Just as a quick recap:</p>
831855
<ul>
832856
<li>We talked about how functions are written in Zig at <a href="#sec-root-file" class="quarto-xref"><span>Section 1.2.2</span></a> and <a href="#sec-main-file" class="quarto-xref"><span>Section 1.2.3</span></a>.</li>
@@ -849,6 +873,9 @@ <h2 data-number="1.9" class="anchored" data-anchor-id="other-parts-of-zig"><span
849873

850874

851875
<div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="0" role="list" style="display: none">
876+
<div id="ref-exploit1" class="csl-entry" role="listitem">
877+
Kim, Juhee, Jinbum Park, Sihyeon Roh, Jaeyoung Chung, Youngjoo Lee, Taesoo Kim, and Byoungyoung Lee. 2024. <span>“TikTag: Breaking ARM’s Memory Tagging Extension with Speculative Execution.”</span> <a href="https://arxiv.org/abs/2406.08719">https://arxiv.org/abs/2406.08719</a>.
878+
</div>
852879
<div id="ref-zigguide" class="csl-entry" role="listitem">
853880
Sobeston. 2024. <span>“Zig Guide.”</span> <a href="https://zig.guide/">https://zig.guide/</a>.
854881
</div>
@@ -874,6 +901,8 @@ <h2 data-number="1.9" class="anchored" data-anchor-id="other-parts-of-zig"><span
874901
<li id="fn15"><p><a href="https://ziglang.org/documentation/master/#Primitive-Types" class="uri">https://ziglang.org/documentation/master/#Primitive-Types</a>.<a href="#fnref15" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
875902
<li id="fn16"><p><a href="https://www.gnu.org/software/libiconv/" class="uri">https://www.gnu.org/software/libiconv/</a><a href="#fnref16" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
876903
<li id="fn17"><p><a href="https://cplusplus.com/reference/cstdio/printf/" class="uri">https://cplusplus.com/reference/cstdio/printf/</a><a href="#fnref17" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
904+
<li id="fn18"><p><a href="https://www.youtube.com/watch?v=jIZpKpLCOiU&amp;ab_channel=GOTOConferences" class="uri">https://www.youtube.com/watch?v=jIZpKpLCOiU&amp;ab_channel=GOTOConferences</a><a href="#fnref18" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
905+
<li id="fn19"><p>Actually, a lot of existing Rust code is still memory unsafe, because they communicate with external libraries through FFI (<em>foreign function interface</em>), which disables the borrow-checker features through the <code>unsafe</code> keyword.<a href="#fnref19" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
877906
</ol>
878907
</section>
879908

docs/references.html

+5
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,11 @@ <h1 class="title">References</h1>
236236
Chen, Jenny, and Ruohao Guo. 2022. <span>“Stack and Heap Memory.”</span>
237237
<em>Introduction to Data Structures and Algorithms with C++</em>. <a href="https://courses.engr.illinois.edu/cs225/fa2022/resources/stack-heap/">https://courses.engr.illinois.edu/cs225/fa2022/resources/stack-heap/</a>.
238238
</div>
239+
<div id="ref-exploit1" class="csl-entry" role="listitem">
240+
Kim, Juhee, Jinbum Park, Sihyeon Roh, Jaeyoung Chung, Youngjoo Lee,
241+
Taesoo Kim, and Byoungyoung Lee. 2024. <span>“TikTag: Breaking ARM’s
242+
Memory Tagging Extension with Speculative Execution.”</span> <a href="https://arxiv.org/abs/2406.08719">https://arxiv.org/abs/2406.08719</a>.
243+
</div>
239244
<div id="ref-eric_http" class="csl-entry" role="listitem">
240245
Meehan, Eric. 2021. <span>“Creating a Web Server from Scratch in
241246
c.”</span> Youtube. <a href="https://www.youtube.com/watch?v=gk6NL1pZi1M&amp;ab_channel=EricOMeehan">https://www.youtube.com/watch?v=gk6NL1pZi1M&amp;ab_channel=EricOMeehan</a>.

0 commit comments

Comments
 (0)