You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
+
1218
1286
## Other parts of Zig
1219
1287
1220
1288
We already learned a lot about Zig's syntax, and also, some pretty technical
Copy file name to clipboardexpand all lines: docs/Chapters/01-zig-weird.html
+32-3
Original file line number
Diff line number
Diff line change
@@ -279,7 +279,8 @@ <h2 id="toc-title">Table of contents</h2>
279
279
<li><ahref="#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"><spanclass="header-section-number">1.8.2</span> A better look at the object type</a></li>
280
280
<li><ahref="#byte-vs-unicode-points" id="toc-byte-vs-unicode-points" class="nav-link" data-scroll-target="#byte-vs-unicode-points"><spanclass="header-section-number">1.8.3</span> Byte vs unicode points</a></li>
281
281
</ul></li>
282
-
<li><ahref="#other-parts-of-zig" id="toc-other-parts-of-zig" class="nav-link" data-scroll-target="#other-parts-of-zig"><spanclass="header-section-number">1.9</span> Other parts of Zig</a></li>
282
+
<li><ahref="#safety-in-zig" id="toc-safety-in-zig" class="nav-link" data-scroll-target="#safety-in-zig"><spanclass="header-section-number">1.9</span> Safety in Zig</a></li>
283
+
<li><ahref="#other-parts-of-zig" id="toc-other-parts-of-zig" class="nav-link" data-scroll-target="#other-parts-of-zig"><spanclass="header-section-number">1.10</span> Other parts of Zig</a></li>
<h2data-number="1.9" class="anchored" data-anchor-id="safety-in-zig"><spanclass="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 <ahref="https://www.youtube.com/watch?v=jIZpKpLCOiU&ab_channel=GOTOConferences">most recent GOTO conference talk</a><ahref="#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. 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 <spanclass="citation" data-cites="exploit1">(<ahref="../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<ahref="#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>
<h2data-number="1.10" class="anchored" data-anchor-id="other-parts-of-zig"><spanclass="header-section-number">1.10</span> Other parts of Zig</h2>
830
854
<p>We already learned a lot about Zig’s syntax, and also, some pretty technical details about it. Just as a quick recap:</p>
831
855
<ul>
832
856
<li>We talked about how functions are written in Zig at <ahref="#sec-root-file" class="quarto-xref"><span>Section 1.2.2</span></a> and <ahref="#sec-main-file" class="quarto-xref"><span>Section 1.2.3</span></a>.</li>
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><ahref="https://arxiv.org/abs/2406.08719">https://arxiv.org/abs/2406.08719</a>.
<liid="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.<ahref="#fnref19" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
Chen, Jenny, and Ruohao Guo. 2022. <span>“Stack and Heap Memory.”</span>
237
237
<em>Introduction to Data Structures and Algorithms with C++</em>. <ahref="https://courses.engr.illinois.edu/cs225/fa2022/resources/stack-heap/">https://courses.engr.illinois.edu/cs225/fa2022/resources/stack-heap/</a>.
0 commit comments