{"id":17776,"date":"2026-02-28T20:09:41","date_gmt":"2026-02-28T20:09:41","guid":{"rendered":"https:\/\/cryptoted.net\/index.php\/2026\/02\/28\/secured-6-writing-robust-c-best-practices-for-finding-and-preventing-vulnerabilities\/"},"modified":"2026-02-28T20:09:41","modified_gmt":"2026-02-28T20:09:41","slug":"secured-6-writing-robust-c-best-practices-for-finding-and-preventing-vulnerabilities","status":"publish","type":"post","link":"https:\/\/cryptoted.net\/index.php\/2026\/02\/28\/secured-6-writing-robust-c-best-practices-for-finding-and-preventing-vulnerabilities\/","title":{"rendered":"Secured #6 &#8211; Writing Robust C &#8211; Best Practices for Finding and Preventing Vulnerabilities"},"content":{"rendered":"<p> <br \/>\n<\/p>\n<div id=\"\">\n<p class=\"chakra-text css-gi02ar\">For <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/eips.ethereum.org\/EIPS\/eip-4844\">EIP-4844<\/a>, Ethereum clients need the ability to compute and verify KZG commitments. Rather than each client rolling their own crypto, researchers and developers came together to write <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/github.com\/ethereum\/c-kzg-4844\">c-kzg-4844<\/a>, a relatively small C library with bindings for higher-level languages. The idea was to create a robust and efficient cryptographic library that all clients could use. The Protocol Security Research team at the Ethereum Foundation had the opportunity to review and improve this library. This blog post will discuss some things we do to make C projects more secure.<\/p>\n<p><!-- --><\/p>\n<h2 class=\"chakra-heading group css-1kpzc4q\" id=\"fuzz\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"fuzz permalink\" href=\"#fuzz\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Fuzz<\/h2>\n<p class=\"chakra-text css-gi02ar\">Fuzzing is a dynamic code testing technique that involves providing random inputs to discover bugs in a program. <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/www.llvm.org\/docs\/LibFuzzer.html\">LibFuzzer<\/a> and <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/github.com\/AFLplusplus\/AFLplusplus\">afl++<\/a> are two popular fuzzing frameworks for C projects. They are both in-process, coverage-guided, evolutionary fuzzing engines. For c-kzg-4844, <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/github.com\/ethereum\/c-kzg-4844\/tree\/main\/fuzz\">we used<\/a> LibFuzzer since we were already well-integrated with LLVM project&#8217;s other offerings.<\/p>\n<p class=\"chakra-text css-gi02ar\">Here&#8217;s the fuzzer for <span class=\"chakra-text css-ons8vw\">verify_kzg_proof<\/span>, one of c-kzg-4844&#8217;s functions:<\/p>\n<div class=\"chakra-stack css-1jx0in4\">\n<pre><pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-c=\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>#include \"..\/base_fuzz.h\"\n<\/span>\n<!-- -->static const size_t COMMITMENT_OFFSET = 0;\n<!-- -->static const size_t Z_OFFSET = COMMITMENT_OFFSET + BYTES_PER_COMMITMENT;\n<!-- -->static const size_t Y_OFFSET = Z_OFFSET + BYTES_PER_FIELD_ELEMENT;\n<!-- -->static const size_t PROOF_OFFSET = Y_OFFSET + BYTES_PER_FIELD_ELEMENT;\n<!-- -->static const size_t INPUT_SIZE = PROOF_OFFSET + BYTES_PER_PROOF;\n<!-- -->\n<!-- -->int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {\n<!-- -->    initialize();\n<!-- -->    if (size == INPUT_SIZE) {\n<!-- -->        bool ok;\n<!-- -->        verify_kzg_proof(\n<!-- -->            &amp;ok,\n<!-- -->            (const Bytes48 *)(data + COMMITMENT_OFFSET),\n<!-- -->            (const Bytes32 *)(data + Z_OFFSET),\n<!-- -->            (const Bytes32 *)(data + Y_OFFSET),\n<!-- -->            (const Bytes48 *)(data + PROOF_OFFSET),\n<!-- -->            &amp;s\n<!-- -->        );\n<!-- -->    }\n<!-- -->    return 0;\n<!-- -->}\n<\/code><\/pre>\n<\/div>\n<p class=\"chakra-text css-gi02ar\">When executed, this is what the output looks like. If there were a problem, it would write the input to disk and stop executing. Ideally, you should be able to reproduce the problem.<\/p>\n<p class=\"chakra-text css-gi02ar\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/storage.googleapis.com\/ethereum-hackmd\/upload_6abe9afa0e4eaa3f085f98b0386ab980.png\" class=\"chakra-image css-hw6q2r\"\/><\/p>\n<p class=\"chakra-text css-gi02ar\">There&#8217;s also differential fuzzing, which is a technique which fuzzes two or more implementations of the same interface and compares the outputs. For a given input, if the output is different, and you expected them to be the same, you know something is wrong. This technique is very popular in Ethereum because we like to have several implementations of the same thing. This diversification provides an extra level of safety, knowing that if one implementation were flawed the others may not have the same issue.<\/p>\n<p class=\"chakra-text css-gi02ar\">For KZG libraries, we developed <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/github.com\/jtraglia\/kzg-fuzz\">kzg-fuzz<\/a> which differentially fuzzes c-kzg-4844 (through its Golang bindings) and <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/github.com\/crate-crypto\/go-kzg-4844\">go-kzg-4844<\/a>. So far, there haven&#8217;t been any differences.<\/p>\n<h2 class=\"chakra-heading group css-1kpzc4q\" id=\"coverage\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"coverage permalink\" href=\"#coverage\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Coverage<\/h2>\n<p class=\"chakra-text css-gi02ar\">Next, we used <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/www.llvm.org\/docs\/CommandGuide\/llvm-profdata.html\">llvm-profdata<\/a> and <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/www.llvm.org\/docs\/CommandGuide\/llvm-cov.html\">llvm-cov<\/a> to generate a coverage report from running the tests. This is a great way to verify code is executed (&#8220;covered&#8221;) and tested. See the <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/github.com\/ethereum\/c-kzg-4844\/blob\/f3fffecd1ce7e8b6620cd5bac50c660efc20e48c\/src\/Makefile#L76-L91\"><span class=\"chakra-text css-ons8vw\">coverage<\/span><\/a> target in c-kzg-4844&#8217;s Makefile for an example of how to generate this report.<\/p>\n<p class=\"chakra-text css-gi02ar\">When this target is run (<em class=\"chakra-text css-0\">i.e.<\/em>, <span class=\"chakra-text css-ons8vw\">make coverage<\/span>) it produces a table that serves as a high-level overview of how much of each function is executed. The exported functions are at the top and the non-exported (static) functions are on the bottom.<\/p>\n<p class=\"chakra-text css-gi02ar\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/storage.googleapis.com\/ethereum-hackmd\/upload_cc6a7e22dce7e1f4e3ca1942d9271e2a.png\" class=\"chakra-image css-hw6q2r\"\/><\/p>\n<p class=\"chakra-text css-gi02ar\">There is a lot of green in the table above, but there is some yellow and red too. To determine what is and isn&#8217;t being executed, refer to the HTML file (<span class=\"chakra-text css-ons8vw\">coverage.html<\/span>) that was generated. This webpage shows the entire source file and highlights non-executed code in red. In this project&#8217;s case, most of the non-executed code deals with hard-to-test error cases such as memory allocation failures. For example, here&#8217;s some non-executed code:<\/p>\n<p class=\"chakra-text css-gi02ar\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/storage.googleapis.com\/ethereum-hackmd\/upload_492f85debe5377bd42bcf2411df12021.png\" class=\"chakra-image css-hw6q2r\"\/><\/p>\n<p class=\"chakra-text css-gi02ar\">At the beginning of this function, it checks that the trusted setup is big enough to perform a pairing check. There isn&#8217;t a test case which provides an invalid trusted setup, so this doesn&#8217;t get executed. Also, because we only test with the correct trusted setup, the result of <span class=\"chakra-text css-ons8vw\">is_monomial_form<\/span> is always the same and doesn&#8217;t return the error value.<\/p>\n<h2 class=\"chakra-heading group css-1kpzc4q\" id=\"profile\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"profile permalink\" href=\"#profile\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Profile<\/h2>\n<p class=\"chakra-text css-gi02ar\">We don&#8217;t recommend this for all projects, but since c-kzg-4844 is a performance critical library we think it&#8217;s important to profile its exported functions and measure how long they take to execute. This can help identify inefficiencies which could potentially DoS nodes. For this, we used <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/github.com\/gperftools\/gperftools\">gperftools<\/a> (Google Performance Tools) instead of <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/llvm.org\/docs\/XRay.html\">llvm-xray<\/a> because we found it to be more feature-rich and easier to use.<\/p>\n<p class=\"chakra-text css-gi02ar\">The following is a simple example which profiles <span class=\"chakra-text css-ons8vw\">my_function<\/span>. Profiling works by checking which instruction is being executed every so often. If a function is fast enough, it may not be noticed by the profiler. To reduce the chance of this, you may need to call your function multiple times. In this example, we call <span class=\"chakra-text css-ons8vw\">my_function<\/span> 1000 times.<\/p>\n<div class=\"chakra-stack css-1jx0in4\">\n<pre><pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-c=\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>#include <gperftools>\n<\/gperftools><\/span>\n<!-- -->int task_a(int n) {\n<!-- -->    if (n     return task_a(n - 1) * n;\n<!-- -->}\n<!-- -->\n<!-- -->int task_b(int n) {\n<!-- -->    if (n     return task_b(n - 2) + n;\n<!-- -->}\n<!-- -->\n<!-- -->void my_function(void) {\n<!-- -->    for (int i = 0; i         if (i % 2 == 0) {\n<!-- -->            task_a(i);\n<!-- -->        } else {\n<!-- -->            task_b(i);\n<!-- -->        }\n<!-- -->    }\n<!-- -->}\n<!-- -->\n<!-- -->int main(void) {\n<!-- -->    ProfilerStart(\"example.prof\");\n<!-- -->    for (int i = 0; i         my_function();\n<!-- -->    }\n<!-- -->    ProfilerStop();\n<!-- -->    return 0;\n<!-- -->}\n<\/code><\/pre>\n<\/div>\n<p class=\"chakra-text css-gi02ar\">Use <span class=\"chakra-text css-ons8vw\">ProfilerStart(&#8220;<filename>&#8220;)<\/filename><\/span> and <span class=\"chakra-text css-ons8vw\">ProfilerStop()<\/span> to mark which parts of your program to profile. When re-compiled and executed, it will write a file to disk with profiling data. You can then use <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/github.com\/google\/pprof\">pprof<\/a> to visualize this data.<\/p>\n<p class=\"chakra-text css-gi02ar\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/storage.googleapis.com\/ethereum-hackmd\/upload_928840ff7f217e9bef867c28c52ce5b5.png\" class=\"chakra-image css-hw6q2r\"\/><\/p>\n<p class=\"chakra-text css-gi02ar\">Here is the graph generated from the command above:<\/p>\n<p class=\"chakra-text css-gi02ar\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/storage.googleapis.com\/ethereum-hackmd\/upload_65ba3120f91592876c51b8ac92525914.png\" class=\"chakra-image css-hw6q2r\"\/><\/p>\n<p class=\"chakra-text css-gi02ar\">Here&#8217;s a bigger example from one of c-kzg-4844&#8217;s functions. The following image is the profiling graph for <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/github.com\/ethereum\/c-kzg-4844\/blob\/f3fffecd1ce7e8b6620cd5bac50c660efc20e48c\/src\/c_kzg_4844.c#L1106-L1145\"><span class=\"chakra-text css-ons8vw\">compute_blob_kzg_proof<\/span><\/a>. As you can see, 80% of this function&#8217;s time is spent performing Montgomery multiplications. This is expected.<\/p>\n<p class=\"chakra-text css-gi02ar\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/storage.googleapis.com\/ethereum-hackmd\/upload_e6bad1c1c6cb6a5a71aa98a108abb99d.png\" class=\"chakra-image css-hw6q2r\"\/><\/p>\n<h2 class=\"chakra-heading group css-1kpzc4q\" id=\"reverse\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"reverse permalink\" href=\"#reverse\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Reverse<\/h2>\n<p class=\"chakra-text css-gi02ar\">Next, view your binary in a software reverse engineering (SRE) tool such as <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/ghidra-sre.org\">Ghidra<\/a> or <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/hex-rays.com\/ida-free\/\">IDA<\/a>. These tools can help you understand how high-level constructs are translated into low-level machine code. We think it helps to review your code this way; like how reading a paper in a different font will force your brain to interpret sentences differently. It&#8217;s also useful to see what type of optimizations your compiler makes. It&#8217;s rare, but sometimes the compiler will optimize out something which it deemed unnecessary. Keep an eye out for this, something like this actually happened in c-kzg-4844, <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/github.com\/ethereum\/c-kzg-4844\/pull\/133\">some of the tests were being optimized out<\/a>.<\/p>\n<p class=\"chakra-text css-gi02ar\">When you view a decompiled function, it will not have variable names, complex types, or comments. When compiled, this information isn&#8217;t included in the binary. It will be up to you to reverse engineer this. You&#8217;ll often see functions are inlined into a single function, multiple variables declared in code are optimized into a single buffer, and the order of checks are different. These are just compiler optimizations and are generally fine. It may help to build your binary with DWARF debugging information; most SREs can analyze this section to provide better results.<\/p>\n<p class=\"chakra-text css-gi02ar\">For example, this is what <span class=\"chakra-text css-ons8vw\">blob_to_kzg_commitment<\/span> initially looks like in Ghidra:<\/p>\n<p class=\"chakra-text css-gi02ar\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/storage.googleapis.com\/ethereum-hackmd\/upload_add5963e243fa2449ff2fa088db8e2b8.png\" class=\"chakra-image css-hw6q2r\"\/><\/p>\n<p class=\"chakra-text css-gi02ar\">With a little work, you can rename variables and add comments to make it easier to read. Here&#8217;s what it could look like after a few minutes:<\/p>\n<p class=\"chakra-text css-gi02ar\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/storage.googleapis.com\/ethereum-hackmd\/upload_187e2686e3e43aec289d5c3c2a8914e3.png\" class=\"chakra-image css-hw6q2r\"\/><\/p>\n<h2 class=\"chakra-heading group css-1kpzc4q\" id=\"static-analysis\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"static analysis permalink\" href=\"#static-analysis\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Static Analysis<\/h2>\n<p class=\"chakra-text css-gi02ar\"><a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/clang.llvm.org\">Clang<\/a> comes built-in with the <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/clang-analyzer.llvm.org\">Clang Static Analyzer<\/a>, which is an excellent static analysis tool that can identify many problems that the compiler will miss. As the name &#8220;static&#8221; suggests, it examines code without executing it. This is slower than the compiler, but a lot faster than &#8220;dynamic&#8221; analysis tools which execute code.<\/p>\n<p class=\"chakra-text css-gi02ar\">Here&#8217;s a simple example which forgets to free <span class=\"chakra-text css-ons8vw\">arr<\/span> (and has another problem but we will talk more about that later). The compiler will not identify this, even with all warnings enabled because technically this is completely valid code.<\/p>\n<div class=\"chakra-stack css-1jx0in4\">\n<pre><pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-c=\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>#include <stdlib.h>\n<\/stdlib.h><\/span>\n<!-- -->int main(void) {\n<!-- -->    int* arr = malloc(5 * sizeof(int));\n<!-- -->    arr[5] = 42;\n<!-- -->    return 0;\n<!-- -->}\n<\/code><\/pre>\n<\/div>\n<p class=\"chakra-text css-gi02ar\">The <span class=\"chakra-text css-ons8vw\">unix.Malloc<\/span> checker will identify that <span class=\"chakra-text css-ons8vw\">arr<\/span> wasn&#8217;t freed. The line in the warning message is a bit misleading, but it makes sense if you think about it; the analyzer reached the return statement and noticed that the memory hadn&#8217;t been freed.<\/p>\n<p class=\"chakra-text css-gi02ar\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/storage.googleapis.com\/ethereum-hackmd\/upload_a881c53b712cbfcdc95251ac9e26e9c7.png\" class=\"chakra-image css-hw6q2r\"\/><\/p>\n<p class=\"chakra-text css-gi02ar\">Not all of the findings are that simple though. Here&#8217;s a finding that Clang Static Analyzer found in c-kzg-4844 when initially introduced to the project:<\/p>\n<p class=\"chakra-text css-gi02ar\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/storage.googleapis.com\/ethereum-hackmd\/upload_8cb730fd65c5008b19e66b0e0567267d.png\" class=\"chakra-image css-hw6q2r\"\/><\/p>\n<p class=\"chakra-text css-gi02ar\">Given an unexpected input, it was possible to shift this value by 32 bits which is undefined behavior. The solution was to restrict the input with <span class=\"chakra-text css-ons8vw\">CHECK(log2_pow2(n) != 0)<\/span> so that this was impossible. Good job, Clang Static Analyzer!<\/p>\n<h2 class=\"chakra-heading group css-1kpzc4q\" id=\"sanitize\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"sanitize permalink\" href=\"#sanitize\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Sanitize<\/h2>\n<p class=\"chakra-text css-gi02ar\">Santizers are dynamic analysis tools which instrument (add instructions) to programs which can point out issues during execution. These are particularly useful at finding common mistakes associated with memory handling. Clang comes built-in with several sanitizers; here are the four we find most useful and easy to use.<\/p>\n<h3 class=\"chakra-heading group css-xuzltg\" id=\"address\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"address permalink\" href=\"#address\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Address<\/h3>\n<p class=\"chakra-text css-gi02ar\"><a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/clang.llvm.org\/docs\/AddressSanitizer.html\">AddressSanitizer<\/a> (ASan) is a fast memory error detector which can identify out-of-bounds accesses, use-after-free, use-after-return, use-after-scope, double-free, and memory leaks.<\/p>\n<p class=\"chakra-text css-gi02ar\">Here is the same example from earlier. It forgets to free <span class=\"chakra-text css-ons8vw\">arr<\/span> and it will set  the 6th element in a 5 element array. This is a simple example of a heap-buffer-overflow:<\/p>\n<div class=\"chakra-stack css-1jx0in4\">\n<pre><pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-c=\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>#include <stdlib.h>\n<\/stdlib.h><\/span>\n<!-- -->int main(void) {\n<!-- -->    int* arr = malloc(5 * sizeof(int));\n<!-- -->    arr[5] = 42;\n<!-- -->    return 0;\n<!-- -->}\n<\/code><\/pre>\n<\/div>\n<p class=\"chakra-text css-gi02ar\">When compiled with <span class=\"chakra-text css-ons8vw\">-fsanitize=address<\/span> and executed, it will output the following error message. This points you in a good direction (a 4-byte write in <span class=\"chakra-text css-ons8vw\">main<\/span>). This binary could be viewed in a disassembler to figure out exactly which instruction (at <span class=\"chakra-text css-ons8vw\">main+0x84<\/span>) is causing the problem.<\/p>\n<p class=\"chakra-text css-gi02ar\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/storage.googleapis.com\/ethereum-hackmd\/upload_f93e2b996431bb0fa2c97fd074047a8a.png\" class=\"chakra-image css-hw6q2r\"\/><\/p>\n<p class=\"chakra-text css-gi02ar\">Similarly, here&#8217;s an example where it finds a heap-use-after-free:<\/p>\n<div class=\"chakra-stack css-1jx0in4\">\n<pre><pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-c=\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>#include <stdlib.h>\n<\/stdlib.h><\/span>\n<!-- -->int main(void) {\n<!-- -->    int *arr = malloc(5 * sizeof(int));\n<!-- -->    free(arr);\n<!-- -->    return arr[2];\n<!-- -->}\n<\/code><\/pre>\n<\/div>\n<p class=\"chakra-text css-gi02ar\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/storage.googleapis.com\/ethereum-hackmd\/upload_7acf4da0ecfa28026043293dae99e9ec.png\" class=\"chakra-image css-hw6q2r\"\/><\/p>\n<p class=\"chakra-text css-gi02ar\">It tells you that there&#8217;s a 4-byte read of freed memory at <span class=\"chakra-text css-ons8vw\">main+0x8c<\/span>.<\/p>\n<h3 class=\"chakra-heading group css-xuzltg\" id=\"memory\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"memory permalink\" href=\"#memory\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Memory<\/h3>\n<p class=\"chakra-text css-gi02ar\"><a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/clang.llvm.org\/docs\/MemorySanitizer.html\">MemorySanitizer<\/a> (MSan) is a detector of uninitialized reads. Here&#8217;s a simple example which reads (and returns) an uninitialized value:<\/p>\n<div class=\"chakra-stack css-1jx0in4\">\n<pre><pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-c=\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>int main(void) {\n<\/span>    int data[2];\n<!-- -->    return data[0];\n<!-- -->}\n<\/code><\/pre>\n<\/div>\n<p class=\"chakra-text css-gi02ar\">When compiled with <span class=\"chakra-text css-ons8vw\">-fsanitize=memory<\/span> and executed, it will output the following error message:<\/p>\n<p class=\"chakra-text css-gi02ar\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/storage.googleapis.com\/ethereum-hackmd\/upload_08f2007fb193bbf1051d3a46bbbdb299.png\" class=\"chakra-image css-hw6q2r\"\/><\/p>\n<h3 class=\"chakra-heading group css-xuzltg\" id=\"undefined-behavior\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"undefined behavior permalink\" href=\"#undefined-behavior\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Undefined Behavior<\/h3>\n<p class=\"chakra-text css-gi02ar\"><a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/clang.llvm.org\/docs\/UndefinedBehaviorSanitizer.html\">UndefinedBehaviorSanitizer<\/a> (UBSan) detects undefined behavior, which refers to the situation where a program&#8217;s behavior is unpredictable and not specified by the langauge standard. Some common examples of this are accessing out-of-bounds memory, dereferencing an invalid pointer, reading uninitialized variables, and overflow of a signed integer. For example, here we increment <span class=\"chakra-text css-ons8vw\">INT_MAX<\/span> which is undefined behavior.<\/p>\n<div class=\"chakra-stack css-1jx0in4\">\n<pre><pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-c=\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>#include <limits.h>\n<\/limits.h><\/span>\n<!-- -->int main(void) {\n<!-- -->    int a = INT_MAX;\n<!-- -->    return a + 1;\n<!-- -->}\n<\/code><\/pre>\n<\/div>\n<p class=\"chakra-text css-gi02ar\">When compiled with <span class=\"chakra-text css-ons8vw\">-fsanitize=undefined<\/span> and executed, it will output the following error message which tells us exactly where the problem is and what the conditions are:<\/p>\n<p class=\"chakra-text css-gi02ar\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/storage.googleapis.com\/ethereum-hackmd\/upload_943dbefe49f7da39c69bec29e3c4261a.png\" class=\"chakra-image css-hw6q2r\"\/><\/p>\n<h3 class=\"chakra-heading group css-xuzltg\" id=\"thread\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"thread permalink\" href=\"#thread\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Thread<\/h3>\n<p class=\"chakra-text css-gi02ar\"><a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/clang.llvm.org\/docs\/ThreadSanitizer.html\">ThreadSanitizer<\/a> (TSan) detects data races, which can occur in multi-threaded programs when two or more threads access a shared memory location at the same time. This situation introduces unpredictability and can lead to undefined behavior. Here&#8217;s an example in which two threads increment a global <span class=\"chakra-text css-ons8vw\">counter<\/span> variable. There aren&#8217;t any locks or semaphores, so it&#8217;s entirely possible that these two threads will increment the variable at the same time.<\/p>\n<div class=\"chakra-stack css-1jx0in4\">\n<pre><pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-c=\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>#include <pthread.h>\n<\/pthread.h><\/span>\n<!-- -->int counter = 0;\n<!-- -->\n<!-- -->void *increment(void *arg) {\n<!-- -->    (void)arg;\n<!-- -->    for (int i = 0; i         counter++;\n<!-- -->    return NULL;\n<!-- -->}\n<!-- -->\n<!-- -->int main(void) {\n<!-- -->    pthread_t thread1, thread2;\n<!-- -->    pthread_create(&amp;thread1, NULL, increment, NULL);\n<!-- -->    pthread_create(&amp;thread2, NULL, increment, NULL);\n<!-- -->    pthread_join(thread1, NULL);\n<!-- -->    pthread_join(thread2, NULL);\n<!-- -->    return 0;\n<!-- -->}\n<\/code><\/pre>\n<\/div>\n<p class=\"chakra-text css-gi02ar\">When compiled with <span class=\"chakra-text css-ons8vw\">-fsanitize=thread<\/span> and executed, it will output the following error message:<\/p>\n<p class=\"chakra-text css-gi02ar\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/storage.googleapis.com\/ethereum-hackmd\/upload_82d46b5c5a4b180cbcdd2e7c12637cae.png\" class=\"chakra-image css-hw6q2r\"\/><\/p>\n<p class=\"chakra-text css-gi02ar\">This error message tells us that there&#8217;s a data race. In two threads, the <span class=\"chakra-text css-ons8vw\">increment<\/span> function is writing to the same 4 bytes at the same time. It even tells us that the memory is <span class=\"chakra-text css-ons8vw\">counter<\/span>.<\/p>\n<h2 class=\"chakra-heading group css-1kpzc4q\" id=\"valgrind\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"valgrind permalink\" href=\"#valgrind\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Valgrind<\/h2>\n<p class=\"chakra-text css-gi02ar\"><a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/valgrind.org\">Valgrind<\/a> is a powerful instrumentation framework for building dynamic analysis tools, but its best known for identifying memory errors and leaks with its built-in Memcheck tool.<\/p>\n<p class=\"chakra-text css-gi02ar\">The following image shows the output from running c-kzg-4844&#8217;s tests with Valgrind. In the red box is a valid finding for a &#8220;conditional jump or move [that] depends on uninitialized value(s).&#8221;<\/p>\n<p class=\"chakra-text css-gi02ar\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/storage.googleapis.com\/ethereum-hackmd\/upload_39f00e156f5f622804660bb2622b5cb4.png\" class=\"chakra-image css-hw6q2r\"\/><\/p>\n<p class=\"chakra-text css-gi02ar\">This <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/github.com\/ethereum\/c-kzg-4844\/pull\/375\">identified an edge case<\/a> in <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/github.com\/ethereum\/c-kzg-4844\/blob\/b2e41491ad1859f1792964a2432a419b64dc6fb2\/src\/c_kzg_4844.c#L1557-L1570\"><span class=\"chakra-text css-ons8vw\">expand_root_of_unity<\/span><\/a>. If the wrong root of unity or width were provided, it was possible that the loop will break before <span class=\"chakra-text css-ons8vw\">out[width]<\/span> was initialized. In this situation, the final check would depend on an uninitialized value.<\/p>\n<div class=\"chakra-stack css-1jx0in4\">\n<pre><pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-c=1557\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>static C_KZG_RET expand_root_of_unity(\n<\/span>    fr_t *out, const fr_t *root, uint64_t width\n<!-- -->) {\n<!-- -->    out[0] = FR_ONE;\n<!-- -->    out[1] = *root;\n<!-- -->\n<!-- -->    for (uint64_t i = 2; !fr_is_one(&amp;out[i - 1]); i++) {\n<!-- -->        CHECK(i         blst_fr_mul(&amp;out[i], &amp;out[i - 1], root);\n<!-- -->    }\n<!-- -->    CHECK(fr_is_one(&amp;out[width]));\n<!-- -->\n<!-- -->    return C_KZG_OK;\n<!-- -->}\n<\/code><\/pre>\n<\/div>\n<h2 class=\"chakra-heading group css-1kpzc4q\" id=\"security-review\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"security review permalink\" href=\"#security-review\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Security Review<\/h2>\n<p class=\"chakra-text css-gi02ar\">After development stabilizes, it&#8217;s been thoroughly tested, and your team has manually reviewed the codebase themselves multiple times, it&#8217;s time to get a security review by a reputable security group. This won&#8217;t be a stamp of approval, but it shows that your project is at least somewhat secure. Keep in mind there is no such thing as perfect security. There will always be the risk of vulnerabilities.<\/p>\n<p class=\"chakra-text css-gi02ar\">For c-kzg-4844 and go-kzg-4844, the Ethereum Foundation contracted <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/sigmaprime.io\/\">Sigma Prime<\/a> to conduct a security review. They produced <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/github.com\/ethereum\/c-kzg-4844\/blob\/main\/doc\/audit\/Sigma_Prime_Ethereum_Foundation_KZG_Implementations_Security_Assessment.pdf\">this report<\/a> with 8 findings. It contains one critical vulnerability in go-kzg-4844 that was a really good find. The BLS12-381 library that go-kzg-4844 uses, <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/github.com\/Consensys\/gnark-crypto\/\"><span class=\"chakra-text css-ons8vw\">gnark-crypto<\/span><\/a>, had a bug which allowed invalid G1 and G2 points to be sucessfully decoded. Had this not been fixed, this could have resulted in a consensus bug (a disagreement between implementations) in Ethereum.<\/p>\n<h2 class=\"chakra-heading group css-1kpzc4q\" id=\"bug-bounty\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"bug bounty permalink\" href=\"#bug-bounty\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Bug Bounty<\/h2>\n<p class=\"chakra-text css-gi02ar\">If a vulnerability in your project could be exploited for gains, like it is for Ethereum, consider setting up a bug bounty program. This allows security researchers, or anyone really, to submit vulnerability reports in exchange for money. Generally, this is specifically for findings which can prove that an exploit is possible. If the bug bounty payouts are reasonable, bug finders will notify you of the bug rather than exploiting it or selling it to another party. We recommend starting your bug bounty program after the findings from the first security review are resolved; ideally, the security review would cost less than the bug bounty payouts.<\/p>\n<h2 class=\"chakra-heading group css-1kpzc4q\" id=\"conclusion\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"conclusion permalink\" href=\"#conclusion\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Conclusion<\/h2>\n<p class=\"chakra-text css-gi02ar\">The development of robust C projects, especially in the critical domain of blockchain and cryptocurrencies, requires a multi-faceted approach. Given the inherent vulnerabilities associated with the C language, a combination of best practices and tools is essential for producing resilient software. We hope our experiences and findings from our work with c-kzg-4844 provide valuable insights and best practices for others embarking on similar projects.<\/p>\n<\/div>\n<p><br \/>\n<br \/><a href=\"https:\/\/blog.ethereum.org\/en\/2023\/11\/02\/writing-robust-c\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>For EIP-4844, Ethereum clients need the ability to compute and verify KZG commitments. Rather than each client rolling their own crypto, researchers and developers came together to write c-kzg-4844, a relatively small C library with bindings for higher-level languages. The idea was to create a robust and efficient cryptographic library that all clients could use. [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"tdm_status":"","tdm_grid_status":"","footnotes":""},"categories":[24],"tags":[],"kronos_expire_date":[],"class_list":["post-17776","post","type-post","status-publish","format-standard","hentry","category-ethereum"],"_links":{"self":[{"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/posts\/17776","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/comments?post=17776"}],"version-history":[{"count":0,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/posts\/17776\/revisions"}],"wp:attachment":[{"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/media?parent=17776"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/categories?post=17776"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/tags?post=17776"},{"taxonomy":"kronos_expire_date","embeddable":true,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/kronos_expire_date?post=17776"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}