CINXE.COM

Project Zero: The quantum state of Linux kernel garbage collection CVE-2021-0920 (Part I)

<!DOCTYPE html> <html class='v2' dir='ltr' lang='en' xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr'> <head> <link href='https://www.blogger.com/static/v1/widgets/3566091532-css_bundle_v2.css' rel='stylesheet' type='text/css'/> <meta content='width=1100' name='viewport'/> <meta content='text/html; charset=UTF-8' http-equiv='Content-Type'/> <meta content='blogger' name='generator'/> <link href='https://googleprojectzero.blogspot.com/favicon.ico' rel='icon' type='image/x-icon'/> <link href='https://googleprojectzero.blogspot.com/2022/08/the-quantum-state-of-linux-kernel.html' rel='canonical'/> <link rel="alternate" type="application/atom+xml" title="Project Zero - Atom" href="https://googleprojectzero.blogspot.com/feeds/posts/default" /> <link rel="alternate" type="application/rss+xml" title="Project Zero - RSS" href="https://googleprojectzero.blogspot.com/feeds/posts/default?alt=rss" /> <link rel="service.post" type="application/atom+xml" title="Project Zero - Atom" href="https://www.blogger.com/feeds/4838136820032157985/posts/default" /> <link rel="alternate" type="application/atom+xml" title="Project Zero - Atom" href="https://googleprojectzero.blogspot.com/feeds/6481767562526230244/comments/default" /> <!--Can't find substitution for tag [blog.ieCssRetrofitLinks]--> <link href='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNWAkA0RVb4goO21_FhJOVV-LSNTfbXV7GKoqH-CUrdMTpDcNUSQxEssrnAVGxC50aK-Z3HfIWeDyCgkr6lb5-a1Ha9Km5ppaHeBzWmLj8NTmZtUjx8J-VzzM1O7mYdjOfw2ErddrslDXw6rDZrs0g1DEC1Ya4VAbkLKKEhZgNPeiSefH-xpv3zDa8/s1200/image71.png' rel='image_src'/> <meta content='https://googleprojectzero.blogspot.com/2022/08/the-quantum-state-of-linux-kernel.html' property='og:url'/> <meta content='The quantum state of Linux kernel garbage collection CVE-2021-0920 (Part I)' property='og:title'/> <meta content=' A deep dive into an in-the-wild Android exploit Guest Post by Xingyu Jin, Android Security Research This is part one of a two-part guest...' property='og:description'/> <meta content='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNWAkA0RVb4goO21_FhJOVV-LSNTfbXV7GKoqH-CUrdMTpDcNUSQxEssrnAVGxC50aK-Z3HfIWeDyCgkr6lb5-a1Ha9Km5ppaHeBzWmLj8NTmZtUjx8J-VzzM1O7mYdjOfw2ErddrslDXw6rDZrs0g1DEC1Ya4VAbkLKKEhZgNPeiSefH-xpv3zDa8/w1200-h630-p-k-no-nu/image71.png' property='og:image'/> <title>Project Zero: The quantum state of Linux kernel garbage collection CVE-2021-0920 (Part I)</title> <style type='text/css'>@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;font-display:swap;src:url(//fonts.gstatic.com/s/opensans/v40/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4gaVY.eot);}</style> <style id='page-skin-1' type='text/css'><!-- /* ----------------------------------------------- Blogger Template Style Name: Simple Designer: Blogger URL: www.blogger.com ----------------------------------------------- */ /* Variable definitions ==================== <Variable name="keycolor" description="Main Color" type="color" default="#66bbdd"/> <Group description="Page Text" selector="body"> <Variable name="body.font" description="Font" type="font" default="normal normal 12px Arial, Tahoma, Helvetica, FreeSans, sans-serif"/> <Variable name="body.text.color" description="Text Color" type="color" default="#222222"/> </Group> <Group description="Backgrounds" selector=".body-fauxcolumns-outer"> <Variable name="body.background.color" description="Outer Background" type="color" default="#66bbdd"/> <Variable name="content.background.color" description="Main Background" type="color" default="#ffffff"/> <Variable name="header.background.color" description="Header Background" type="color" default="transparent"/> </Group> <Group description="Links" selector=".main-outer"> <Variable name="link.color" description="Link Color" type="color" default="#2288bb"/> <Variable name="link.visited.color" description="Visited Color" type="color" default="#888888"/> <Variable name="link.hover.color" description="Hover Color" type="color" default="#33aaff"/> </Group> <Group description="Blog Title" selector=".header h1"> <Variable name="header.font" description="Font" type="font" default="normal normal 60px Arial, Tahoma, Helvetica, FreeSans, sans-serif"/> <Variable name="header.text.color" description="Title Color" type="color" default="#3399bb" /> </Group> <Group description="Blog Description" selector=".header .description"> <Variable name="description.text.color" description="Description Color" type="color" default="#777777" /> </Group> <Group description="Tabs Text" selector=".tabs-inner .widget li a"> <Variable name="tabs.font" description="Font" type="font" default="normal normal 14px Arial, Tahoma, Helvetica, FreeSans, sans-serif"/> <Variable name="tabs.text.color" description="Text Color" type="color" default="#999999"/> <Variable name="tabs.selected.text.color" description="Selected Color" type="color" default="#000000"/> </Group> <Group description="Tabs Background" selector=".tabs-outer .PageList"> <Variable name="tabs.background.color" description="Background Color" type="color" default="#f5f5f5"/> <Variable name="tabs.selected.background.color" description="Selected Color" type="color" default="#eeeeee"/> </Group> <Group description="Post Title" selector="h3.post-title, .comments h4"> <Variable name="post.title.font" description="Font" type="font" default="normal normal 22px Arial, Tahoma, Helvetica, FreeSans, sans-serif"/> </Group> <Group description="Date Header" selector=".date-header"> <Variable name="date.header.color" description="Text Color" type="color" default="#000000"/> <Variable name="date.header.background.color" description="Background Color" type="color" default="transparent"/> <Variable name="date.header.font" description="Text Font" type="font" default="normal bold 11px Arial, Tahoma, Helvetica, FreeSans, sans-serif"/> <Variable name="date.header.padding" description="Date Header Padding" type="string" default="inherit"/> <Variable name="date.header.letterspacing" description="Date Header Letter Spacing" type="string" default="inherit"/> <Variable name="date.header.margin" description="Date Header Margin" type="string" default="inherit"/> </Group> <Group description="Post Footer" selector=".post-footer"> <Variable name="post.footer.text.color" description="Text Color" type="color" default="#666666"/> <Variable name="post.footer.background.color" description="Background Color" type="color" default="#f9f9f9"/> <Variable name="post.footer.border.color" description="Shadow Color" type="color" default="#eeeeee"/> </Group> <Group description="Gadgets" selector="h2"> <Variable name="widget.title.font" description="Title Font" type="font" default="normal bold 11px Arial, Tahoma, Helvetica, FreeSans, sans-serif"/> <Variable name="widget.title.text.color" description="Title Color" type="color" default="#000000"/> <Variable name="widget.alternate.text.color" description="Alternate Color" type="color" default="#999999"/> </Group> <Group description="Images" selector=".main-inner"> <Variable name="image.background.color" description="Background Color" type="color" default="#ffffff"/> <Variable name="image.border.color" description="Border Color" type="color" default="#eeeeee"/> <Variable name="image.text.color" description="Caption Text Color" type="color" default="#000000"/> </Group> <Group description="Accents" selector=".content-inner"> <Variable name="body.rule.color" description="Separator Line Color" type="color" default="#eeeeee"/> <Variable name="tabs.border.color" description="Tabs Border Color" type="color" default="transparent"/> </Group> <Variable name="body.background" description="Body Background" type="background" color="#eeeeee" default="$(color) none repeat scroll top left"/> <Variable name="body.background.override" description="Body Background Override" type="string" default=""/> <Variable name="body.background.gradient.cap" description="Body Gradient Cap" type="url" default="url(https://resources.blogblog.com/blogblog/data/1kt/simple/gradients_light.png)"/> <Variable name="body.background.gradient.tile" description="Body Gradient Tile" type="url" default="url(https://resources.blogblog.com/blogblog/data/1kt/simple/body_gradient_tile_light.png)"/> <Variable name="content.background.color.selector" description="Content Background Color Selector" type="string" default=".content-inner"/> <Variable name="content.padding" description="Content Padding" type="length" default="10px" min="0" max="100px"/> <Variable name="content.padding.horizontal" description="Content Horizontal Padding" type="length" default="10px" min="0" max="100px"/> <Variable name="content.shadow.spread" description="Content Shadow Spread" type="length" default="40px" min="0" max="100px"/> <Variable name="content.shadow.spread.webkit" description="Content Shadow Spread (WebKit)" type="length" default="5px" min="0" max="100px"/> <Variable name="content.shadow.spread.ie" description="Content Shadow Spread (IE)" type="length" default="10px" min="0" max="100px"/> <Variable name="main.border.width" description="Main Border Width" type="length" default="0" min="0" max="10px"/> <Variable name="header.background.gradient" description="Header Gradient" type="url" default="none"/> <Variable name="header.shadow.offset.left" description="Header Shadow Offset Left" type="length" default="-1px" min="-50px" max="50px"/> <Variable name="header.shadow.offset.top" description="Header Shadow Offset Top" type="length" default="-1px" min="-50px" max="50px"/> <Variable name="header.shadow.spread" description="Header Shadow Spread" type="length" default="1px" min="0" max="100px"/> <Variable name="header.padding" description="Header Padding" type="length" default="30px" min="0" max="100px"/> <Variable name="header.border.size" description="Header Border Size" type="length" default="1px" min="0" max="10px"/> <Variable name="header.bottom.border.size" description="Header Bottom Border Size" type="length" default="1px" min="0" max="10px"/> <Variable name="header.border.horizontalsize" description="Header Horizontal Border Size" type="length" default="0" min="0" max="10px"/> <Variable name="description.text.size" description="Description Text Size" type="string" default="140%"/> <Variable name="tabs.margin.top" description="Tabs Margin Top" type="length" default="0" min="0" max="100px"/> <Variable name="tabs.margin.side" description="Tabs Side Margin" type="length" default="30px" min="0" max="100px"/> <Variable name="tabs.background.gradient" description="Tabs Background Gradient" type="url" default="url(https://resources.blogblog.com/blogblog/data/1kt/simple/gradients_light.png)"/> <Variable name="tabs.border.width" description="Tabs Border Width" type="length" default="1px" min="0" max="10px"/> <Variable name="tabs.bevel.border.width" description="Tabs Bevel Border Width" type="length" default="1px" min="0" max="10px"/> <Variable name="post.margin.bottom" description="Post Bottom Margin" type="length" default="25px" min="0" max="100px"/> <Variable name="image.border.small.size" description="Image Border Small Size" type="length" default="2px" min="0" max="10px"/> <Variable name="image.border.large.size" description="Image Border Large Size" type="length" default="5px" min="0" max="10px"/> <Variable name="page.width.selector" description="Page Width Selector" type="string" default=".region-inner"/> <Variable name="page.width" description="Page Width" type="string" default="auto"/> <Variable name="main.section.margin" description="Main Section Margin" type="length" default="15px" min="0" max="100px"/> <Variable name="main.padding" description="Main Padding" type="length" default="15px" min="0" max="100px"/> <Variable name="main.padding.top" description="Main Padding Top" type="length" default="30px" min="0" max="100px"/> <Variable name="main.padding.bottom" description="Main Padding Bottom" type="length" default="30px" min="0" max="100px"/> <Variable name="paging.background" color="#ffffff" description="Background of blog paging area" type="background" default="transparent none no-repeat scroll top center"/> <Variable name="footer.bevel" description="Bevel border length of footer" type="length" default="0" min="0" max="10px"/> <Variable name="mobile.background.overlay" description="Mobile Background Overlay" type="string" default="transparent none repeat scroll top left"/> <Variable name="mobile.background.size" description="Mobile Background Size" type="string" default="auto"/> <Variable name="mobile.button.color" description="Mobile Button Color" type="color" default="#ffffff" /> <Variable name="startSide" description="Side where text starts in blog language" type="automatic" default="left"/> <Variable name="endSide" description="Side where text ends in blog language" type="automatic" default="right"/> */ /* Content ----------------------------------------------- */ body { font: normal normal 12px Open Sans; color: #000000; background: #eeeeee none repeat scroll top left; padding: 0 0 0 0; } html body .region-inner { min-width: 0; max-width: 100%; width: auto; } h2 { font-size: 22px; } a:link { text-decoration:none; color: #2288bb; } a:visited { text-decoration:none; color: #888888; } a:hover { text-decoration:underline; color: #33aaff; } .body-fauxcolumn-outer .fauxcolumn-inner { background: transparent none repeat scroll top left; _background-image: none; } .body-fauxcolumn-outer .cap-top { position: absolute; z-index: 1; height: 400px; width: 100%; } .body-fauxcolumn-outer .cap-top .cap-left { width: 100%; background: transparent none repeat-x scroll top left; _background-image: none; } .content-outer { -moz-box-shadow: 0 0 0 rgba(0, 0, 0, .15); -webkit-box-shadow: 0 0 0 rgba(0, 0, 0, .15); -goog-ms-box-shadow: 0 0 0 #333333; box-shadow: 0 0 0 rgba(0, 0, 0, .15); margin-bottom: 1px; } .content-inner { padding: 10px 40px; } .content-inner { background-color: #ffffff; } /* Header ----------------------------------------------- */ .header-outer { background: transparent none repeat-x scroll 0 -400px; _background-image: none; } .Header h1 { font: normal normal 40px Open Sans; color: #000000; text-shadow: 0 0 0 rgba(0, 0, 0, .2); } .Header h1 a { color: #000000; } .Header .description { font-size: 18px; color: #000000; } .header-inner .Header .titlewrapper { padding: 22px 0; } .header-inner .Header .descriptionwrapper { padding: 0 0; } /* Tabs ----------------------------------------------- */ .tabs-inner .section:first-child { border-top: 0 solid #dddddd; } .tabs-inner .section:first-child ul { margin-top: -1px; border-top: 1px solid #dddddd; border-left: 1px solid #dddddd; border-right: 1px solid #dddddd; } .tabs-inner .widget ul { background: transparent none repeat-x scroll 0 -800px; _background-image: none; border-bottom: 1px solid #dddddd; margin-top: 0; margin-left: -30px; margin-right: -30px; } .tabs-inner .widget li a { display: inline-block; padding: .6em 1em; font: normal normal 12px Open Sans; color: #000000; border-left: 1px solid #ffffff; border-right: 1px solid #dddddd; } .tabs-inner .widget li:first-child a { border-left: none; } .tabs-inner .widget li.selected a, .tabs-inner .widget li a:hover { color: #000000; background-color: #eeeeee; text-decoration: none; } /* Columns ----------------------------------------------- */ .main-outer { border-top: 0 solid transparent; } .fauxcolumn-left-outer .fauxcolumn-inner { border-right: 1px solid transparent; } .fauxcolumn-right-outer .fauxcolumn-inner { border-left: 1px solid transparent; } /* Headings ----------------------------------------------- */ div.widget > h2, div.widget h2.title { margin: 0 0 1em 0; font: normal bold 11px 'Trebuchet MS',Trebuchet,Verdana,sans-serif; color: #000000; } /* Widgets ----------------------------------------------- */ .widget .zippy { color: #999999; text-shadow: 2px 2px 1px rgba(0, 0, 0, .1); } .widget .popular-posts ul { list-style: none; } /* Posts ----------------------------------------------- */ h2.date-header { font: normal bold 11px Arial, Tahoma, Helvetica, FreeSans, sans-serif; } .date-header span { background-color: #bbbbbb; color: #ffffff; padding: 0.4em; letter-spacing: 3px; margin: inherit; } .main-inner { padding-top: 35px; padding-bottom: 65px; } .main-inner .column-center-inner { padding: 0 0; } .main-inner .column-center-inner .section { margin: 0 1em; } .post { margin: 0 0 45px 0; } h3.post-title, .comments h4 { font: normal normal 22px Open Sans; margin: .75em 0 0; } .post-body { font-size: 110%; line-height: 1.4; position: relative; } .post-body img, .post-body .tr-caption-container, .Profile img, .Image img, .BlogList .item-thumbnail img { padding: 2px; background: #ffffff; border: 1px solid #eeeeee; -moz-box-shadow: 1px 1px 5px rgba(0, 0, 0, .1); -webkit-box-shadow: 1px 1px 5px rgba(0, 0, 0, .1); box-shadow: 1px 1px 5px rgba(0, 0, 0, .1); } .post-body img, .post-body .tr-caption-container { padding: 5px; } .post-body .tr-caption-container { color: #666666; } .post-body .tr-caption-container img { padding: 0; background: transparent; border: none; -moz-box-shadow: 0 0 0 rgba(0, 0, 0, .1); -webkit-box-shadow: 0 0 0 rgba(0, 0, 0, .1); box-shadow: 0 0 0 rgba(0, 0, 0, .1); } .post-header { margin: 0 0 1.5em; line-height: 1.6; font-size: 90%; } .post-footer { margin: 20px -2px 0; padding: 5px 10px; color: #666666; background-color: #eeeeee; border-bottom: 1px solid #eeeeee; line-height: 1.6; font-size: 90%; } #comments .comment-author { padding-top: 1.5em; border-top: 1px solid transparent; background-position: 0 1.5em; } #comments .comment-author:first-child { padding-top: 0; border-top: none; } .avatar-image-container { margin: .2em 0 0; } #comments .avatar-image-container img { border: 1px solid #eeeeee; } /* Comments ----------------------------------------------- */ .comments .comments-content .icon.blog-author { background-repeat: no-repeat; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAAd0SU1FB9sLFwMeCjjhcOMAAAD+SURBVDjLtZSvTgNBEIe/WRRnm3U8RC1neQdsm1zSBIU9VVF1FkUguQQsD9ITmD7ECZIJSE4OZo9stoVjC/zc7ky+zH9hXwVwDpTAWWLrgS3QAe8AZgaAJI5zYAmc8r0G4AHYHQKVwII8PZrZFsBFkeRCABYiMh9BRUhnSkPTNCtVXYXURi1FpBDgArj8QU1eVXUzfnjv7yP7kwu1mYrkWlU33vs1QNu2qU8pwN0UpKoqokjWwCztrMuBhEhmh8bD5UDqur75asbcX0BGUB9/HAMB+r32hznJgXy2v0sGLBcyAJ1EK3LFcbo1s91JeLwAbwGYu7TP/3ZGfnXYPgAVNngtqatUNgAAAABJRU5ErkJggg==); } .comments .comments-content .loadmore a { border-top: 1px solid #999999; border-bottom: 1px solid #999999; } .comments .comment-thread.inline-thread { background-color: #eeeeee; } .comments .continue { border-top: 2px solid #999999; } /* Accents ---------------------------------------------- */ .section-columns td.columns-cell { border-left: 1px solid transparent; } .blog-pager { background: transparent url(//www.blogblog.com/1kt/simple/paging_dot.png) repeat-x scroll top center; } .blog-pager-older-link, .home-link, .blog-pager-newer-link { background-color: #ffffff; padding: 5px; } .footer-outer { border-top: 1px dashed #bbbbbb; } /* Mobile ----------------------------------------------- */ body.mobile { background-size: auto; } .mobile .body-fauxcolumn-outer { background: transparent none repeat scroll top left; } .mobile .body-fauxcolumn-outer .cap-top { background-size: 100% auto; } .mobile .content-outer { -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, .15); box-shadow: 0 0 3px rgba(0, 0, 0, .15); } .mobile .tabs-inner .widget ul { margin-left: 0; margin-right: 0; } .mobile .post { margin: 0; } .mobile .main-inner .column-center-inner .section { margin: 0; } .mobile .date-header span { padding: 0.1em 10px; margin: 0 -10px; } .mobile h3.post-title { margin: 0; } .mobile .blog-pager { background: transparent none no-repeat scroll top center; } .mobile .footer-outer { border-top: none; } .mobile .main-inner, .mobile .footer-inner { background-color: #ffffff; } .mobile-index-contents { color: #000000; } .mobile-link-button { background-color: #2288bb; } .mobile-link-button a:link, .mobile-link-button a:visited { color: #ffffff; } .mobile .tabs-inner .section:first-child { border-top: none; } .mobile .tabs-inner .PageList .widget-content { background-color: #eeeeee; color: #000000; border-top: 1px solid #dddddd; border-bottom: 1px solid #dddddd; } .mobile .tabs-inner .PageList .widget-content .pagelist-arrow { border-left: 1px solid #dddddd; } --></style> <style id='template-skin-1' type='text/css'><!-- body { min-width: 1120px; } .content-outer, .content-fauxcolumn-outer, .region-inner { min-width: 1120px; max-width: 1120px; _width: 1120px; } .main-inner .columns { padding-left: 0; padding-right: 310px; } .main-inner .fauxcolumn-center-outer { left: 0; right: 310px; /* IE6 does not respect left and right together */ _width: expression(this.parentNode.offsetWidth - parseInt("0") - parseInt("310px") + 'px'); } .main-inner .fauxcolumn-left-outer { width: 0; } .main-inner .fauxcolumn-right-outer { width: 310px; } .main-inner .column-left-outer { width: 0; right: 100%; margin-left: -0; } .main-inner .column-right-outer { width: 310px; margin-right: -310px; } #layout { min-width: 0; } #layout .content-outer { min-width: 0; width: 800px; } #layout .region-inner { min-width: 0; width: auto; } body#layout div.add_widget { padding: 8px; } body#layout div.add_widget a { margin-left: 32px; } --></style> <script type='text/javascript'> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-240546891-1', 'auto', 'blogger'); ga('blogger.send', 'pageview'); </script> <link href='https://www.blogger.com/dyn-css/authorization.css?targetBlogID=4838136820032157985&amp;zx=dd12d16f-47b1-45ec-9a52-9d6602fe5782' media='none' onload='if(media!=&#39;all&#39;)media=&#39;all&#39;' rel='stylesheet'/><noscript><link href='https://www.blogger.com/dyn-css/authorization.css?targetBlogID=4838136820032157985&amp;zx=dd12d16f-47b1-45ec-9a52-9d6602fe5782' rel='stylesheet'/></noscript> <meta name='google-adsense-platform-account' content='ca-host-pub-1556223355139109'/> <meta name='google-adsense-platform-domain' content='blogspot.com'/> </head> <body class='loading'> <div class='navbar section' id='navbar' name='Navbar'><div class='widget Navbar' data-version='1' id='Navbar1'><script type="text/javascript"> function setAttributeOnload(object, attribute, val) { if(window.addEventListener) { window.addEventListener('load', function(){ object[attribute] = val; }, false); } else { window.attachEvent('onload', function(){ object[attribute] = val; }); } } </script> <div id="navbar-iframe-container"></div> <script type="text/javascript" src="https://apis.google.com/js/platform.js"></script> <script type="text/javascript"> gapi.load("gapi.iframes:gapi.iframes.style.bubble", function() { if (gapi.iframes && gapi.iframes.getContext) { gapi.iframes.getContext().openChild({ url: 'https://www.blogger.com/navbar/4838136820032157985?po\x3d6481767562526230244\x26origin\x3dhttps://googleprojectzero.blogspot.com', where: document.getElementById("navbar-iframe-container"), id: "navbar-iframe" }); } }); </script><script type="text/javascript"> (function() { var script = document.createElement('script'); script.type = 'text/javascript'; script.src = '//pagead2.googlesyndication.com/pagead/js/google_top_exp.js'; var head = document.getElementsByTagName('head')[0]; if (head) { head.appendChild(script); }})(); </script> </div></div> <div class='body-fauxcolumns'> <div class='fauxcolumn-outer body-fauxcolumn-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </div> <div class='content'> <div class='content-fauxcolumns'> <div class='fauxcolumn-outer content-fauxcolumn-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </div> <div class='content-outer'> <div class='content-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left content-fauxborder-left'> <div class='fauxborder-right content-fauxborder-right'></div> <div class='content-inner'> <header> <div class='header-outer'> <div class='header-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left header-fauxborder-left'> <div class='fauxborder-right header-fauxborder-right'></div> <div class='region-inner header-inner'> <div class='header section' id='header' name='Header'><div class='widget Header' data-version='1' id='Header1'> <div id='header-inner'> <div class='titlewrapper'> <h1 class='title'> <a href='https://googleprojectzero.blogspot.com/'> Project Zero </a> </h1> </div> <div class='descriptionwrapper'> <p class='description'><span>News and updates from the Project Zero team at Google</span></p> </div> </div> </div></div> </div> </div> <div class='header-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </header> <div class='tabs-outer'> <div class='tabs-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left tabs-fauxborder-left'> <div class='fauxborder-right tabs-fauxborder-right'></div> <div class='region-inner tabs-inner'> <div class='tabs no-items section' id='crosscol' name='Cross-Column'></div> <div class='tabs no-items section' id='crosscol-overflow' name='Cross-Column 2'></div> </div> </div> <div class='tabs-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <div class='main-outer'> <div class='main-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left main-fauxborder-left'> <div class='fauxborder-right main-fauxborder-right'></div> <div class='region-inner main-inner'> <div class='columns fauxcolumns'> <div class='fauxcolumn-outer fauxcolumn-center-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <div class='fauxcolumn-outer fauxcolumn-left-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <div class='fauxcolumn-outer fauxcolumn-right-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <!-- corrects IE6 width calculation --> <div class='columns-inner'> <div class='column-center-outer'> <div class='column-center-inner'> <div class='main section' id='main' name='Main'><div class='widget Blog' data-version='1' id='Blog1'> <div class='blog-posts hfeed'> <div class="date-outer"> <h2 class='date-header'><span>Wednesday, August 10, 2022</span></h2> <div class="date-posts"> <div class='post-outer'> <div class='post hentry uncustomized-post-template' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'> <meta content='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNWAkA0RVb4goO21_FhJOVV-LSNTfbXV7GKoqH-CUrdMTpDcNUSQxEssrnAVGxC50aK-Z3HfIWeDyCgkr6lb5-a1Ha9Km5ppaHeBzWmLj8NTmZtUjx8J-VzzM1O7mYdjOfw2ErddrslDXw6rDZrs0g1DEC1Ya4VAbkLKKEhZgNPeiSefH-xpv3zDa8/s1200/image71.png' itemprop='image_url'/> <meta content='4838136820032157985' itemprop='blogId'/> <meta content='6481767562526230244' itemprop='postId'/> <a name='6481767562526230244'></a> <h3 class='post-title entry-title' itemprop='name'> The quantum state of Linux kernel garbage collection CVE-2021-0920 (Part I) </h3> <div class='post-header'> <div class='post-header-line-1'></div> </div> <div class='post-body entry-content' id='post-body-6481767562526230244' itemprop='description articleBody'> <style type="text/css">@import url('https://themes.googleusercontent.com/fonts/css?kit=wJuDEFlUsDZt7lpAAPdLm9CoNqneSjGN6FUREF5POP9krml-9Eg4KzR8naUO0aF3kuG_eoWNft1SfWZjF8JeEg');.lst-kix_wm3dnufq67dx-7>li:before{content:"- "}.lst-kix_wm3dnufq67dx-8>li:before{content:"- "}ol.lst-kix_iptxq54yrrnf-3.start{counter-reset:lst-ctn-kix_iptxq54yrrnf-3 0}.lst-kix_u3opzkdcnklc-1>li{counter-increment:lst-ctn-kix_u3opzkdcnklc-1}.lst-kix_wm3dnufq67dx-1>li:before{content:"- "}.lst-kix_iptxq54yrrnf-4>li{counter-increment:lst-ctn-kix_iptxq54yrrnf-4}ol.lst-kix_mfudkcwv2w89-7.start{counter-reset:lst-ctn-kix_mfudkcwv2w89-7 0}.lst-kix_wm3dnufq67dx-0>li:before{content:"- "}.lst-kix_hk8k8itxmlfp-4>li{counter-increment:lst-ctn-kix_hk8k8itxmlfp-4}.lst-kix_8chkxhfzc2ds-3>li:before{content:"- "}.lst-kix_8chkxhfzc2ds-5>li:before{content:"- "}.lst-kix_8chkxhfzc2ds-4>li:before{content:"- "}.lst-kix_8chkxhfzc2ds-8>li:before{content:"- "}.lst-kix_8chkxhfzc2ds-7>li:before{content:"- "}.lst-kix_8chkxhfzc2ds-6>li:before{content:"- "}ol.lst-kix_58ja23nrczhl-0{list-style-type:none}ol.lst-kix_51hgl6mwb3et-2.start{counter-reset:lst-ctn-kix_51hgl6mwb3et-2 0}ol.lst-kix_58ja23nrczhl-3{list-style-type:none}ol.lst-kix_58ja23nrczhl-4{list-style-type:none}ol.lst-kix_58ja23nrczhl-1{list-style-type:none}ol.lst-kix_58ja23nrczhl-2{list-style-type:none}ol.lst-kix_58ja23nrczhl-7{list-style-type:none}ol.lst-kix_58ja23nrczhl-8{list-style-type:none}ol.lst-kix_58ja23nrczhl-5{list-style-type:none}.lst-kix_58ja23nrczhl-4>li{counter-increment:lst-ctn-kix_58ja23nrczhl-4}ol.lst-kix_58ja23nrczhl-6{list-style-type:none}ol.lst-kix_7y90gfloiotx-8.start{counter-reset:lst-ctn-kix_7y90gfloiotx-8 0}.lst-kix_5yi4tofw6s0z-1>li{counter-increment:lst-ctn-kix_5yi4tofw6s0z-1}.lst-kix_51hgl6mwb3et-0>li:before{content:"" counter(lst-ctn-kix_51hgl6mwb3et-0,decimal) ". "}.lst-kix_51hgl6mwb3et-1>li:before{content:"" counter(lst-ctn-kix_51hgl6mwb3et-1,lower-latin) ". "}.lst-kix_51hgl6mwb3et-2>li:before{content:"" counter(lst-ctn-kix_51hgl6mwb3et-2,lower-roman) ". "}.lst-kix_5oipgjcxugcr-0>li{counter-increment:lst-ctn-kix_5oipgjcxugcr-0}ol.lst-kix_j5vmamheymgq-4.start{counter-reset:lst-ctn-kix_j5vmamheymgq-4 0}.lst-kix_51hgl6mwb3et-3>li:before{content:"" counter(lst-ctn-kix_51hgl6mwb3et-3,decimal) ". "}ol.lst-kix_8mkn8rg9im4a-0.start{counter-reset:lst-ctn-kix_8mkn8rg9im4a-0 0}.lst-kix_51hgl6mwb3et-4>li:before{content:"" counter(lst-ctn-kix_51hgl6mwb3et-4,lower-latin) ". "}.lst-kix_51hgl6mwb3et-6>li:before{content:"" counter(lst-ctn-kix_51hgl6mwb3et-6,decimal) ". "}.lst-kix_51hgl6mwb3et-5>li:before{content:"" counter(lst-ctn-kix_51hgl6mwb3et-5,lower-roman) ". "}.lst-kix_whw4pjgxp3w1-2>li:before{content:"- "}.lst-kix_hk8k8itxmlfp-0>li:before{content:"" counter(lst-ctn-kix_hk8k8itxmlfp-0,decimal) ". "}.lst-kix_51hgl6mwb3et-8>li:before{content:"" counter(lst-ctn-kix_51hgl6mwb3et-8,lower-roman) ". "}.lst-kix_whw4pjgxp3w1-1>li:before{content:"- "}.lst-kix_51hgl6mwb3et-7>li:before{content:"" counter(lst-ctn-kix_51hgl6mwb3et-7,lower-latin) ". "}.lst-kix_whw4pjgxp3w1-0>li:before{content:"- "}ol.lst-kix_mfudkcwv2w89-2.start{counter-reset:lst-ctn-kix_mfudkcwv2w89-2 0}.lst-kix_hk8k8itxmlfp-3>li:before{content:"" counter(lst-ctn-kix_hk8k8itxmlfp-3,decimal) ". "}.lst-kix_hk8k8itxmlfp-2>li:before{content:"" counter(lst-ctn-kix_hk8k8itxmlfp-2,lower-roman) ". "}.lst-kix_hk8k8itxmlfp-4>li:before{content:"" counter(lst-ctn-kix_hk8k8itxmlfp-4,lower-latin) ". "}.lst-kix_hk8k8itxmlfp-1>li:before{content:"" counter(lst-ctn-kix_hk8k8itxmlfp-1,lower-latin) ". "}.lst-kix_hk8k8itxmlfp-5>li:before{content:"" counter(lst-ctn-kix_hk8k8itxmlfp-5,lower-roman) ". "}ul.lst-kix_9gryrzygx46m-6{list-style-type:none}ul.lst-kix_9gryrzygx46m-5{list-style-type:none}ul.lst-kix_9gryrzygx46m-4{list-style-type:none}ul.lst-kix_9gryrzygx46m-3{list-style-type:none}ul.lst-kix_9gryrzygx46m-8{list-style-type:none}ul.lst-kix_9gryrzygx46m-7{list-style-type:none}.lst-kix_5yi4tofw6s0z-8>li{counter-increment:lst-ctn-kix_5yi4tofw6s0z-8}.lst-kix_wm3dnufq67dx-2>li:before{content:"- "}ol.lst-kix_5yi4tofw6s0z-4.start{counter-reset:lst-ctn-kix_5yi4tofw6s0z-4 0}.lst-kix_wm3dnufq67dx-3>li:before{content:"- "}.lst-kix_wm3dnufq67dx-4>li:before{content:"- "}ol.lst-kix_iptxq54yrrnf-8.start{counter-reset:lst-ctn-kix_iptxq54yrrnf-8 0}ol.lst-kix_7y90gfloiotx-3.start{counter-reset:lst-ctn-kix_7y90gfloiotx-3 0}.lst-kix_hk8k8itxmlfp-7>li:before{content:"" counter(lst-ctn-kix_hk8k8itxmlfp-7,lower-latin) ". "}.lst-kix_wm3dnufq67dx-5>li:before{content:"- "}.lst-kix_wm3dnufq67dx-6>li:before{content:"- "}.lst-kix_hk8k8itxmlfp-6>li:before{content:"" counter(lst-ctn-kix_hk8k8itxmlfp-6,decimal) ". "}.lst-kix_hk8k8itxmlfp-8>li:before{content:"" counter(lst-ctn-kix_hk8k8itxmlfp-8,lower-roman) ". "}ol.lst-kix_58ja23nrczhl-4.start{counter-reset:lst-ctn-kix_58ja23nrczhl-4 0}ul.lst-kix_wm3dnufq67dx-0{list-style-type:none}.lst-kix_yjo4cwnqbjp0-2>li:before{content:"- "}ul.lst-kix_wm3dnufq67dx-2{list-style-type:none}ul.lst-kix_wm3dnufq67dx-1{list-style-type:none}.lst-kix_yjo4cwnqbjp0-0>li:before{content:"- "}ul.lst-kix_wm3dnufq67dx-8{list-style-type:none}ul.lst-kix_wm3dnufq67dx-7{list-style-type:none}ul.lst-kix_wm3dnufq67dx-4{list-style-type:none}ul.lst-kix_9gryrzygx46m-2{list-style-type:none}ul.lst-kix_wm3dnufq67dx-3{list-style-type:none}ul.lst-kix_9gryrzygx46m-1{list-style-type:none}ul.lst-kix_wm3dnufq67dx-6{list-style-type:none}ul.lst-kix_9gryrzygx46m-0{list-style-type:none}ul.lst-kix_wm3dnufq67dx-5{list-style-type:none}.lst-kix_yjo4cwnqbjp0-6>li:before{content:"- "}.lst-kix_6l3lpr6ytz51-0>li:before{content:"- "}.lst-kix_yjo4cwnqbjp0-4>li:before{content:"- "}.lst-kix_whw4pjgxp3w1-6>li:before{content:"- "}.lst-kix_j5vmamheymgq-3>li{counter-increment:lst-ctn-kix_j5vmamheymgq-3}.lst-kix_7y90gfloiotx-7>li{counter-increment:lst-ctn-kix_7y90gfloiotx-7}.lst-kix_9prd8pa3o8y7-6>li{counter-increment:lst-ctn-kix_9prd8pa3o8y7-6}ol.lst-kix_9prd8pa3o8y7-7.start{counter-reset:lst-ctn-kix_9prd8pa3o8y7-7 0}.lst-kix_whw4pjgxp3w1-4>li:before{content:"- "}ol.lst-kix_u3opzkdcnklc-8.start{counter-reset:lst-ctn-kix_u3opzkdcnklc-8 0}.lst-kix_whw4pjgxp3w1-8>li:before{content:"- "}ol.lst-kix_51hgl6mwb3et-7.start{counter-reset:lst-ctn-kix_51hgl6mwb3et-7 0}ol.lst-kix_hk8k8itxmlfp-7.start{counter-reset:lst-ctn-kix_hk8k8itxmlfp-7 0}ol.lst-kix_p4ttii5g8cnl-7.start{counter-reset:lst-ctn-kix_p4ttii5g8cnl-7 0}ol.lst-kix_5oipgjcxugcr-8.start{counter-reset:lst-ctn-kix_5oipgjcxugcr-8 0}.lst-kix_j5vmamheymgq-7>li:before{content:"" counter(lst-ctn-kix_j5vmamheymgq-7,lower-latin) ". "}.lst-kix_9prd8pa3o8y7-5>li{counter-increment:lst-ctn-kix_9prd8pa3o8y7-5}.lst-kix_8chkxhfzc2ds-1>li:before{content:"- "}.lst-kix_u3opzkdcnklc-8>li{counter-increment:lst-ctn-kix_u3opzkdcnklc-8}.lst-kix_6l3lpr6ytz51-4>li:before{content:"- "}.lst-kix_6l3lpr6ytz51-6>li:before{content:"- "}.lst-kix_j5vmamheymgq-5>li:before{content:"" counter(lst-ctn-kix_j5vmamheymgq-5,lower-roman) ". "}.lst-kix_6l3lpr6ytz51-2>li:before{content:"- "}.lst-kix_5oipgjcxugcr-8>li{counter-increment:lst-ctn-kix_5oipgjcxugcr-8}.lst-kix_j5vmamheymgq-1>li:before{content:"" counter(lst-ctn-kix_j5vmamheymgq-1,lower-latin) ". "}.lst-kix_j5vmamheymgq-3>li:before{content:"" counter(lst-ctn-kix_j5vmamheymgq-3,decimal) ". "}.lst-kix_6l3lpr6ytz51-8>li:before{content:"- "}.lst-kix_7y90gfloiotx-6>li{counter-increment:lst-ctn-kix_7y90gfloiotx-6}.lst-kix_iptxq54yrrnf-5>li{counter-increment:lst-ctn-kix_iptxq54yrrnf-5}ol.lst-kix_hk8k8itxmlfp-8.start{counter-reset:lst-ctn-kix_hk8k8itxmlfp-8 0}.lst-kix_hk8k8itxmlfp-5>li{counter-increment:lst-ctn-kix_hk8k8itxmlfp-5}ol.lst-kix_p4ttii5g8cnl-6.start{counter-reset:lst-ctn-kix_p4ttii5g8cnl-6 0}.lst-kix_mfudkcwv2w89-1>li{counter-increment:lst-ctn-kix_mfudkcwv2w89-1}.lst-kix_58ja23nrczhl-3>li{counter-increment:lst-ctn-kix_58ja23nrczhl-3}.lst-kix_hk8k8itxmlfp-3>li{counter-increment:lst-ctn-kix_hk8k8itxmlfp-3}.lst-kix_u3opzkdcnklc-4>li:before{content:"" counter(lst-ctn-kix_u3opzkdcnklc-4,lower-latin) ". "}.lst-kix_u3opzkdcnklc-8>li:before{content:"" counter(lst-ctn-kix_u3opzkdcnklc-8,lower-roman) ". "}.lst-kix_u3opzkdcnklc-3>li:before{content:"" counter(lst-ctn-kix_u3opzkdcnklc-3,decimal) ". "}.lst-kix_u3opzkdcnklc-7>li:before{content:"" counter(lst-ctn-kix_u3opzkdcnklc-7,lower-latin) ". "}.lst-kix_iptxq54yrrnf-3>li{counter-increment:lst-ctn-kix_iptxq54yrrnf-3}ol.lst-kix_p4ttii5g8cnl-1.start{counter-reset:lst-ctn-kix_p4ttii5g8cnl-1 0}ol.lst-kix_j5vmamheymgq-8.start{counter-reset:lst-ctn-kix_j5vmamheymgq-8 0}ul.lst-kix_h1p96gz9lzq4-0{list-style-type:none}ul.lst-kix_h1p96gz9lzq4-1{list-style-type:none}.lst-kix_u3opzkdcnklc-0>li:before{content:"" counter(lst-ctn-kix_u3opzkdcnklc-0,decimal) ". "}ul.lst-kix_h1p96gz9lzq4-4{list-style-type:none}ul.lst-kix_h1p96gz9lzq4-5{list-style-type:none}ul.lst-kix_h1p96gz9lzq4-2{list-style-type:none}ul.lst-kix_h1p96gz9lzq4-3{list-style-type:none}ul.lst-kix_h1p96gz9lzq4-8{list-style-type:none}.lst-kix_mfudkcwv2w89-3>li{counter-increment:lst-ctn-kix_mfudkcwv2w89-3}ul.lst-kix_h1p96gz9lzq4-6{list-style-type:none}ul.lst-kix_h1p96gz9lzq4-7{list-style-type:none}.lst-kix_3a2g7o19wgb3-2>li{counter-increment:lst-ctn-kix_3a2g7o19wgb3-2}.lst-kix_p4ttii5g8cnl-5>li{counter-increment:lst-ctn-kix_p4ttii5g8cnl-5}.lst-kix_5oipgjcxugcr-1>li{counter-increment:lst-ctn-kix_5oipgjcxugcr-1}.lst-kix_3a2g7o19wgb3-4>li{counter-increment:lst-ctn-kix_3a2g7o19wgb3-4}ol.lst-kix_j5vmamheymgq-3.start{counter-reset:lst-ctn-kix_j5vmamheymgq-3 0}ol.lst-kix_u3opzkdcnklc-7.start{counter-reset:lst-ctn-kix_u3opzkdcnklc-7 0}.lst-kix_yjo4cwnqbjp0-8>li:before{content:"- "}ol.lst-kix_9prd8pa3o8y7-6.start{counter-reset:lst-ctn-kix_9prd8pa3o8y7-6 0}.lst-kix_g3pd9wzbzpzz-3>li:before{content:"- "}.lst-kix_g3pd9wzbzpzz-7>li:before{content:"- "}ol.lst-kix_p4ttii5g8cnl-2.start{counter-reset:lst-ctn-kix_p4ttii5g8cnl-2 0}.lst-kix_yjo4cwnqbjp0-1>li:before{content:"- "}ol.lst-kix_iptxq54yrrnf-7.start{counter-reset:lst-ctn-kix_iptxq54yrrnf-7 0}.lst-kix_yjo4cwnqbjp0-5>li:before{content:"- "}.lst-kix_yn2ql2u2egdg-0>li:before{content:"- "}ol.lst-kix_51hgl6mwb3et-1.start{counter-reset:lst-ctn-kix_51hgl6mwb3et-1 0}.lst-kix_dqkfvt9lb2wy-1>li:before{content:"- "}ol.lst-kix_iptxq54yrrnf-4.start{counter-reset:lst-ctn-kix_iptxq54yrrnf-4 0}.lst-kix_whw4pjgxp3w1-5>li:before{content:"- "}.lst-kix_51hgl6mwb3et-2>li{counter-increment:lst-ctn-kix_51hgl6mwb3et-2}.lst-kix_yn2ql2u2egdg-8>li:before{content:"- "}ol.lst-kix_u3opzkdcnklc-2.start{counter-reset:lst-ctn-kix_u3opzkdcnklc-2 0}.lst-kix_mfudkcwv2w89-6>li:before{content:"" counter(lst-ctn-kix_mfudkcwv2w89-6,decimal) ". "}ol.lst-kix_9prd8pa3o8y7-1.start{counter-reset:lst-ctn-kix_9prd8pa3o8y7-1 0}.lst-kix_dqkfvt9lb2wy-5>li:before{content:"- "}.lst-kix_yn2ql2u2egdg-4>li:before{content:"- "}.lst-kix_mfudkcwv2w89-2>li:before{content:"" counter(lst-ctn-kix_mfudkcwv2w89-2,lower-roman) ". "}.lst-kix_5oipgjcxugcr-6>li:before{content:"" counter(lst-ctn-kix_5oipgjcxugcr-6,decimal) ". "}.lst-kix_3a2g7o19wgb3-7>li:before{content:"" counter(lst-ctn-kix_3a2g7o19wgb3-7,lower-latin) ". "}.lst-kix_5oipgjcxugcr-2>li:before{content:"" counter(lst-ctn-kix_5oipgjcxugcr-2,lower-roman) ". "}.lst-kix_yzib59bcdnhj-4>li:before{content:"- "}.lst-kix_iptxq54yrrnf-4>li:before{content:"" counter(lst-ctn-kix_iptxq54yrrnf-4,lower-latin) ". "}.lst-kix_j5vmamheymgq-1>li{counter-increment:lst-ctn-kix_j5vmamheymgq-1}ol.lst-kix_u3opzkdcnklc-4.start{counter-reset:lst-ctn-kix_u3opzkdcnklc-4 0}.lst-kix_8chkxhfzc2ds-0>li:before{content:"- "}.lst-kix_3a2g7o19wgb3-3>li:before{content:"" counter(lst-ctn-kix_3a2g7o19wgb3-3,decimal) ". "}.lst-kix_iptxq54yrrnf-8>li:before{content:"" counter(lst-ctn-kix_iptxq54yrrnf-8,lower-roman) ". "}.lst-kix_j5vmamheymgq-8>li:before{content:"" counter(lst-ctn-kix_j5vmamheymgq-8,lower-roman) ". "}.lst-kix_mfudkcwv2w89-8>li{counter-increment:lst-ctn-kix_mfudkcwv2w89-8}.lst-kix_yzib59bcdnhj-0>li:before{content:"- "}.lst-kix_8mkn8rg9im4a-2>li{counter-increment:lst-ctn-kix_8mkn8rg9im4a-2}.lst-kix_h1p96gz9lzq4-0>li:before{content:"- "}.lst-kix_9prd8pa3o8y7-2>li:before{content:"" counter(lst-ctn-kix_9prd8pa3o8y7-2,lower-roman) ". "}.lst-kix_9prd8pa3o8y7-6>li:before{content:"" counter(lst-ctn-kix_9prd8pa3o8y7-6,decimal) ". "}.lst-kix_h1p96gz9lzq4-4>li:before{content:"- "}ol.lst-kix_9prd8pa3o8y7-2.start{counter-reset:lst-ctn-kix_9prd8pa3o8y7-2 0}.lst-kix_j5vmamheymgq-4>li:before{content:"" counter(lst-ctn-kix_j5vmamheymgq-4,lower-latin) ". "}.lst-kix_6l3lpr6ytz51-3>li:before{content:"- "}.lst-kix_h1p96gz9lzq4-8>li:before{content:"- "}ol.lst-kix_u3opzkdcnklc-3.start{counter-reset:lst-ctn-kix_u3opzkdcnklc-3 0}.lst-kix_p4ttii5g8cnl-7>li{counter-increment:lst-ctn-kix_p4ttii5g8cnl-7}.lst-kix_yzib59bcdnhj-8>li:before{content:"- "}.lst-kix_j5vmamheymgq-0>li:before{content:"" counter(lst-ctn-kix_j5vmamheymgq-0,decimal) ". "}.lst-kix_6l3lpr6ytz51-7>li:before{content:"- "}ol.lst-kix_5yi4tofw6s0z-8{list-style-type:none}ol.lst-kix_5yi4tofw6s0z-7{list-style-type:none}ol.lst-kix_5yi4tofw6s0z-6{list-style-type:none}.lst-kix_58ja23nrczhl-2>li{counter-increment:lst-ctn-kix_58ja23nrczhl-2}ol.lst-kix_5yi4tofw6s0z-5{list-style-type:none}.lst-kix_7y90gfloiotx-1>li{counter-increment:lst-ctn-kix_7y90gfloiotx-1}ol.lst-kix_3a2g7o19wgb3-1.start{counter-reset:lst-ctn-kix_3a2g7o19wgb3-1 0}.lst-kix_iptxq54yrrnf-6>li{counter-increment:lst-ctn-kix_iptxq54yrrnf-6}.lst-kix_8mkn8rg9im4a-4>li{counter-increment:lst-ctn-kix_8mkn8rg9im4a-4}ol.lst-kix_51hgl6mwb3et-8.start{counter-reset:lst-ctn-kix_51hgl6mwb3et-8 0}ol.lst-kix_7y90gfloiotx-2.start{counter-reset:lst-ctn-kix_7y90gfloiotx-2 0}.lst-kix_iptxq54yrrnf-2>li:before{content:"" counter(lst-ctn-kix_iptxq54yrrnf-2,lower-roman) ". "}.lst-kix_u3opzkdcnklc-3>li{counter-increment:lst-ctn-kix_u3opzkdcnklc-3}ul.lst-kix_yn2ql2u2egdg-6{list-style-type:none}ul.lst-kix_yn2ql2u2egdg-5{list-style-type:none}ul.lst-kix_yn2ql2u2egdg-8{list-style-type:none}ul.lst-kix_yn2ql2u2egdg-7{list-style-type:none}ol.lst-kix_8mkn8rg9im4a-1.start{counter-reset:lst-ctn-kix_8mkn8rg9im4a-1 0}.lst-kix_p4ttii5g8cnl-0>li:before{content:"" counter(lst-ctn-kix_p4ttii5g8cnl-0,decimal) ". "}.lst-kix_p4ttii5g8cnl-3>li:before{content:"" counter(lst-ctn-kix_p4ttii5g8cnl-3,decimal) ". "}.lst-kix_iptxq54yrrnf-2>li{counter-increment:lst-ctn-kix_iptxq54yrrnf-2}.lst-kix_j5vmamheymgq-8>li{counter-increment:lst-ctn-kix_j5vmamheymgq-8}.lst-kix_p4ttii5g8cnl-5>li:before{content:"" counter(lst-ctn-kix_p4ttii5g8cnl-5,lower-roman) ". "}.lst-kix_p4ttii5g8cnl-6>li:before{content:"" counter(lst-ctn-kix_p4ttii5g8cnl-6,decimal) ". "}ol.lst-kix_51hgl6mwb3et-3.start{counter-reset:lst-ctn-kix_51hgl6mwb3et-3 0}.lst-kix_58ja23nrczhl-6>li{counter-increment:lst-ctn-kix_58ja23nrczhl-6}.lst-kix_7y90gfloiotx-8>li{counter-increment:lst-ctn-kix_7y90gfloiotx-8}ol.lst-kix_3a2g7o19wgb3-6.start{counter-reset:lst-ctn-kix_3a2g7o19wgb3-6 0}ol.lst-kix_58ja23nrczhl-5.start{counter-reset:lst-ctn-kix_58ja23nrczhl-5 0}ol.lst-kix_p4ttii5g8cnl-3.start{counter-reset:lst-ctn-kix_p4ttii5g8cnl-3 0}ol.lst-kix_5yi4tofw6s0z-0{list-style-type:none}ol.lst-kix_8mkn8rg9im4a-6.start{counter-reset:lst-ctn-kix_8mkn8rg9im4a-6 0}.lst-kix_58ja23nrczhl-5>li:before{content:"" counter(lst-ctn-kix_58ja23nrczhl-5,lower-roman) ". "}.lst-kix_p4ttii5g8cnl-8>li:before{content:"" counter(lst-ctn-kix_p4ttii5g8cnl-8,lower-roman) ". "}ol.lst-kix_5yi4tofw6s0z-4{list-style-type:none}.lst-kix_58ja23nrczhl-4>li:before{content:"" counter(lst-ctn-kix_58ja23nrczhl-4,lower-latin) ". "}ol.lst-kix_5yi4tofw6s0z-3{list-style-type:none}ol.lst-kix_5yi4tofw6s0z-2{list-style-type:none}ol.lst-kix_5yi4tofw6s0z-1{list-style-type:none}.lst-kix_58ja23nrczhl-2>li:before{content:"" counter(lst-ctn-kix_58ja23nrczhl-2,lower-roman) ". "}.lst-kix_g3pd9wzbzpzz-6>li:before{content:"- "}ol.lst-kix_3a2g7o19wgb3-8.start{counter-reset:lst-ctn-kix_3a2g7o19wgb3-8 0}ol.lst-kix_8mkn8rg9im4a-8.start{counter-reset:lst-ctn-kix_8mkn8rg9im4a-8 0}.lst-kix_yn2ql2u2egdg-1>li:before{content:"- "}.lst-kix_58ja23nrczhl-7>li:before{content:"" counter(lst-ctn-kix_58ja23nrczhl-7,lower-latin) ". "}ol.lst-kix_7y90gfloiotx-1{list-style-type:none}ol.lst-kix_7y90gfloiotx-0{list-style-type:none}.lst-kix_g3pd9wzbzpzz-4>li:before{content:"- "}ol.lst-kix_7y90gfloiotx-4.start{counter-reset:lst-ctn-kix_7y90gfloiotx-4 0}.lst-kix_dqkfvt9lb2wy-0>li:before{content:"- "}ol.lst-kix_7y90gfloiotx-7{list-style-type:none}ol.lst-kix_7y90gfloiotx-6{list-style-type:none}ol.lst-kix_7y90gfloiotx-8{list-style-type:none}ol.lst-kix_7y90gfloiotx-3{list-style-type:none}ol.lst-kix_7y90gfloiotx-2{list-style-type:none}ol.lst-kix_7y90gfloiotx-5{list-style-type:none}ol.lst-kix_7y90gfloiotx-4{list-style-type:none}.lst-kix_k47gmg94hbw2-5>li:before{content:"- "}ol.lst-kix_p4ttii5g8cnl-5.start{counter-reset:lst-ctn-kix_p4ttii5g8cnl-5 0}.lst-kix_mfudkcwv2w89-7>li:before{content:"" counter(lst-ctn-kix_mfudkcwv2w89-7,lower-latin) ". "}.lst-kix_yn2ql2u2egdg-3>li:before{content:"- "}ol.lst-kix_hk8k8itxmlfp-4.start{counter-reset:lst-ctn-kix_hk8k8itxmlfp-4 0}.lst-kix_mfudkcwv2w89-1>li:before{content:"" counter(lst-ctn-kix_mfudkcwv2w89-1,lower-latin) ". "}.lst-kix_dqkfvt9lb2wy-6>li:before{content:"- "}ol.lst-kix_p4ttii5g8cnl-8.start{counter-reset:lst-ctn-kix_p4ttii5g8cnl-8 0}.lst-kix_k47gmg94hbw2-3>li:before{content:"- "}.lst-kix_dqkfvt9lb2wy-8>li:before{content:"- "}.lst-kix_3a2g7o19wgb3-8>li:before{content:"" counter(lst-ctn-kix_3a2g7o19wgb3-8,lower-roman) ". "}.lst-kix_5oipgjcxugcr-5>li:before{content:"" counter(lst-ctn-kix_5oipgjcxugcr-5,lower-roman) ". "}ol.lst-kix_58ja23nrczhl-8.start{counter-reset:lst-ctn-kix_58ja23nrczhl-8 0}.lst-kix_9gryrzygx46m-1>li:before{content:"- "}ul.lst-kix_yn2ql2u2egdg-2{list-style-type:none}ul.lst-kix_yn2ql2u2egdg-1{list-style-type:none}.lst-kix_5oipgjcxugcr-3>li:before{content:"" counter(lst-ctn-kix_5oipgjcxugcr-3,decimal) ". "}ul.lst-kix_yn2ql2u2egdg-4{list-style-type:none}ul.lst-kix_yn2ql2u2egdg-3{list-style-type:none}.lst-kix_58ja23nrczhl-5>li{counter-increment:lst-ctn-kix_58ja23nrczhl-5}ul.lst-kix_yn2ql2u2egdg-0{list-style-type:none}.lst-kix_9gryrzygx46m-7>li:before{content:"- "}.lst-kix_3a2g7o19wgb3-0>li:before{content:"" counter(lst-ctn-kix_3a2g7o19wgb3-0,decimal) ". "}.lst-kix_iptxq54yrrnf-5>li:before{content:"" counter(lst-ctn-kix_iptxq54yrrnf-5,lower-roman) ". "}.lst-kix_iptxq54yrrnf-7>li:before{content:"" counter(lst-ctn-kix_iptxq54yrrnf-7,lower-latin) ". "}.lst-kix_3a2g7o19wgb3-2>li:before{content:"" counter(lst-ctn-kix_3a2g7o19wgb3-2,lower-roman) ". "}.lst-kix_9prd8pa3o8y7-3>li:before{content:"" counter(lst-ctn-kix_9prd8pa3o8y7-3,decimal) ". "}ol.lst-kix_51hgl6mwb3et-6.start{counter-reset:lst-ctn-kix_51hgl6mwb3et-6 0}.lst-kix_zcvcgbx5ju56-1>li:before{content:"- "}.lst-kix_5oipgjcxugcr-2>li{counter-increment:lst-ctn-kix_5oipgjcxugcr-2}ol.lst-kix_7y90gfloiotx-7.start{counter-reset:lst-ctn-kix_7y90gfloiotx-7 0}.lst-kix_5yi4tofw6s0z-3>li{counter-increment:lst-ctn-kix_5yi4tofw6s0z-3}ol.lst-kix_8mkn8rg9im4a-7{list-style-type:none}ol.lst-kix_8mkn8rg9im4a-6{list-style-type:none}ol.lst-kix_8mkn8rg9im4a-8{list-style-type:none}ol.lst-kix_8mkn8rg9im4a-3{list-style-type:none}ol.lst-kix_8mkn8rg9im4a-2{list-style-type:none}ol.lst-kix_58ja23nrczhl-7.start{counter-reset:lst-ctn-kix_58ja23nrczhl-7 0}.lst-kix_zcvcgbx5ju56-7>li:before{content:"- "}ol.lst-kix_8mkn8rg9im4a-5{list-style-type:none}ol.lst-kix_8mkn8rg9im4a-4{list-style-type:none}ul.lst-kix_t1ae57uxlfl0-3{list-style-type:none}ul.lst-kix_t1ae57uxlfl0-4{list-style-type:none}ol.lst-kix_hk8k8itxmlfp-6.start{counter-reset:lst-ctn-kix_hk8k8itxmlfp-6 0}ol.lst-kix_8mkn8rg9im4a-1{list-style-type:none}ul.lst-kix_t1ae57uxlfl0-1{list-style-type:none}.lst-kix_h1p96gz9lzq4-7>li:before{content:"- "}ol.lst-kix_8mkn8rg9im4a-0{list-style-type:none}ul.lst-kix_t1ae57uxlfl0-2{list-style-type:none}.lst-kix_yzib59bcdnhj-5>li:before{content:"- "}ul.lst-kix_t1ae57uxlfl0-0{list-style-type:none}.lst-kix_h1p96gz9lzq4-5>li:before{content:"- "}ul.lst-kix_t1ae57uxlfl0-7{list-style-type:none}.lst-kix_9prd8pa3o8y7-5>li:before{content:"" counter(lst-ctn-kix_9prd8pa3o8y7-5,lower-roman) ". "}ul.lst-kix_t1ae57uxlfl0-8{list-style-type:none}.lst-kix_yzib59bcdnhj-7>li:before{content:"- "}.lst-kix_51hgl6mwb3et-4>li{counter-increment:lst-ctn-kix_51hgl6mwb3et-4}.lst-kix_p4ttii5g8cnl-4>li{counter-increment:lst-ctn-kix_p4ttii5g8cnl-4}ul.lst-kix_t1ae57uxlfl0-5{list-style-type:none}ul.lst-kix_t1ae57uxlfl0-6{list-style-type:none}.lst-kix_7y90gfloiotx-0>li{counter-increment:lst-ctn-kix_7y90gfloiotx-0}.lst-kix_5yi4tofw6s0z-0>li:before{content:"" counter(lst-ctn-kix_5yi4tofw6s0z-0,decimal) ". "}ol.lst-kix_hk8k8itxmlfp-2.start{counter-reset:lst-ctn-kix_hk8k8itxmlfp-2 0}.lst-kix_u3opzkdcnklc-6>li:before{content:"" counter(lst-ctn-kix_u3opzkdcnklc-6,decimal) ". "}.lst-kix_f96hgc2s4b68-6>li:before{content:"- "}.lst-kix_f96hgc2s4b68-3>li:before{content:"- "}.lst-kix_51hgl6mwb3et-8>li{counter-increment:lst-ctn-kix_51hgl6mwb3et-8}ol.lst-kix_8mkn8rg9im4a-4.start{counter-reset:lst-ctn-kix_8mkn8rg9im4a-4 0}ol.lst-kix_58ja23nrczhl-2.start{counter-reset:lst-ctn-kix_58ja23nrczhl-2 0}.lst-kix_5yi4tofw6s0z-8>li:before{content:"" counter(lst-ctn-kix_5yi4tofw6s0z-8,lower-roman) ". "}ol.lst-kix_3a2g7o19wgb3-4.start{counter-reset:lst-ctn-kix_3a2g7o19wgb3-4 0}ol.lst-kix_7y90gfloiotx-5.start{counter-reset:lst-ctn-kix_7y90gfloiotx-5 0}.lst-kix_5yi4tofw6s0z-3>li:before{content:"" counter(lst-ctn-kix_5yi4tofw6s0z-3,decimal) ". "}.lst-kix_u3opzkdcnklc-1>li:before{content:"" counter(lst-ctn-kix_u3opzkdcnklc-1,lower-latin) ". "}.lst-kix_u3opzkdcnklc-0>li{counter-increment:lst-ctn-kix_u3opzkdcnklc-0}ol.lst-kix_hk8k8itxmlfp-3.start{counter-reset:lst-ctn-kix_hk8k8itxmlfp-3 0}ol.lst-kix_p4ttii5g8cnl-8{list-style-type:none}.lst-kix_7y90gfloiotx-4>li{counter-increment:lst-ctn-kix_7y90gfloiotx-4}.lst-kix_t1ae57uxlfl0-6>li:before{content:"- "}.lst-kix_u3opzkdcnklc-7>li{counter-increment:lst-ctn-kix_u3opzkdcnklc-7}ol.lst-kix_3a2g7o19wgb3-5.start{counter-reset:lst-ctn-kix_3a2g7o19wgb3-5 0}.lst-kix_j5vmamheymgq-5>li{counter-increment:lst-ctn-kix_j5vmamheymgq-5}.lst-kix_j5vmamheymgq-2>li{counter-increment:lst-ctn-kix_j5vmamheymgq-2}.lst-kix_t1ae57uxlfl0-1>li:before{content:"- "}ol.lst-kix_58ja23nrczhl-3.start{counter-reset:lst-ctn-kix_58ja23nrczhl-3 0}ol.lst-kix_7y90gfloiotx-1.start{counter-reset:lst-ctn-kix_7y90gfloiotx-1 0}.lst-kix_p4ttii5g8cnl-8>li{counter-increment:lst-ctn-kix_p4ttii5g8cnl-8}.lst-kix_g3pd9wzbzpzz-1>li:before{content:"- "}.lst-kix_aj3gpabmyk88-3>li:before{content:"- "}ol.lst-kix_58ja23nrczhl-0.start{counter-reset:lst-ctn-kix_58ja23nrczhl-0 0}.lst-kix_dqkfvt9lb2wy-3>li:before{content:"- "}ol.lst-kix_8mkn8rg9im4a-5.start{counter-reset:lst-ctn-kix_8mkn8rg9im4a-5 0}.lst-kix_6l3lpr6ytz51-1>li:before{content:"- "}.lst-kix_yjo4cwnqbjp0-3>li:before{content:"- "}.lst-kix_k47gmg94hbw2-8>li:before{content:"- "}.lst-kix_8mkn8rg9im4a-1>li{counter-increment:lst-ctn-kix_8mkn8rg9im4a-1}.lst-kix_whw4pjgxp3w1-3>li:before{content:"- "}ol.lst-kix_p4ttii5g8cnl-3{list-style-type:none}ol.lst-kix_p4ttii5g8cnl-2{list-style-type:none}ol.lst-kix_p4ttii5g8cnl-1{list-style-type:none}.lst-kix_k47gmg94hbw2-0>li:before{content:"- "}ol.lst-kix_p4ttii5g8cnl-0{list-style-type:none}ol.lst-kix_3a2g7o19wgb3-0.start{counter-reset:lst-ctn-kix_3a2g7o19wgb3-0 0}.lst-kix_5oipgjcxugcr-0>li:before{content:"" counter(lst-ctn-kix_5oipgjcxugcr-0,decimal) ". "}ol.lst-kix_p4ttii5g8cnl-7{list-style-type:none}ol.lst-kix_p4ttii5g8cnl-6{list-style-type:none}ol.lst-kix_hk8k8itxmlfp-1.start{counter-reset:lst-ctn-kix_hk8k8itxmlfp-1 0}ol.lst-kix_p4ttii5g8cnl-5{list-style-type:none}ol.lst-kix_p4ttii5g8cnl-4{list-style-type:none}.lst-kix_mfudkcwv2w89-4>li:before{content:"" counter(lst-ctn-kix_mfudkcwv2w89-4,lower-latin) ". "}.lst-kix_5yi4tofw6s0z-7>li{counter-increment:lst-ctn-kix_5yi4tofw6s0z-7}.lst-kix_yn2ql2u2egdg-6>li:before{content:"- "}.lst-kix_8mkn8rg9im4a-8>li{counter-increment:lst-ctn-kix_8mkn8rg9im4a-8}ol.lst-kix_j5vmamheymgq-6{list-style-type:none}ol.lst-kix_3a2g7o19wgb3-3.start{counter-reset:lst-ctn-kix_3a2g7o19wgb3-3 0}ol.lst-kix_j5vmamheymgq-7{list-style-type:none}ol.lst-kix_j5vmamheymgq-8{list-style-type:none}.lst-kix_9gryrzygx46m-4>li:before{content:"- "}ol.lst-kix_8mkn8rg9im4a-3.start{counter-reset:lst-ctn-kix_8mkn8rg9im4a-3 0}.lst-kix_5oipgjcxugcr-8>li:before{content:"" counter(lst-ctn-kix_5oipgjcxugcr-8,lower-roman) ". "}ol.lst-kix_j5vmamheymgq-0{list-style-type:none}ol.lst-kix_j5vmamheymgq-1{list-style-type:none}ol.lst-kix_j5vmamheymgq-2{list-style-type:none}ol.lst-kix_j5vmamheymgq-3{list-style-type:none}.lst-kix_3a2g7o19wgb3-5>li:before{content:"" counter(lst-ctn-kix_3a2g7o19wgb3-5,lower-roman) ". "}ol.lst-kix_j5vmamheymgq-4{list-style-type:none}ol.lst-kix_j5vmamheymgq-5{list-style-type:none}ol.lst-kix_hk8k8itxmlfp-0.start{counter-reset:lst-ctn-kix_hk8k8itxmlfp-0 0}.lst-kix_yzib59bcdnhj-2>li:before{content:"- "}.lst-kix_3a2g7o19wgb3-3>li{counter-increment:lst-ctn-kix_3a2g7o19wgb3-3}.lst-kix_8chkxhfzc2ds-2>li:before{content:"- "}.lst-kix_mfudkcwv2w89-2>li{counter-increment:lst-ctn-kix_mfudkcwv2w89-2}.lst-kix_1m9wqzg4mvqt-1>li:before{content:"- "}ol.lst-kix_8mkn8rg9im4a-2.start{counter-reset:lst-ctn-kix_8mkn8rg9im4a-2 0}.lst-kix_5oipgjcxugcr-5>li{counter-increment:lst-ctn-kix_5oipgjcxugcr-5}.lst-kix_j5vmamheymgq-6>li:before{content:"" counter(lst-ctn-kix_j5vmamheymgq-6,decimal) ". "}ul.lst-kix_8chkxhfzc2ds-4{list-style-type:none}.lst-kix_9prd8pa3o8y7-0>li:before{content:"" counter(lst-ctn-kix_9prd8pa3o8y7-0,decimal) ". "}.lst-kix_9prd8pa3o8y7-8>li:before{content:"" counter(lst-ctn-kix_9prd8pa3o8y7-8,lower-roman) ". "}ul.lst-kix_8chkxhfzc2ds-3{list-style-type:none}ul.lst-kix_8chkxhfzc2ds-2{list-style-type:none}ul.lst-kix_8chkxhfzc2ds-1{list-style-type:none}.lst-kix_h1p96gz9lzq4-2>li:before{content:"- "}ul.lst-kix_8chkxhfzc2ds-8{list-style-type:none}ul.lst-kix_8chkxhfzc2ds-7{list-style-type:none}li.li-bullet-0:before{margin-left:-18pt;white-space:nowrap;display:inline-block;min-width:18pt}ul.lst-kix_8chkxhfzc2ds-6{list-style-type:none}.lst-kix_5yi4tofw6s0z-0>li{counter-increment:lst-ctn-kix_5yi4tofw6s0z-0}ul.lst-kix_8chkxhfzc2ds-5{list-style-type:none}.lst-kix_51hgl6mwb3et-1>li{counter-increment:lst-ctn-kix_51hgl6mwb3et-1}.lst-kix_p4ttii5g8cnl-1>li{counter-increment:lst-ctn-kix_p4ttii5g8cnl-1}.lst-kix_7y90gfloiotx-2>li:before{content:"" counter(lst-ctn-kix_7y90gfloiotx-2,lower-roman) ". "}ul.lst-kix_8chkxhfzc2ds-0{list-style-type:none}ol.lst-kix_58ja23nrczhl-1.start{counter-reset:lst-ctn-kix_58ja23nrczhl-1 0}.lst-kix_8mkn8rg9im4a-5>li:before{content:"" counter(lst-ctn-kix_8mkn8rg9im4a-5,lower-roman) ". "}ol.lst-kix_7y90gfloiotx-0.start{counter-reset:lst-ctn-kix_7y90gfloiotx-0 0}ol.lst-kix_3a2g7o19wgb3-2.start{counter-reset:lst-ctn-kix_3a2g7o19wgb3-2 0}.lst-kix_zcvcgbx5ju56-4>li:before{content:"- "}.lst-kix_p4ttii5g8cnl-2>li{counter-increment:lst-ctn-kix_p4ttii5g8cnl-2}ol.lst-kix_hk8k8itxmlfp-5.start{counter-reset:lst-ctn-kix_hk8k8itxmlfp-5 0}.lst-kix_5oipgjcxugcr-4>li{counter-increment:lst-ctn-kix_5oipgjcxugcr-4}.lst-kix_9prd8pa3o8y7-2>li{counter-increment:lst-ctn-kix_9prd8pa3o8y7-2}ol.lst-kix_3a2g7o19wgb3-6{list-style-type:none}ol.lst-kix_3a2g7o19wgb3-5{list-style-type:none}ol.lst-kix_3a2g7o19wgb3-4{list-style-type:none}ol.lst-kix_3a2g7o19wgb3-3{list-style-type:none}ol.lst-kix_3a2g7o19wgb3-8{list-style-type:none}ol.lst-kix_3a2g7o19wgb3-7{list-style-type:none}ol.lst-kix_3a2g7o19wgb3-7.start{counter-reset:lst-ctn-kix_3a2g7o19wgb3-7 0}ol.lst-kix_p4ttii5g8cnl-4.start{counter-reset:lst-ctn-kix_p4ttii5g8cnl-4 0}.lst-kix_iptxq54yrrnf-8>li{counter-increment:lst-ctn-kix_iptxq54yrrnf-8}.lst-kix_5yi4tofw6s0z-5>li{counter-increment:lst-ctn-kix_5yi4tofw6s0z-5}.lst-kix_58ja23nrczhl-0>li{counter-increment:lst-ctn-kix_58ja23nrczhl-0}ol.lst-kix_8mkn8rg9im4a-7.start{counter-reset:lst-ctn-kix_8mkn8rg9im4a-7 0}.lst-kix_hk8k8itxmlfp-8>li{counter-increment:lst-ctn-kix_hk8k8itxmlfp-8}ul.lst-kix_zcvcgbx5ju56-1{list-style-type:none}ul.lst-kix_zcvcgbx5ju56-2{list-style-type:none}ul.lst-kix_zcvcgbx5ju56-0{list-style-type:none}ul.lst-kix_zcvcgbx5ju56-5{list-style-type:none}.lst-kix_8mkn8rg9im4a-6>li{counter-increment:lst-ctn-kix_8mkn8rg9im4a-6}ul.lst-kix_zcvcgbx5ju56-6{list-style-type:none}ul.lst-kix_zcvcgbx5ju56-3{list-style-type:none}ul.lst-kix_zcvcgbx5ju56-4{list-style-type:none}ol.lst-kix_5yi4tofw6s0z-7.start{counter-reset:lst-ctn-kix_5yi4tofw6s0z-7 0}.lst-kix_aj3gpabmyk88-8>li:before{content:"- "}ol.lst-kix_5oipgjcxugcr-6.start{counter-reset:lst-ctn-kix_5oipgjcxugcr-6 0}.lst-kix_aj3gpabmyk88-4>li:before{content:"- "}.lst-kix_mfudkcwv2w89-6>li{counter-increment:lst-ctn-kix_mfudkcwv2w89-6}.lst-kix_aj3gpabmyk88-2>li:before{content:"- "}.lst-kix_8mkn8rg9im4a-8>li:before{content:"" counter(lst-ctn-kix_8mkn8rg9im4a-8,lower-roman) ". "}.lst-kix_1m9wqzg4mvqt-8>li:before{content:"- "}.lst-kix_aj3gpabmyk88-0>li:before{content:"- "}.lst-kix_mfudkcwv2w89-5>li{counter-increment:lst-ctn-kix_mfudkcwv2w89-5}ol.lst-kix_51hgl6mwb3et-8{list-style-type:none}.lst-kix_hk8k8itxmlfp-0>li{counter-increment:lst-ctn-kix_hk8k8itxmlfp-0}.lst-kix_iptxq54yrrnf-0>li{counter-increment:lst-ctn-kix_iptxq54yrrnf-0}.lst-kix_51hgl6mwb3et-5>li{counter-increment:lst-ctn-kix_51hgl6mwb3et-5}ol.lst-kix_58ja23nrczhl-6.start{counter-reset:lst-ctn-kix_58ja23nrczhl-6 0}ol.lst-kix_j5vmamheymgq-1.start{counter-reset:lst-ctn-kix_j5vmamheymgq-1 0}ol.lst-kix_51hgl6mwb3et-6{list-style-type:none}ol.lst-kix_51hgl6mwb3et-7{list-style-type:none}ol.lst-kix_51hgl6mwb3et-4{list-style-type:none}ol.lst-kix_51hgl6mwb3et-5{list-style-type:none}ol.lst-kix_51hgl6mwb3et-2{list-style-type:none}ol.lst-kix_51hgl6mwb3et-3{list-style-type:none}ol.lst-kix_51hgl6mwb3et-0{list-style-type:none}ol.lst-kix_51hgl6mwb3et-1{list-style-type:none}.lst-kix_hk8k8itxmlfp-7>li{counter-increment:lst-ctn-kix_hk8k8itxmlfp-7}ol.lst-kix_7y90gfloiotx-6.start{counter-reset:lst-ctn-kix_7y90gfloiotx-6 0}.lst-kix_iptxq54yrrnf-7>li{counter-increment:lst-ctn-kix_iptxq54yrrnf-7}.lst-kix_iptxq54yrrnf-1>li{counter-increment:lst-ctn-kix_iptxq54yrrnf-1}ol.lst-kix_3a2g7o19wgb3-2{list-style-type:none}.lst-kix_hk8k8itxmlfp-1>li{counter-increment:lst-ctn-kix_hk8k8itxmlfp-1}ol.lst-kix_3a2g7o19wgb3-1{list-style-type:none}ol.lst-kix_3a2g7o19wgb3-0{list-style-type:none}.lst-kix_1m9wqzg4mvqt-0>li:before{content:"- "}.lst-kix_8mkn8rg9im4a-0>li:before{content:"" counter(lst-ctn-kix_8mkn8rg9im4a-0,decimal) ". "}.lst-kix_1m9wqzg4mvqt-4>li:before{content:"- "}.lst-kix_8mkn8rg9im4a-2>li:before{content:"" counter(lst-ctn-kix_8mkn8rg9im4a-2,lower-roman) ". "}ol.lst-kix_mfudkcwv2w89-5.start{counter-reset:lst-ctn-kix_mfudkcwv2w89-5 0}.lst-kix_1m9wqzg4mvqt-6>li:before{content:"- "}.lst-kix_7y90gfloiotx-7>li:before{content:"" counter(lst-ctn-kix_7y90gfloiotx-7,lower-latin) ". "}.lst-kix_3a2g7o19wgb3-6>li{counter-increment:lst-ctn-kix_3a2g7o19wgb3-6}.lst-kix_8mkn8rg9im4a-6>li:before{content:"" counter(lst-ctn-kix_8mkn8rg9im4a-6,decimal) ". "}.lst-kix_7y90gfloiotx-1>li:before{content:"" counter(lst-ctn-kix_7y90gfloiotx-1,lower-latin) ". "}.lst-kix_7y90gfloiotx-5>li:before{content:"" counter(lst-ctn-kix_7y90gfloiotx-5,lower-roman) ". "}.lst-kix_8mkn8rg9im4a-4>li:before{content:"" counter(lst-ctn-kix_8mkn8rg9im4a-4,lower-latin) ". "}.lst-kix_1m9wqzg4mvqt-2>li:before{content:"- "}.lst-kix_aj3gpabmyk88-6>li:before{content:"- "}.lst-kix_7y90gfloiotx-3>li:before{content:"" counter(lst-ctn-kix_7y90gfloiotx-3,decimal) ". "}ul.lst-kix_6l3lpr6ytz51-8{list-style-type:none}.lst-kix_8mkn8rg9im4a-5>li{counter-increment:lst-ctn-kix_8mkn8rg9im4a-5}ol.lst-kix_mfudkcwv2w89-4.start{counter-reset:lst-ctn-kix_mfudkcwv2w89-4 0}ul.lst-kix_6l3lpr6ytz51-7{list-style-type:none}ul.lst-kix_6l3lpr6ytz51-4{list-style-type:none}ol.lst-kix_u3opzkdcnklc-6.start{counter-reset:lst-ctn-kix_u3opzkdcnklc-6 0}ul.lst-kix_6l3lpr6ytz51-3{list-style-type:none}ul.lst-kix_6l3lpr6ytz51-6{list-style-type:none}ul.lst-kix_6l3lpr6ytz51-5{list-style-type:none}ul.lst-kix_6l3lpr6ytz51-0{list-style-type:none}ul.lst-kix_6l3lpr6ytz51-2{list-style-type:none}ol.lst-kix_u3opzkdcnklc-8{list-style-type:none}ul.lst-kix_6l3lpr6ytz51-1{list-style-type:none}ol.lst-kix_u3opzkdcnklc-7{list-style-type:none}ol.lst-kix_u3opzkdcnklc-6{list-style-type:none}ol.lst-kix_u3opzkdcnklc-5{list-style-type:none}ol.lst-kix_u3opzkdcnklc-4{list-style-type:none}ol.lst-kix_9prd8pa3o8y7-0.start{counter-reset:lst-ctn-kix_9prd8pa3o8y7-0 0}ol.lst-kix_j5vmamheymgq-2.start{counter-reset:lst-ctn-kix_j5vmamheymgq-2 0}ol.lst-kix_iptxq54yrrnf-6.start{counter-reset:lst-ctn-kix_iptxq54yrrnf-6 0}.lst-kix_3a2g7o19wgb3-0>li{counter-increment:lst-ctn-kix_3a2g7o19wgb3-0}.lst-kix_f96hgc2s4b68-1>li:before{content:"- "}.lst-kix_f96hgc2s4b68-0>li:before{content:"- "}.lst-kix_f96hgc2s4b68-5>li:before{content:"- "}.lst-kix_f96hgc2s4b68-4>li:before{content:"- "}.lst-kix_5yi4tofw6s0z-6>li:before{content:"" counter(lst-ctn-kix_5yi4tofw6s0z-6,decimal) ". "}.lst-kix_9prd8pa3o8y7-3>li{counter-increment:lst-ctn-kix_9prd8pa3o8y7-3}ul.lst-kix_yjo4cwnqbjp0-8{list-style-type:none}.lst-kix_5yi4tofw6s0z-1>li:before{content:"" counter(lst-ctn-kix_5yi4tofw6s0z-1,lower-latin) ". "}.lst-kix_5yi4tofw6s0z-2>li:before{content:"" counter(lst-ctn-kix_5yi4tofw6s0z-2,lower-roman) ". "}ul.lst-kix_yjo4cwnqbjp0-4{list-style-type:none}ul.lst-kix_yjo4cwnqbjp0-5{list-style-type:none}ul.lst-kix_yjo4cwnqbjp0-6{list-style-type:none}ul.lst-kix_yjo4cwnqbjp0-7{list-style-type:none}ul.lst-kix_yjo4cwnqbjp0-0{list-style-type:none}.lst-kix_5yi4tofw6s0z-5>li:before{content:"" counter(lst-ctn-kix_5yi4tofw6s0z-5,lower-roman) ". "}ul.lst-kix_yjo4cwnqbjp0-1{list-style-type:none}.lst-kix_8mkn8rg9im4a-7>li{counter-increment:lst-ctn-kix_8mkn8rg9im4a-7}ul.lst-kix_yjo4cwnqbjp0-2{list-style-type:none}.lst-kix_f96hgc2s4b68-8>li:before{content:"- "}ul.lst-kix_yjo4cwnqbjp0-3{list-style-type:none}ol.lst-kix_iptxq54yrrnf-0.start{counter-reset:lst-ctn-kix_iptxq54yrrnf-0 0}ol.lst-kix_51hgl6mwb3et-5.start{counter-reset:lst-ctn-kix_51hgl6mwb3et-5 0}.lst-kix_58ja23nrczhl-1>li{counter-increment:lst-ctn-kix_58ja23nrczhl-1}.lst-kix_5yi4tofw6s0z-4>li{counter-increment:lst-ctn-kix_5yi4tofw6s0z-4}ol.lst-kix_u3opzkdcnklc-1.start{counter-reset:lst-ctn-kix_u3opzkdcnklc-1 0}.lst-kix_u3opzkdcnklc-4>li{counter-increment:lst-ctn-kix_u3opzkdcnklc-4}ol.lst-kix_iptxq54yrrnf-1.start{counter-reset:lst-ctn-kix_iptxq54yrrnf-1 0}ol.lst-kix_51hgl6mwb3et-4.start{counter-reset:lst-ctn-kix_51hgl6mwb3et-4 0}ol.lst-kix_9prd8pa3o8y7-5.start{counter-reset:lst-ctn-kix_9prd8pa3o8y7-5 0}.lst-kix_3a2g7o19wgb3-7>li{counter-increment:lst-ctn-kix_3a2g7o19wgb3-7}.lst-kix_t1ae57uxlfl0-8>li:before{content:"- "}.lst-kix_t1ae57uxlfl0-3>li:before{content:"- "}.lst-kix_t1ae57uxlfl0-7>li:before{content:"- "}.lst-kix_t1ae57uxlfl0-4>li:before{content:"- "}ol.lst-kix_u3opzkdcnklc-3{list-style-type:none}ol.lst-kix_u3opzkdcnklc-2{list-style-type:none}ol.lst-kix_u3opzkdcnklc-1{list-style-type:none}.lst-kix_9prd8pa3o8y7-1>li{counter-increment:lst-ctn-kix_9prd8pa3o8y7-1}ol.lst-kix_u3opzkdcnklc-0{list-style-type:none}.lst-kix_t1ae57uxlfl0-0>li:before{content:"- "}ol.lst-kix_u3opzkdcnklc-0.start{counter-reset:lst-ctn-kix_u3opzkdcnklc-0 0}.lst-kix_58ja23nrczhl-8>li{counter-increment:lst-ctn-kix_58ja23nrczhl-8}.lst-kix_9prd8pa3o8y7-8>li{counter-increment:lst-ctn-kix_9prd8pa3o8y7-8}.lst-kix_7y90gfloiotx-0>li:before{content:"" counter(lst-ctn-kix_7y90gfloiotx-0,decimal) ". "}.lst-kix_1m9wqzg4mvqt-7>li:before{content:"- "}.lst-kix_aj3gpabmyk88-1>li:before{content:"- "}.lst-kix_58ja23nrczhl-8>li:before{content:"" counter(lst-ctn-kix_58ja23nrczhl-8,lower-roman) ". "}ol.lst-kix_9prd8pa3o8y7-4.start{counter-reset:lst-ctn-kix_9prd8pa3o8y7-4 0}.lst-kix_k47gmg94hbw2-6>li:before{content:"- "}ol.lst-kix_mfudkcwv2w89-0.start{counter-reset:lst-ctn-kix_mfudkcwv2w89-0 0}.lst-kix_j5vmamheymgq-6>li{counter-increment:lst-ctn-kix_j5vmamheymgq-6}.lst-kix_k47gmg94hbw2-2>li:before{content:"- "}.lst-kix_u3opzkdcnklc-6>li{counter-increment:lst-ctn-kix_u3opzkdcnklc-6}ol.lst-kix_u3opzkdcnklc-5.start{counter-reset:lst-ctn-kix_u3opzkdcnklc-5 0}ol.lst-kix_51hgl6mwb3et-0.start{counter-reset:lst-ctn-kix_51hgl6mwb3et-0 0}.lst-kix_9gryrzygx46m-6>li:before{content:"- "}.lst-kix_7y90gfloiotx-3>li{counter-increment:lst-ctn-kix_7y90gfloiotx-3}ol.lst-kix_j5vmamheymgq-7.start{counter-reset:lst-ctn-kix_j5vmamheymgq-7 0}.lst-kix_9gryrzygx46m-2>li:before{content:"- "}.lst-kix_zcvcgbx5ju56-2>li:before{content:"- "}.lst-kix_5yi4tofw6s0z-6>li{counter-increment:lst-ctn-kix_5yi4tofw6s0z-6}.lst-kix_zcvcgbx5ju56-6>li:before{content:"- "}.lst-kix_7y90gfloiotx-8>li:before{content:"" counter(lst-ctn-kix_7y90gfloiotx-8,lower-roman) ". "}.lst-kix_8mkn8rg9im4a-7>li:before{content:"" counter(lst-ctn-kix_8mkn8rg9im4a-7,lower-latin) ". "}.lst-kix_7y90gfloiotx-4>li:before{content:"" counter(lst-ctn-kix_7y90gfloiotx-4,lower-latin) ". "}.lst-kix_51hgl6mwb3et-7>li{counter-increment:lst-ctn-kix_51hgl6mwb3et-7}ol.lst-kix_p4ttii5g8cnl-0.start{counter-reset:lst-ctn-kix_p4ttii5g8cnl-0 0}.lst-kix_8mkn8rg9im4a-3>li:before{content:"" counter(lst-ctn-kix_8mkn8rg9im4a-3,decimal) ". "}.lst-kix_1m9wqzg4mvqt-3>li:before{content:"- "}ol.lst-kix_iptxq54yrrnf-5.start{counter-reset:lst-ctn-kix_iptxq54yrrnf-5 0}.lst-kix_aj3gpabmyk88-5>li:before{content:"- "}ol.lst-kix_j5vmamheymgq-6.start{counter-reset:lst-ctn-kix_j5vmamheymgq-6 0}ol.lst-kix_9prd8pa3o8y7-3.start{counter-reset:lst-ctn-kix_9prd8pa3o8y7-3 0}ol.lst-kix_hk8k8itxmlfp-2{list-style-type:none}ol.lst-kix_hk8k8itxmlfp-1{list-style-type:none}ol.lst-kix_hk8k8itxmlfp-0{list-style-type:none}ol.lst-kix_hk8k8itxmlfp-8{list-style-type:none}ol.lst-kix_hk8k8itxmlfp-7{list-style-type:none}ol.lst-kix_hk8k8itxmlfp-6{list-style-type:none}ol.lst-kix_hk8k8itxmlfp-5{list-style-type:none}ol.lst-kix_hk8k8itxmlfp-4{list-style-type:none}ol.lst-kix_hk8k8itxmlfp-3{list-style-type:none}ul.lst-kix_k47gmg94hbw2-6{list-style-type:none}ul.lst-kix_k47gmg94hbw2-7{list-style-type:none}ul.lst-kix_k47gmg94hbw2-8{list-style-type:none}.lst-kix_9prd8pa3o8y7-0>li{counter-increment:lst-ctn-kix_9prd8pa3o8y7-0}ol.lst-kix_j5vmamheymgq-5.start{counter-reset:lst-ctn-kix_j5vmamheymgq-5 0}ol.lst-kix_5yi4tofw6s0z-3.start{counter-reset:lst-ctn-kix_5yi4tofw6s0z-3 0}ul.lst-kix_k47gmg94hbw2-0{list-style-type:none}ul.lst-kix_k47gmg94hbw2-1{list-style-type:none}ul.lst-kix_k47gmg94hbw2-2{list-style-type:none}ul.lst-kix_yzib59bcdnhj-8{list-style-type:none}ul.lst-kix_k47gmg94hbw2-3{list-style-type:none}ul.lst-kix_yzib59bcdnhj-7{list-style-type:none}ul.lst-kix_k47gmg94hbw2-4{list-style-type:none}ul.lst-kix_yzib59bcdnhj-6{list-style-type:none}ul.lst-kix_k47gmg94hbw2-5{list-style-type:none}.lst-kix_p4ttii5g8cnl-0>li{counter-increment:lst-ctn-kix_p4ttii5g8cnl-0}ul.lst-kix_yzib59bcdnhj-5{list-style-type:none}.lst-kix_iptxq54yrrnf-3>li:before{content:"" counter(lst-ctn-kix_iptxq54yrrnf-3,decimal) ". "}ul.lst-kix_yzib59bcdnhj-4{list-style-type:none}ul.lst-kix_yzib59bcdnhj-3{list-style-type:none}ul.lst-kix_yzib59bcdnhj-2{list-style-type:none}ul.lst-kix_yzib59bcdnhj-1{list-style-type:none}.lst-kix_iptxq54yrrnf-1>li:before{content:"" counter(lst-ctn-kix_iptxq54yrrnf-1,lower-latin) ". "}ul.lst-kix_yzib59bcdnhj-0{list-style-type:none}.lst-kix_iptxq54yrrnf-0>li:before{content:"" counter(lst-ctn-kix_iptxq54yrrnf-0,decimal) ". "}ol.lst-kix_5oipgjcxugcr-2.start{counter-reset:lst-ctn-kix_5oipgjcxugcr-2 0}.lst-kix_mfudkcwv2w89-0>li{counter-increment:lst-ctn-kix_mfudkcwv2w89-0}.lst-kix_hk8k8itxmlfp-6>li{counter-increment:lst-ctn-kix_hk8k8itxmlfp-6}.lst-kix_p4ttii5g8cnl-1>li:before{content:"" counter(lst-ctn-kix_p4ttii5g8cnl-1,lower-latin) ". "}.lst-kix_p4ttii5g8cnl-2>li:before{content:"" counter(lst-ctn-kix_p4ttii5g8cnl-2,lower-roman) ". "}.lst-kix_3a2g7o19wgb3-8>li{counter-increment:lst-ctn-kix_3a2g7o19wgb3-8}.lst-kix_5oipgjcxugcr-6>li{counter-increment:lst-ctn-kix_5oipgjcxugcr-6}.lst-kix_p4ttii5g8cnl-4>li:before{content:"" counter(lst-ctn-kix_p4ttii5g8cnl-4,lower-latin) ". "}.lst-kix_mfudkcwv2w89-4>li{counter-increment:lst-ctn-kix_mfudkcwv2w89-4}.lst-kix_51hgl6mwb3et-0>li{counter-increment:lst-ctn-kix_51hgl6mwb3et-0}.lst-kix_hk8k8itxmlfp-2>li{counter-increment:lst-ctn-kix_hk8k8itxmlfp-2}.lst-kix_3a2g7o19wgb3-1>li{counter-increment:lst-ctn-kix_3a2g7o19wgb3-1}.lst-kix_58ja23nrczhl-0>li:before{content:"" counter(lst-ctn-kix_58ja23nrczhl-0,decimal) ". "}ul.lst-kix_g3pd9wzbzpzz-0{list-style-type:none}ol.lst-kix_iptxq54yrrnf-2.start{counter-reset:lst-ctn-kix_iptxq54yrrnf-2 0}ol.lst-kix_mfudkcwv2w89-8.start{counter-reset:lst-ctn-kix_mfudkcwv2w89-8 0}ul.lst-kix_g3pd9wzbzpzz-4{list-style-type:none}ul.lst-kix_g3pd9wzbzpzz-3{list-style-type:none}ul.lst-kix_g3pd9wzbzpzz-2{list-style-type:none}ul.lst-kix_g3pd9wzbzpzz-1{list-style-type:none}.lst-kix_8mkn8rg9im4a-0>li{counter-increment:lst-ctn-kix_8mkn8rg9im4a-0}.lst-kix_p4ttii5g8cnl-7>li:before{content:"" counter(lst-ctn-kix_p4ttii5g8cnl-7,lower-latin) ". "}.lst-kix_58ja23nrczhl-3>li:before{content:"" counter(lst-ctn-kix_58ja23nrczhl-3,decimal) ". "}.lst-kix_mfudkcwv2w89-7>li{counter-increment:lst-ctn-kix_mfudkcwv2w89-7}.lst-kix_9prd8pa3o8y7-4>li{counter-increment:lst-ctn-kix_9prd8pa3o8y7-4}ol.lst-kix_mfudkcwv2w89-1.start{counter-reset:lst-ctn-kix_mfudkcwv2w89-1 0}.lst-kix_58ja23nrczhl-1>li:before{content:"" counter(lst-ctn-kix_58ja23nrczhl-1,lower-latin) ". "}.lst-kix_51hgl6mwb3et-3>li{counter-increment:lst-ctn-kix_51hgl6mwb3et-3}.lst-kix_g3pd9wzbzpzz-2>li:before{content:"- "}.lst-kix_g3pd9wzbzpzz-0>li:before{content:"- "}.lst-kix_g3pd9wzbzpzz-8>li:before{content:"- "}.lst-kix_dqkfvt9lb2wy-4>li:before{content:"- "}.lst-kix_j5vmamheymgq-4>li{counter-increment:lst-ctn-kix_j5vmamheymgq-4}ul.lst-kix_g3pd9wzbzpzz-8{list-style-type:none}.lst-kix_7y90gfloiotx-5>li{counter-increment:lst-ctn-kix_7y90gfloiotx-5}ul.lst-kix_g3pd9wzbzpzz-7{list-style-type:none}ul.lst-kix_g3pd9wzbzpzz-6{list-style-type:none}ul.lst-kix_g3pd9wzbzpzz-5{list-style-type:none}.lst-kix_dqkfvt9lb2wy-2>li:before{content:"- "}.lst-kix_yn2ql2u2egdg-7>li:before{content:"- "}ol.lst-kix_mfudkcwv2w89-3.start{counter-reset:lst-ctn-kix_mfudkcwv2w89-3 0}.lst-kix_mfudkcwv2w89-5>li:before{content:"" counter(lst-ctn-kix_mfudkcwv2w89-5,lower-roman) ". "}.lst-kix_k47gmg94hbw2-7>li:before{content:"- "}.lst-kix_mfudkcwv2w89-3>li:before{content:"" counter(lst-ctn-kix_mfudkcwv2w89-3,decimal) ". "}.lst-kix_k47gmg94hbw2-1>li:before{content:"- "}.lst-kix_3a2g7o19wgb3-5>li{counter-increment:lst-ctn-kix_3a2g7o19wgb3-5}.lst-kix_yn2ql2u2egdg-5>li:before{content:"- "}ol.lst-kix_mfudkcwv2w89-6.start{counter-reset:lst-ctn-kix_mfudkcwv2w89-6 0}.lst-kix_5oipgjcxugcr-7>li:before{content:"" counter(lst-ctn-kix_5oipgjcxugcr-7,lower-latin) ". "}.lst-kix_9gryrzygx46m-5>li:before{content:"- "}ol.lst-kix_9prd8pa3o8y7-8.start{counter-reset:lst-ctn-kix_9prd8pa3o8y7-8 0}.lst-kix_3a2g7o19wgb3-4>li:before{content:"" counter(lst-ctn-kix_3a2g7o19wgb3-4,lower-latin) ". "}.lst-kix_5oipgjcxugcr-1>li:before{content:"" counter(lst-ctn-kix_5oipgjcxugcr-1,lower-latin) ". "}.lst-kix_3a2g7o19wgb3-6>li:before{content:"" counter(lst-ctn-kix_3a2g7o19wgb3-6,decimal) ". "}.lst-kix_yzib59bcdnhj-3>li:before{content:"- "}.lst-kix_yzib59bcdnhj-1>li:before{content:"- "}.lst-kix_9gryrzygx46m-3>li:before{content:"- "}ul.lst-kix_whw4pjgxp3w1-7{list-style-type:none}ul.lst-kix_whw4pjgxp3w1-8{list-style-type:none}.lst-kix_h1p96gz9lzq4-1>li:before{content:"- "}ul.lst-kix_whw4pjgxp3w1-3{list-style-type:none}ul.lst-kix_whw4pjgxp3w1-4{list-style-type:none}ul.lst-kix_whw4pjgxp3w1-5{list-style-type:none}.lst-kix_u3opzkdcnklc-2>li{counter-increment:lst-ctn-kix_u3opzkdcnklc-2}ul.lst-kix_whw4pjgxp3w1-6{list-style-type:none}ol.lst-kix_j5vmamheymgq-0.start{counter-reset:lst-ctn-kix_j5vmamheymgq-0 0}.lst-kix_9prd8pa3o8y7-7>li:before{content:"" counter(lst-ctn-kix_9prd8pa3o8y7-7,lower-latin) ". "}ul.lst-kix_whw4pjgxp3w1-0{list-style-type:none}ul.lst-kix_whw4pjgxp3w1-1{list-style-type:none}.lst-kix_h1p96gz9lzq4-3>li:before{content:"- "}ul.lst-kix_whw4pjgxp3w1-2{list-style-type:none}.lst-kix_9prd8pa3o8y7-1>li:before{content:"" counter(lst-ctn-kix_9prd8pa3o8y7-1,lower-latin) ". "}ol.lst-kix_5yi4tofw6s0z-8.start{counter-reset:lst-ctn-kix_5yi4tofw6s0z-8 0}.lst-kix_zcvcgbx5ju56-5>li:before{content:"- "}.lst-kix_zcvcgbx5ju56-3>li:before{content:"- "}ol.lst-kix_5oipgjcxugcr-7.start{counter-reset:lst-ctn-kix_5oipgjcxugcr-7 0}ul.lst-kix_1m9wqzg4mvqt-0{list-style-type:none}ol.lst-kix_5yi4tofw6s0z-0.start{counter-reset:lst-ctn-kix_5yi4tofw6s0z-0 0}ol.lst-kix_mfudkcwv2w89-0{list-style-type:none}ol.lst-kix_mfudkcwv2w89-1{list-style-type:none}ul.lst-kix_1m9wqzg4mvqt-4{list-style-type:none}ul.lst-kix_1m9wqzg4mvqt-3{list-style-type:none}ul.lst-kix_1m9wqzg4mvqt-2{list-style-type:none}.lst-kix_5oipgjcxugcr-3>li{counter-increment:lst-ctn-kix_5oipgjcxugcr-3}ul.lst-kix_1m9wqzg4mvqt-1{list-style-type:none}.lst-kix_5yi4tofw6s0z-2>li{counter-increment:lst-ctn-kix_5yi4tofw6s0z-2}.lst-kix_j5vmamheymgq-0>li{counter-increment:lst-ctn-kix_j5vmamheymgq-0}.lst-kix_f96hgc2s4b68-2>li:before{content:"- "}.lst-kix_p4ttii5g8cnl-3>li{counter-increment:lst-ctn-kix_p4ttii5g8cnl-3}.lst-kix_f96hgc2s4b68-7>li:before{content:"- "}ol.lst-kix_5oipgjcxugcr-5.start{counter-reset:lst-ctn-kix_5oipgjcxugcr-5 0}.lst-kix_7y90gfloiotx-2>li{counter-increment:lst-ctn-kix_7y90gfloiotx-2}.lst-kix_5yi4tofw6s0z-7>li:before{content:"" counter(lst-ctn-kix_5yi4tofw6s0z-7,lower-latin) ". "}.lst-kix_u3opzkdcnklc-5>li:before{content:"" counter(lst-ctn-kix_u3opzkdcnklc-5,lower-roman) ". "}ol.lst-kix_5yi4tofw6s0z-6.start{counter-reset:lst-ctn-kix_5yi4tofw6s0z-6 0}.lst-kix_u3opzkdcnklc-2>li:before{content:"" counter(lst-ctn-kix_u3opzkdcnklc-2,lower-roman) ". "}.lst-kix_5yi4tofw6s0z-4>li:before{content:"" counter(lst-ctn-kix_5yi4tofw6s0z-4,lower-latin) ". "}.lst-kix_51hgl6mwb3et-6>li{counter-increment:lst-ctn-kix_51hgl6mwb3et-6}ol.lst-kix_5yi4tofw6s0z-5.start{counter-reset:lst-ctn-kix_5yi4tofw6s0z-5 0}.lst-kix_5oipgjcxugcr-7>li{counter-increment:lst-ctn-kix_5oipgjcxugcr-7}ul.lst-kix_dqkfvt9lb2wy-2{list-style-type:none}ul.lst-kix_dqkfvt9lb2wy-3{list-style-type:none}ul.lst-kix_dqkfvt9lb2wy-4{list-style-type:none}ul.lst-kix_dqkfvt9lb2wy-5{list-style-type:none}ol.lst-kix_iptxq54yrrnf-2{list-style-type:none}ol.lst-kix_iptxq54yrrnf-1{list-style-type:none}ol.lst-kix_iptxq54yrrnf-0{list-style-type:none}ul.lst-kix_dqkfvt9lb2wy-0{list-style-type:none}ul.lst-kix_dqkfvt9lb2wy-1{list-style-type:none}ol.lst-kix_iptxq54yrrnf-6{list-style-type:none}ol.lst-kix_iptxq54yrrnf-5{list-style-type:none}ol.lst-kix_iptxq54yrrnf-4{list-style-type:none}ol.lst-kix_iptxq54yrrnf-3{list-style-type:none}ol.lst-kix_iptxq54yrrnf-8{list-style-type:none}ol.lst-kix_iptxq54yrrnf-7{list-style-type:none}.lst-kix_t1ae57uxlfl0-5>li:before{content:"- "}ul.lst-kix_1m9wqzg4mvqt-8{list-style-type:none}ul.lst-kix_1m9wqzg4mvqt-7{list-style-type:none}ul.lst-kix_1m9wqzg4mvqt-6{list-style-type:none}ul.lst-kix_1m9wqzg4mvqt-5{list-style-type:none}.lst-kix_9prd8pa3o8y7-7>li{counter-increment:lst-ctn-kix_9prd8pa3o8y7-7}.lst-kix_8mkn8rg9im4a-3>li{counter-increment:lst-ctn-kix_8mkn8rg9im4a-3}ol.lst-kix_5oipgjcxugcr-4.start{counter-reset:lst-ctn-kix_5oipgjcxugcr-4 0}.lst-kix_t1ae57uxlfl0-2>li:before{content:"- "}ul.lst-kix_dqkfvt9lb2wy-6{list-style-type:none}ul.lst-kix_dqkfvt9lb2wy-7{list-style-type:none}ul.lst-kix_dqkfvt9lb2wy-8{list-style-type:none}.lst-kix_g3pd9wzbzpzz-5>li:before{content:"- "}.lst-kix_aj3gpabmyk88-7>li:before{content:"- "}ol.lst-kix_5oipgjcxugcr-4{list-style-type:none}ol.lst-kix_5oipgjcxugcr-3{list-style-type:none}.lst-kix_58ja23nrczhl-6>li:before{content:"" counter(lst-ctn-kix_58ja23nrczhl-6,decimal) ". "}ol.lst-kix_5oipgjcxugcr-2{list-style-type:none}ol.lst-kix_5oipgjcxugcr-3.start{counter-reset:lst-ctn-kix_5oipgjcxugcr-3 0}ul.lst-kix_zcvcgbx5ju56-7{list-style-type:none}ol.lst-kix_5oipgjcxugcr-1{list-style-type:none}.lst-kix_yjo4cwnqbjp0-7>li:before{content:"- "}ul.lst-kix_zcvcgbx5ju56-8{list-style-type:none}ol.lst-kix_5oipgjcxugcr-0{list-style-type:none}ol.lst-kix_5oipgjcxugcr-8{list-style-type:none}ol.lst-kix_5oipgjcxugcr-7{list-style-type:none}ol.lst-kix_5oipgjcxugcr-6{list-style-type:none}ol.lst-kix_5oipgjcxugcr-5{list-style-type:none}.lst-kix_whw4pjgxp3w1-7>li:before{content:"- "}.lst-kix_58ja23nrczhl-7>li{counter-increment:lst-ctn-kix_58ja23nrczhl-7}.lst-kix_p4ttii5g8cnl-6>li{counter-increment:lst-ctn-kix_p4ttii5g8cnl-6}.lst-kix_mfudkcwv2w89-8>li:before{content:"" counter(lst-ctn-kix_mfudkcwv2w89-8,lower-roman) ". "}.lst-kix_yn2ql2u2egdg-2>li:before{content:"- "}.lst-kix_mfudkcwv2w89-0>li:before{content:"" counter(lst-ctn-kix_mfudkcwv2w89-0,decimal) ". "}.lst-kix_k47gmg94hbw2-4>li:before{content:"- "}.lst-kix_dqkfvt9lb2wy-7>li:before{content:"- "}ol.lst-kix_5oipgjcxugcr-1.start{counter-reset:lst-ctn-kix_5oipgjcxugcr-1 0}ul.lst-kix_aj3gpabmyk88-6{list-style-type:none}.lst-kix_5oipgjcxugcr-4>li:before{content:"" counter(lst-ctn-kix_5oipgjcxugcr-4,lower-latin) ". "}ul.lst-kix_aj3gpabmyk88-7{list-style-type:none}ol.lst-kix_5yi4tofw6s0z-2.start{counter-reset:lst-ctn-kix_5yi4tofw6s0z-2 0}ul.lst-kix_aj3gpabmyk88-8{list-style-type:none}.lst-kix_9gryrzygx46m-0>li:before{content:"- "}.lst-kix_9gryrzygx46m-8>li:before{content:"- "}.lst-kix_j5vmamheymgq-7>li{counter-increment:lst-ctn-kix_j5vmamheymgq-7}ul.lst-kix_aj3gpabmyk88-2{list-style-type:none}ul.lst-kix_aj3gpabmyk88-3{list-style-type:none}ul.lst-kix_aj3gpabmyk88-4{list-style-type:none}.lst-kix_iptxq54yrrnf-6>li:before{content:"" counter(lst-ctn-kix_iptxq54yrrnf-6,decimal) ". "}ul.lst-kix_aj3gpabmyk88-5{list-style-type:none}.lst-kix_3a2g7o19wgb3-1>li:before{content:"" counter(lst-ctn-kix_3a2g7o19wgb3-1,lower-latin) ". "}ul.lst-kix_aj3gpabmyk88-0{list-style-type:none}ul.lst-kix_aj3gpabmyk88-1{list-style-type:none}.lst-kix_u3opzkdcnklc-5>li{counter-increment:lst-ctn-kix_u3opzkdcnklc-5}.lst-kix_6l3lpr6ytz51-5>li:before{content:"- "}ul.lst-kix_f96hgc2s4b68-0{list-style-type:none}.lst-kix_9prd8pa3o8y7-4>li:before{content:"" counter(lst-ctn-kix_9prd8pa3o8y7-4,lower-latin) ". "}ol.lst-kix_5oipgjcxugcr-0.start{counter-reset:lst-ctn-kix_5oipgjcxugcr-0 0}ul.lst-kix_f96hgc2s4b68-2{list-style-type:none}ul.lst-kix_f96hgc2s4b68-1{list-style-type:none}ul.lst-kix_f96hgc2s4b68-4{list-style-type:none}ul.lst-kix_f96hgc2s4b68-3{list-style-type:none}ul.lst-kix_f96hgc2s4b68-6{list-style-type:none}ul.lst-kix_f96hgc2s4b68-5{list-style-type:none}ul.lst-kix_f96hgc2s4b68-8{list-style-type:none}ul.lst-kix_f96hgc2s4b68-7{list-style-type:none}.lst-kix_1m9wqzg4mvqt-5>li:before{content:"- "}.lst-kix_7y90gfloiotx-6>li:before{content:"" counter(lst-ctn-kix_7y90gfloiotx-6,decimal) ". "}.lst-kix_8mkn8rg9im4a-1>li:before{content:"" counter(lst-ctn-kix_8mkn8rg9im4a-1,lower-latin) ". "}.lst-kix_zcvcgbx5ju56-0>li:before{content:"- "}.lst-kix_zcvcgbx5ju56-8>li:before{content:"- "}.lst-kix_j5vmamheymgq-2>li:before{content:"" counter(lst-ctn-kix_j5vmamheymgq-2,lower-roman) ". "}ol.lst-kix_mfudkcwv2w89-8{list-style-type:none}ol.lst-kix_mfudkcwv2w89-6{list-style-type:none}ol.lst-kix_mfudkcwv2w89-7{list-style-type:none}ol.lst-kix_9prd8pa3o8y7-5{list-style-type:none}ol.lst-kix_mfudkcwv2w89-4{list-style-type:none}ol.lst-kix_9prd8pa3o8y7-6{list-style-type:none}ol.lst-kix_mfudkcwv2w89-5{list-style-type:none}ol.lst-kix_9prd8pa3o8y7-7{list-style-type:none}ol.lst-kix_mfudkcwv2w89-2{list-style-type:none}ol.lst-kix_9prd8pa3o8y7-8{list-style-type:none}ol.lst-kix_mfudkcwv2w89-3{list-style-type:none}.lst-kix_yzib59bcdnhj-6>li:before{content:"- "}ol.lst-kix_9prd8pa3o8y7-1{list-style-type:none}ol.lst-kix_9prd8pa3o8y7-2{list-style-type:none}ol.lst-kix_9prd8pa3o8y7-3{list-style-type:none}ol.lst-kix_9prd8pa3o8y7-4{list-style-type:none}.lst-kix_h1p96gz9lzq4-6>li:before{content:"- "}ol.lst-kix_5yi4tofw6s0z-1.start{counter-reset:lst-ctn-kix_5yi4tofw6s0z-1 0}ol.lst-kix_9prd8pa3o8y7-0{list-style-type:none}ol{margin:0;padding:0}table td,table th{padding:0}.ykcrMYlEiJ-c18{border-right-style:solid;padding:5pt 5pt 5pt 5pt;border-bottom-color:#e0e0e0;border-top-width:1pt;border-right-width:1pt;border-left-color:#e0e0e0;vertical-align:top;border-right-color:#e0e0e0;border-left-width:1pt;border-top-style:solid;background-color:#fafafa;border-left-style:solid;border-bottom-width:1pt;width:540pt;border-top-color:#e0e0e0;border-bottom-style:solid}.ykcrMYlEiJ-c4{border-right-style:solid;padding:5pt 5pt 5pt 5pt;border-bottom-color:#000000;border-top-width:1pt;border-right-width:1pt;border-left-color:#000000;vertical-align:top;border-right-color:#000000;border-left-width:1pt;border-top-style:solid;border-left-style:solid;border-bottom-width:1pt;width:180pt;border-top-color:#000000;border-bottom-style:solid}.ykcrMYlEiJ-c24{padding-top:16pt;border-top-width:0pt;padding-bottom:4pt;line-height:1.5;page-break-after:avoid;border-top-style:solid;background-color:#ffffff;border-bottom-width:0pt;border-bottom-style:solid;text-align:left}.ykcrMYlEiJ-c1{color:#1976d2;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:14pt;font-family:"Arial";font-style:normal}.ykcrMYlEiJ-c2{color:#000000;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:11pt;font-family:"Arial";font-style:normal}.ykcrMYlEiJ-c5{padding-top:0pt;padding-bottom:0pt;line-height:1.5;orphans:2;widows:2;text-align:left;height:11pt}.ykcrMYlEiJ-c30{padding-top:10pt;padding-bottom:10pt;line-height:1.0;page-break-after:avoid;text-align:left}.ykcrMYlEiJ-c6{padding-top:0pt;padding-bottom:0pt;line-height:1.0;text-align:left;height:11pt}.ykcrMYlEiJ-c31{padding-top:0pt;padding-bottom:0pt;line-height:1.5;text-align:center}.ykcrMYlEiJ-c36{color:#1976d2;font-weight:700;font-size:15pt;font-style:normal}.ykcrMYlEiJ-c33{border-spacing:0;border-collapse:collapse;margin-right:auto}.ykcrMYlEiJ-c35{font-size:10pt;font-family:Consolas,"Courier New";color:#c53929;font-weight:400}.ykcrMYlEiJ-c14{font-size:10pt;font-family:Consolas,"Courier New";color:#9c27b0;font-weight:400}.ykcrMYlEiJ-c0{font-size:10pt;font-family:Consolas,"Courier New";color:#000000;font-weight:400}.ykcrMYlEiJ-c23{font-size:10pt;font-family:Consolas,"Courier New";color:#455a64;font-weight:400}.ykcrMYlEiJ-c12{padding-top:0pt;padding-bottom:0pt;line-height:1.5;text-align:left}.ykcrMYlEiJ-c10{font-size:10pt;font-family:Consolas,"Courier New";color:#616161;font-weight:400}.ykcrMYlEiJ-c22{padding-top:0pt;padding-bottom:0pt;line-height:1.0;text-align:left}.ykcrMYlEiJ-c9{text-decoration-skip-ink:none;-webkit-text-decoration-skip:none;color:#1155cc;text-decoration:underline}.ykcrMYlEiJ-c43{color:#1976d2;font-size:12pt;font-family:"Raleway"}.ykcrMYlEiJ-c3{font-family:Consolas,"Courier New";color:#0d904f;font-weight:400}.ykcrMYlEiJ-c8{font-family:"Times New Roman";font-style:italic;font-weight:400}.ykcrMYlEiJ-c50{text-decoration:none;vertical-align:baseline;font-family:"Times New Roman"}.ykcrMYlEiJ-c51{color:#424242;font-size:15pt;font-family:"Roboto"}.ykcrMYlEiJ-c11{vertical-align:sub;font-family:"Times New Roman";font-weight:400}.ykcrMYlEiJ-c34{text-decoration:none;vertical-align:baseline;font-family:"Arial"}.ykcrMYlEiJ-c13{text-decoration:none;vertical-align:baseline;font-style:normal}.ykcrMYlEiJ-c52{color:#666666;font-size:15pt}.ykcrMYlEiJ-c16{border:1px solid black;margin:5px}.ykcrMYlEiJ-c47{font-size:15pt;color:#1976d2}.ykcrMYlEiJ-c27{padding:0;margin:0}.ykcrMYlEiJ-c19{color:#000000;font-size:11pt}.ykcrMYlEiJ-c41{color:#1976d2;font-size:14pt}.ykcrMYlEiJ-c21{margin-left:72pt;padding-left:0pt}.ykcrMYlEiJ-c45{max-width:540pt;padding:36pt 36pt 36pt 36pt}.ykcrMYlEiJ-c32{font-weight:700;font-style:italic}.ykcrMYlEiJ-c20{orphans:2;widows:2}.ykcrMYlEiJ-c37{text-decoration:none;font-style:normal}.ykcrMYlEiJ-c15{font-weight:400;font-family:"Times New Roman"}.ykcrMYlEiJ-c44{font-weight:400;font-family:"Cambria Math"}.ykcrMYlEiJ-c25{margin-left:36pt;padding-left:0pt}.ykcrMYlEiJ-c26{color:inherit;text-decoration:inherit}.ykcrMYlEiJ-c49{font-weight:400}.ykcrMYlEiJ-c7{background-color:#ffff00}.ykcrMYlEiJ-c29{height:11pt}.ykcrMYlEiJ-c28{background-color:#ffffff}.ykcrMYlEiJ-c40{vertical-align:sub}.ykcrMYlEiJ-c42{font-style:normal}.ykcrMYlEiJ-c38{font-style:italic}.ykcrMYlEiJ-c46{height:23.9pt}.ykcrMYlEiJ-c48{margin-left:36pt}.ykcrMYlEiJ-c39{font-weight:700}.ykcrMYlEiJ-c17{height:0pt}.title{padding-top:0pt;color:#000000;font-size:26pt;padding-bottom:3pt;font-family:"Arial";line-height:1.5;page-break-after:avoid;orphans:2;widows:2;text-align:left}.subtitle{padding-top:0pt;color:#666666;font-size:15pt;padding-bottom:16pt;font-family:"Arial";line-height:1.5;page-break-after:avoid;orphans:2;widows:2;text-align:left}li{color:#000000;font-size:11pt;font-family:"Arial"}p{margin:0;color:#000000;font-size:11pt;font-family:"Arial"}h1{padding-top:10pt;color:#1976d2;font-weight:700;font-size:15pt;padding-bottom:10pt;font-family:"Arial";line-height:1.0;page-break-after:avoid;orphans:2;widows:2;text-align:left}h2{padding-top:10pt;color:#1976d2;font-size:14pt;padding-bottom:10pt;font-family:"Arial";line-height:1.0;page-break-after:avoid;orphans:2;widows:2;text-align:left}h3{padding-top:16pt;color:#434343;font-size:14pt;padding-bottom:4pt;font-family:"Arial";line-height:1.5;page-break-after:avoid;orphans:2;widows:2;text-align:left}h4{padding-top:14pt;color:#666666;font-size:12pt;padding-bottom:4pt;font-family:"Arial";line-height:1.5;page-break-after:avoid;orphans:2;widows:2;text-align:left}h5{padding-top:12pt;color:#666666;font-size:11pt;padding-bottom:4pt;font-family:"Arial";line-height:1.5;page-break-after:avoid;orphans:2;widows:2;text-align:left}h6{padding-top:12pt;color:#666666;font-size:11pt;padding-bottom:4pt;font-family:"Arial";line-height:1.5;page-break-after:avoid;font-style:italic;orphans:2;widows:2;text-align:left}</style></head><body class="c28 c45 doc-content"> <p class="c20 c24 subtitle" id="h.y3ub1og6t2w0"><span class="c34 c49 c42 c52">A deep dive into an in-the-wild Android exploit</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Guest Post by Xingyu Jin, Android Security Research<br><br></span><span>This is part one of a two-part guest blog post, where first we&#39;ll look at the <span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://googleprojectzero.github.io/0days-in-the-wild//0day-RCAs/2021/CVE-2021-0920.html">root cause</a></span> of the CVE-2021-0920 vulnerability. In the second post, we&#39;ll dive </span><span>into the in</span><span>-</span><span>the</span><span>-wild 0-day exploitation of the vulnerability and post-compromise modules.</span></p><h1 class="ykcrMYlEiJ-c30 ykcrMYlEiJ-c20" id="h.ki897ei81q67"><span>Overview of in-the-wild CVE-2021-0920 exploits</span></h1> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>A surveillance vendor </span><span>named Wintego</span><span>&nbsp;has developed an exploit for Linux socket syscall 0-day, CVE-2021-0920, and used it in the wild since </span><span>at least November 2020 based on the earliest captured sample</span><span>, until the issue was fixed in November 2021. &nbsp;Combined with Chrome and Samsung browser </span><span>exploits</span><span>, the vendor was able to remotely root Samsung devices. The fix was released with the </span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://source.android.com/security/bulletin/2021-11-01">November 2021 Android Security Bulletin</a></span><span class="ykcrMYlEiJ-c2">, and applied to Samsung devices in Samsung&#39;s December 2021 security update.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Google&#39;s Threat Analysis Group (TAG) discovered Samsung browser exploit chains being used in the wild. TAG then performed root cause analysis and discovered that this vulnerability, CVE-2021-0920, was being used to escape the sandbox and elevate privileges. </span><span>CVE-2021-0920 was reported to Linux/Android anonymously. The Google Android Security Team performed</span><span>&nbsp;the full deep-dive analysis of the exploit.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>This issue was initially discovered in 2016 by a RedHat kernel developer and disclosed in a public email thread, but the Linux kernel community </span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://patchwork.ozlabs.org/project/netdev/patch/CAOssrKcfncAYsQWkfLGFgoOxAQJVT2hYVWdBA6Cw7hhO8RJ_wQ@mail.gmail.com/">did not patch</a></span><span class="ykcrMYlEiJ-c2">&nbsp;the issue until it was re-reported in 2021.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Various Samsung devices were targeted, including the Samsung S10 and S20. By abusing an ephemeral race condition in Linux kernel garbage collection, the exploit code was able to obtain a use-after-free (UAF) in a kernel </span><span class="ykcrMYlEiJ-c3">sk_buff</span><span>&nbsp;object. The in-the-wild sample could effectively circumvent </span><span class="ykcrMYlEiJ-c3">CONFIG_ARM64_UAO</span><span>, achieve arbitrary read / write primitives and bypass Samsung RKP to elevate to root.</span><span>&nbsp;Other Android devices</span><span>&nbsp;</span><span class="ykcrMYlEiJ-c2">were also vulnerable, but we did not find any exploit samples against them.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2">Text extracted from captured samples dubbed the vulnerability &ldquo;quantum Linux kernel garbage collection&rdquo;, which appears to be a fitting title for this blogpost.</span></p><h1 class="ykcrMYlEiJ-c30 ykcrMYlEiJ-c20" id="h.q8pevpc2sw6u"><span class="ykcrMYlEiJ-c36 ykcrMYlEiJ-c34">Introduction</span></h1> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>CVE-2021-0920 is a use-after-free (UAF) due to a race condition in the garbage collection system for </span><span class="ykcrMYlEiJ-c3">SCM_RIGHTS</span><span>. </span><span class="ykcrMYlEiJ-c3">SCM_RIGHTS</span><span>&nbsp;is a control message that allows unix-domain sockets to transmit an open file descriptor from one process to another. In other words, the sender transmits a file descriptor and the receiver then obtains a file descriptor from the sender. This passing of file descriptors adds complexity to reference-counting file structs. To account for this, the Linux kernel community designed a special garbage collection system. CVE-2021-0920 is a vulnerability within this garbage collection system. By winning a race condition during the garbage collection process, an adversary can exploit the UAF on the socket buffer, </span><span class="ykcrMYlEiJ-c3">sk_buff</span><span>&nbsp;object. In the following sections, we&rsquo;ll explain the </span><span class="ykcrMYlEiJ-c3">SCM_RIGHTS</span><span>&nbsp;garbage collection system and the details of the vulnerability. The analysis is based on the Linux 4.14 kernel.</span></p><h2 class="ykcrMYlEiJ-c30 ykcrMYlEiJ-c20" id="h.qjne51ghywhs"><span>What is SCM_RIGHTS</span><span class="ykcrMYlEiJ-c1">?</span></h2> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Linux developers can share file descriptors (fd) from one process to another using the </span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://man7.org/linux/man-pages/man7/unix.7.html">SCM_RIGHTS datagram with the sendmsg syscall</a></span><span>. When a process passes a file descriptor to another process, </span><span class="ykcrMYlEiJ-c3">SCM_RIGHTS</span><span>&nbsp;will add a reference to the underlying </span><span class="ykcrMYlEiJ-c3">file</span><span>&nbsp;struct. This means that the process that is sending the file descriptors can immediately close the file descriptor on their end, even if the receiving process has not yet accepted and taken ownership of the file descriptors. When the file descriptors are in the &ldquo;queued&rdquo; state (meaning the sender has passed the fd and then closed it, but the receiver has not yet accepted the fd and taken ownership), specialized garbage collection is needed. To track this &ldquo;queued&rdquo; state, this </span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://lwn.net/Articles/779472/">LWN article</a></span><span>&nbsp;does a great job explaining </span><span class="ykcrMYlEiJ-c3">SCM_RIGHTS</span><span class="ykcrMYlEiJ-c2">&nbsp;reference counting, and it&#39;s recommended reading before continuing on with this blogpost.</span></p><h2 class="ykcrMYlEiJ-c30 ykcrMYlEiJ-c20" id="h.4irl9u2c0bda"><span class="ykcrMYlEiJ-c1">Sending</span></h2> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>As stated previously, a unix domain socket uses the syscall </span><span class="ykcrMYlEiJ-c3">sendmsg</span><span>&nbsp;to send a file descriptor to another socket. To explain the reference counting that occurs during </span><span class="ykcrMYlEiJ-c3">SCM_RIGHTS</span><span>, </span><span>we&rsquo;ll start from the sender&rsquo;s point of view. We start with the kernel</span><span>&nbsp;function </span><span class="ykcrMYlEiJ-c3">unix_stream_sendmsg</span><span>, which implements the </span><span class="ykcrMYlEiJ-c3">sendmsg</span><span>&nbsp;syscall. </span><span>To implement the </span><span class="ykcrMYlEiJ-c3">SCM_RIGHTS</span><span>&nbsp;functionality, the kernel uses the structure </span><span class="ykcrMYlEiJ-c3">scm_fp_list</span><span>&nbsp;for managing all the transmitted </span><span class="ykcrMYlEiJ-c3">file</span><span>&nbsp;structures. </span><span class="ykcrMYlEiJ-c3">scm_fp_list</span><span>&nbsp;stores the list of </span><span class="ykcrMYlEiJ-c3">file</span><span class="ykcrMYlEiJ-c2">&nbsp;pointers to be passed. </span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><a id="t.c96392c69342188701600f62dd8e18978b65546f"></a><a id="t.0"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;scm_fp_list </span><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">short</span><span class="ykcrMYlEiJ-c0">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; count</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">short</span><span class="ykcrMYlEiJ-c0">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; max</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;user_struct &nbsp; &nbsp; &nbsp;</span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">user</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;file &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">fp</span><span class="ykcrMYlEiJ-c10">[</span><span class="ykcrMYlEiJ-c0">SCM_MAX_FD</span><span class="ykcrMYlEiJ-c10">];</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">};</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c3">unix_stream_sendmsg</span><span>&nbsp;invokes </span><span class="ykcrMYlEiJ-c3">scm_send</span><span>&nbsp;(</span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://elixir.bootlin.com/linux/v4.14.277/source/net/unix/af_unix.c#L1886">af_unix.c#L1886</a></span><span>) to initialize the </span><span class="ykcrMYlEiJ-c3">scm_fp_list</span><span>&nbsp;structure, linked by the</span><span>&nbsp;</span><span class="ykcrMYlEiJ-c3">scm_cookie</span><span>&nbsp;structure on the stack.</span></p><a id="t.15e3db5d013417d6ac8097f3ef1d76367028ae48"></a><a id="t.1"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;scm_cookie </span><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;pid &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">pid</span><span class="ykcrMYlEiJ-c10">;</span><span class="ykcrMYlEiJ-c0">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c23">/* Skb credentials */</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14 ykcrMYlEiJ-c7">struct</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;scm_fp_list &nbsp; &nbsp; &nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">*</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">fp</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="ykcrMYlEiJ-c23 ykcrMYlEiJ-c7">/* Passed files &nbsp; &nbsp; &nbsp; &nbsp; */</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;scm_creds &nbsp; &nbsp; &nbsp; &nbsp;creds</span><span class="ykcrMYlEiJ-c10">;</span><span class="ykcrMYlEiJ-c0">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="ykcrMYlEiJ-c23">/* Skb credentials &nbsp; &nbsp; &nbsp;*/</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">#ifdef</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13">&nbsp;CONFIG_SECURITY_NETWORK</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; u32 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; secid</span><span class="ykcrMYlEiJ-c10">;</span><span class="ykcrMYlEiJ-c0">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="ykcrMYlEiJ-c23">/* Passed security ID &nbsp; */</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">#endif</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">};</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>To be more specific, </span><span class="ykcrMYlEiJ-c3">scm_send</span><span>&nbsp;&rarr; </span><span class="ykcrMYlEiJ-c3">__scm_send</span><span>&nbsp;&rarr; </span><span class="ykcrMYlEiJ-c3">scm_fp_copy</span><span>&nbsp;(</span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://elixir.bootlin.com/linux/v4.14.277/source/net/core/scm.c#L68">scm.c#L68</a></span><span>) reads the file descriptors from the userspace and initializes </span><span class="ykcrMYlEiJ-c3">scm_cookie-&gt;fp</span><span>&nbsp;which can contain </span><span class="ykcrMYlEiJ-c3">SCM_MAX_FD</span><span class="ykcrMYlEiJ-c2">&nbsp;file structures.</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Since the Linux kernel uses the </span><span class="ykcrMYlEiJ-c3">sk_buff</span><span>&nbsp;(also known as socket buffers or </span><span class="ykcrMYlEiJ-c3">skb</span><span>) object to manage all types of socket datagrams, the kernel also needs to invoke the </span><span class="ykcrMYlEiJ-c3">unix_scm_to_skb</span><span>&nbsp;function to link the </span><span class="ykcrMYlEiJ-c3">scm_cookie-&gt;fp</span><span>&nbsp;to a corresponding </span><span class="ykcrMYlEiJ-c3">skb</span><span>&nbsp;object. This occurs in </span><span class="ykcrMYlEiJ-c3">unix_attach_fds</span><span>&nbsp;(</span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://elixir.bootlin.com/linux/v4.14.277/source/net/unix/scm.c#L103">scm.c#L103</a></span><span class="ykcrMYlEiJ-c2">):</span></p> <p class="c31 c20 c29"><span class="ykcrMYlEiJ-c2"></span></p><a id="t.7d908bfdc8aa4cf5bff47e5320fdce7dc7e2949e"></a><a id="t.2"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">&hellip;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">/*</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;* Need to duplicate file references for the sake of garbage</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;* collection. &nbsp;Otherwise a socket in the fps might become a</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;* candidate for GC while the skb is not yet queued.</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;*/</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">UNIXCB</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">skb</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">).</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">fp </span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">=</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;scm_fp_dup</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">scm</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">fp</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c14">if</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(!</span><span class="ykcrMYlEiJ-c0">UNIXCB</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">skb</span><span class="ykcrMYlEiJ-c10">).</span><span class="ykcrMYlEiJ-c0">fp</span><span class="ykcrMYlEiJ-c10">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">return</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">-</span><span class="ykcrMYlEiJ-c0">ENOMEM</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">&hellip;</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>The </span><span class="ykcrMYlEiJ-c3">scm_fp_dup</span><span>&nbsp;call in </span><span class="ykcrMYlEiJ-c3">unix_attach_fds</span><span class="ykcrMYlEiJ-c2">&nbsp;increases the reference count of the file descriptor that&rsquo;s being passed so the file is still valid even after the sender closes the transmitted file descriptor later:</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><a id="t.48360ede8275e8fd7e6e61cd084a628de58bb15f"></a><a id="t.3"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;scm_fp_list </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">scm_fp_dup</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;scm_fp_list </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">fpl</span><span class="ykcrMYlEiJ-c10">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;scm_fp_list </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">new_fpl</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">int</span><span class="ykcrMYlEiJ-c0">&nbsp;i</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">if</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(!</span><span class="ykcrMYlEiJ-c0">fpl</span><span class="ykcrMYlEiJ-c10">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">return</span><span class="ykcrMYlEiJ-c0">&nbsp;NULL</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; new_fpl </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;kmemdup</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">fpl</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;offsetof</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;scm_fp_list</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;fp</span><span class="ykcrMYlEiJ-c10">[</span><span class="ykcrMYlEiJ-c0">fpl</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">count</span><span class="ykcrMYlEiJ-c10">]),</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GFP_KERNEL</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">if</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">new_fpl</span><span class="ykcrMYlEiJ-c10">)</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">for</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">i </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c35">0</span><span class="ykcrMYlEiJ-c10">;</span><span class="ykcrMYlEiJ-c0">&nbsp;i </span><span class="ykcrMYlEiJ-c10">&lt;</span><span class="ykcrMYlEiJ-c0">&nbsp;fpl</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">count</span><span class="ykcrMYlEiJ-c10">;</span><span class="ykcrMYlEiJ-c0">&nbsp;i</span><span class="ykcrMYlEiJ-c10">++)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get_file</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">fpl</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">fp</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">[</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">i</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">]);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_fpl</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">max </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;new_fpl</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">count</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_fpl</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">user </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;get_uid</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">fpl</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">user</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c10">}</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">return</span><span class="ykcrMYlEiJ-c0">&nbsp;new_fpl</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">}</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Let&rsquo;s examine a concrete example. Assume we have sockets </span><span class="ykcrMYlEiJ-c8">A</span><span>&nbsp;and </span><span class="ykcrMYlEiJ-c8">B</span><span>. The </span><span class="ykcrMYlEiJ-c8">A</span><span>&nbsp;attempts to pass itself to </span><span class="ykcrMYlEiJ-c8">B</span><span>. After the </span><span class="ykcrMYlEiJ-c3">SCM_RIGHTS</span><span>&nbsp;datagram is sent, the newly allocated </span><span class="ykcrMYlEiJ-c3">skb</span><span>&nbsp;from the sender will be appended to the </span><span class="ykcrMYlEiJ-c8">B</span><span>&rsquo;s </span><span class="ykcrMYlEiJ-c3">sk_receive_queue</span><span class="ykcrMYlEiJ-c2">&nbsp;which stores received datagrams:</span></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNWAkA0RVb4goO21_FhJOVV-LSNTfbXV7GKoqH-CUrdMTpDcNUSQxEssrnAVGxC50aK-Z3HfIWeDyCgkr6lb5-a1Ha9Km5ppaHeBzWmLj8NTmZtUjx8J-VzzM1O7mYdjOfw2ErddrslDXw6rDZrs0g1DEC1Ya4VAbkLKKEhZgNPeiSefH-xpv3zDa8/s1438/image71.png" style="display: block; padding: 1em 0;text-align: center;"><img alt="unix_stream_sendmsg creates sk_buff which contains the structure scm_fp_list. The scm_fp_list has a fp pointer points to the transmitted file (A). The sk_buff is appended to the receiver queue and the reference count of A is 2." border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNWAkA0RVb4goO21_FhJOVV-LSNTfbXV7GKoqH-CUrdMTpDcNUSQxEssrnAVGxC50aK-Z3HfIWeDyCgkr6lb5-a1Ha9Km5ppaHeBzWmLj8NTmZtUjx8J-VzzM1O7mYdjOfw2ErddrslDXw6rDZrs0g1DEC1Ya4VAbkLKKEhZgNPeiSefH-xpv3zDa8/s1200/image71.png" style="max-height: 750px; max-width: 600px;" title="unix_stream_sendmsg creates sk_buff which contains the structure scm_fp_list. The scm_fp_list has a fp pointer points to the transmitted file (A). The sk_buff is appended to the receiver queue and the reference count of A is 2." /></a></span></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c3">sk_buff</span><span>&nbsp;carries </span><span class="ykcrMYlEiJ-c3">scm_fp_list</span><span class="ykcrMYlEiJ-c2">&nbsp;structure</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>The reference count of </span><span class="ykcrMYlEiJ-c8">A</span><span>&nbsp;is incremented to 2 and the reference count of </span><span class="ykcrMYlEiJ-c8">B</span><span class="ykcrMYlEiJ-c2">&nbsp;is still 1.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><h2 class="ykcrMYlEiJ-c30 ykcrMYlEiJ-c20" id="h.b16dgtqtkmv1"><span class="ykcrMYlEiJ-c1">Receiving</span></h2> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Now, let&rsquo;s take a look at the receiver side </span><span class="ykcrMYlEiJ-c3">unix_stream_read_generic</span><span>&nbsp;(we will not discuss the </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag yet, and focus on the normal </span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://elixir.bootlin.com/linux/v4.14.277/source/net/unix/af_unix.c#L2445">routine</a></span><span>). First of all, the kernel grabs the current </span><span class="ykcrMYlEiJ-c3">skb</span><span>&nbsp;from </span><span class="ykcrMYlEiJ-c3">sk_receive_queue</span><span>&nbsp;using </span><span class="ykcrMYlEiJ-c3">skb_peek</span><span>. Secondly, since </span><span class="ykcrMYlEiJ-c3">scm_fp_list</span><span>&nbsp;is attached to the </span><span class="ykcrMYlEiJ-c3">skb</span><span>, the kernel will call </span><span class="ykcrMYlEiJ-c3">unix_detach_fds</span><span>&nbsp;(</span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://elixir.bootlin.com/linux/v4.14.277/source/net/unix/scm.c#L125">link</a></span><span>) </span><span>to parse the transmitted file structures from </span><span class="ykcrMYlEiJ-c3">skb</span><span>&nbsp;and clear the </span><span class="ykcrMYlEiJ-c3">skb</span><span>&nbsp;from </span><span class="ykcrMYlEiJ-c3">sk_receive_queue</span><span>:</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><a id="t.d7b1cde66ffafc113438777cb255432b8ed4e0e4"></a><a id="t.4"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">/* Mark read part of skb as used */</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c14">if</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(!(</span><span class="ykcrMYlEiJ-c0">flags </span><span class="ykcrMYlEiJ-c10">&amp;</span><span class="ykcrMYlEiJ-c0">&nbsp;MSG_PEEK</span><span class="ykcrMYlEiJ-c10">))</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c0">UNIXCB</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">skb</span><span class="ykcrMYlEiJ-c10">).</span><span class="ykcrMYlEiJ-c0">consumed </span><span class="ykcrMYlEiJ-c10">+=</span><span class="ykcrMYlEiJ-c0">&nbsp;chunk</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; sk_peek_offset_bwd</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">sk</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;chunk</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14 ykcrMYlEiJ-c7">if</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">UNIXCB</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">skb</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">).</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">fp</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; unix_detach_fds</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(&amp;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">scm</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">,</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;skb</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">);</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">if</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">unix_skb_len</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">skb</span><span class="ykcrMYlEiJ-c10">))</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">break</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; skb_unlink</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">skb</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">&amp;</span><span class="ykcrMYlEiJ-c0">sk</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">sk_receive_queue</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; consume_skb</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">skb</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">if</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">scm</span><span class="ykcrMYlEiJ-c10">.</span><span class="ykcrMYlEiJ-c0">fp</span><span class="ykcrMYlEiJ-c10">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">break</span><span class="ykcrMYlEiJ-c10">;</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>The function </span><span class="ykcrMYlEiJ-c3">scm_detach_fds</span><span>&nbsp;iterates over the list of passed file descriptors (</span><span class="ykcrMYlEiJ-c3">scm-&gt;fp)</span><span>&nbsp;</span><span class="ykcrMYlEiJ-c2">and installs the new file descriptors accordingly for the receiver:</span></p><a id="t.cccd27f0609fb1b03a888ddc1137e5fe1004a78a"></a><a id="t.5"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c14">for</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">i</span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c35">0</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;cmfptr</span><span class="ykcrMYlEiJ-c10">=(</span><span class="ykcrMYlEiJ-c0">__force </span><span class="ykcrMYlEiJ-c14">int</span><span class="ykcrMYlEiJ-c0">&nbsp;__user </span><span class="ykcrMYlEiJ-c10">*)</span><span class="ykcrMYlEiJ-c0">CMSG_DATA</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">cm</span><span class="ykcrMYlEiJ-c10">);</span><span class="ykcrMYlEiJ-c0">&nbsp;i</span><span class="ykcrMYlEiJ-c10">&lt;</span><span class="ykcrMYlEiJ-c0">fdmax</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp;i</span><span class="ykcrMYlEiJ-c10">++,</span><span class="ykcrMYlEiJ-c0">&nbsp;cmfptr</span><span class="ykcrMYlEiJ-c10">++)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;socket </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">sock</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">int</span><span class="ykcrMYlEiJ-c0">&nbsp;new_fd</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; err </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;security_file_receive</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">fp</span><span class="ykcrMYlEiJ-c10">[</span><span class="ykcrMYlEiJ-c0">i</span><span class="ykcrMYlEiJ-c10">]);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">if</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">err</span><span class="ykcrMYlEiJ-c10">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">break</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; err </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;get_unused_fd_flags</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">MSG_CMSG_CLOEXEC </span><span class="ykcrMYlEiJ-c10">&amp;</span><span class="ykcrMYlEiJ-c0">&nbsp;msg</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13">msg_flags</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c10">?</span><span class="ykcrMYlEiJ-c0">&nbsp;O_CLOEXEC </span><span class="ykcrMYlEiJ-c10">:</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c35">0</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">if</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">err </span><span class="ykcrMYlEiJ-c10">&lt;</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c35">0</span><span class="ykcrMYlEiJ-c10">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">break</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; new_fd </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;err</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; err </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;put_user</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">new_fd</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;cmfptr</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">if</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">err</span><span class="ykcrMYlEiJ-c10">)</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; put_unused_fd</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">new_fd</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">break</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c10">}</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c23">/* Bump the usage count and install the file. */</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; sock </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;sock_from_file</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">fp</span><span class="ykcrMYlEiJ-c10">[</span><span class="ykcrMYlEiJ-c0">i</span><span class="ykcrMYlEiJ-c10">],</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">&amp;</span><span class="ykcrMYlEiJ-c0">err</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">if</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">sock</span><span class="ykcrMYlEiJ-c10">)</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sock_update_netprioidx</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">sock</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">sk</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">sk_cgrp_data</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sock_update_classid</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">sock</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">sk</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">sk_cgrp_data</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c10">}</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; fd_install</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">new_fd</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">,</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;get_file</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">fp</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">[</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">i</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">]));</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">}</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">&hellip;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">/*</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;* All of the files that fit in the message have had their</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;* usage counts incremented, so we just free the list.</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;*/</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">__scm_destroy</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">scm</span><span class="c10 c13 c7">);</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Once the file descriptors have been installed</span><span>, </span><span class="ykcrMYlEiJ-c3">__scm_destroy</span><span>&nbsp;(</span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://elixir.bootlin.com/linux/v4.14.277/source/net/core/scm.c#L119">link</a></span><span>) cleans up the allocated </span><span class="ykcrMYlEiJ-c3">scm-&gt;fp</span><span class="ykcrMYlEiJ-c2">&nbsp;and decrements the file reference count for every transmitted file structure:</span></p><a id="t.f6edb942990216f6cb0c4a0bd7dc5c0cd5bf15f9"></a><a id="t.6"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c14">void</span><span class="ykcrMYlEiJ-c0">&nbsp;__scm_destroy</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;scm_cookie </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">scm</span><span class="ykcrMYlEiJ-c10">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;scm_fp_list </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">fpl </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;scm</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">fp</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">int</span><span class="ykcrMYlEiJ-c0">&nbsp;i</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">if</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">fpl</span><span class="ykcrMYlEiJ-c10">)</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; scm</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">fp </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;NULL</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">for</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">i</span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">fpl</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">count</span><span class="ykcrMYlEiJ-c10">-</span><span class="ykcrMYlEiJ-c35">1</span><span class="ykcrMYlEiJ-c10">;</span><span class="ykcrMYlEiJ-c0">&nbsp;i</span><span class="ykcrMYlEiJ-c10">&gt;=</span><span class="ykcrMYlEiJ-c35">0</span><span class="ykcrMYlEiJ-c10">;</span><span class="ykcrMYlEiJ-c0">&nbsp;i</span><span class="ykcrMYlEiJ-c10">--)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">fput</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">fpl</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">fp</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">[</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">i</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">]);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; free_uid</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">fpl</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">user</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; kfree</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">fpl</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c10">}</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">}</span></p></td></tr></table><h2 class="ykcrMYlEiJ-c30 ykcrMYlEiJ-c20" id="h.zi0w3dhxm2me"><span class="ykcrMYlEiJ-c1">Reference Counting and Inflight Counting</span></h2> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>As mentioned above, when a file descriptor is passed using </span><span class="ykcrMYlEiJ-c3">SCM_RIGHTS,</span><span class="ykcrMYlEiJ-c2">&nbsp;its reference count is immediately incremented. Once the recipient socket has accepted and installed the passed file descriptor, the reference count is then decremented. The complication comes from the &ldquo;middle&rdquo; of this operation: after the file descriptor has been sent, but before the receiver has accepted and installed the file descriptor.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2">Let&rsquo;s consider the following scenario:</span></p><ol class="c27 lst-kix_3a2g7o19wgb3-0 start" start="1"><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span>The process creates sockets </span><span class="ykcrMYlEiJ-c8">A</span><span>&nbsp;and </span><span class="ykcrMYlEiJ-c8">B</span><span class="ykcrMYlEiJ-c2">.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">A</span><span>&nbsp;sends socket </span><span class="ykcrMYlEiJ-c8">A </span><span>to socket </span><span class="ykcrMYlEiJ-c8">B</span><span class="ykcrMYlEiJ-c2">.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">B</span><span>&nbsp;sends socket </span><span class="ykcrMYlEiJ-c8">B</span><span>&nbsp;to socket </span><span class="ykcrMYlEiJ-c8">A</span><span class="ykcrMYlEiJ-c2">.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span>Close </span><span class="ykcrMYlEiJ-c8">A</span><span class="ykcrMYlEiJ-c2">.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span>Close </span><span class="ykcrMYlEiJ-c8">B</span><span class="ykcrMYlEiJ-c2">.</span></li></ol> <p class="c31 c20 c48"></p> <p class="c31 c20 c48"><span class="ykcrMYlEiJ-c2"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixn2j2I0_3XKxc7uimc_-Bd2F7fUflziTRwXRLeCfzDzrA_GKDsDLvqidYluwq_lGptlzWkZ3DD4f2DGnyjuALHuH46yzHjovkrVdzuG-Ncgi4WphgXf9HK_RPnxB91R07fG7cnyy4wZN-M3qZtb6uKOwarRmxIPdQWbJVA-KQlhKQBBR4EZS6aZDe/s724/image66.png" style="display: block; padding: 1em 0;text-align: center;"><img alt="Socket A and B form a reference count cycle." border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixn2j2I0_3XKxc7uimc_-Bd2F7fUflziTRwXRLeCfzDzrA_GKDsDLvqidYluwq_lGptlzWkZ3DD4f2DGnyjuALHuH46yzHjovkrVdzuG-Ncgi4WphgXf9HK_RPnxB91R07fG7cnyy4wZN-M3qZtb6uKOwarRmxIPdQWbJVA-KQlhKQBBR4EZS6aZDe/s724/image66.png" style="max-height: 750px; max-width: 600px;" title="Socket A and B form a reference count cycle." /></a></span></p> <p class="ykcrMYlEiJ-c20 ykcrMYlEiJ-c31"><span class="c34 c19 c32">Scenario for reference count cycle</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Both sockets are closed prior to accepting the passed file descriptors.The reference counts of </span><span class="ykcrMYlEiJ-c8">A</span><span>&nbsp;and </span><span class="ykcrMYlEiJ-c8">B</span><span>&nbsp;are both 1 and can&#39;t be further decremented because they were removed from the kernel fd table when the respective processes closed them. Therefore the kernel is unable to release the two skbs and sock structures </span><span>and an unbreakable cycle is formed</span><span>. The Linux kernel garbage collection system is designed to prevent memory exhaustion in this particular scenario. The </span><span class="ykcrMYlEiJ-c3">inflight</span><span>&nbsp;count was implemented to identify potential garbage. Each time the reference count is increased due to an SCM_RIGHTS datagram being sent, the </span><span class="ykcrMYlEiJ-c3">inflight</span><span class="ykcrMYlEiJ-c2">&nbsp;count will also be incremented.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>When a file descriptor is sent by </span><span class="ykcrMYlEiJ-c3">SCM_RIGHTS</span><span>&nbsp;datagram,</span><span>&nbsp;the Linux kernel puts its </span><span class="ykcrMYlEiJ-c3">unix_sock</span><span>&nbsp;into a global list </span><span class="ykcrMYlEiJ-c3">gc_inflight_list</span><span>. The kernel</span><span>&nbsp;</span><span>increments </span><span class="ykcrMYlEiJ-c3">unix_tot_inflight</span><span>&nbsp;which counts the total number of inflight sockets. Then, the kernel increments </span><span class="ykcrMYlEiJ-c3">u-&gt;inflight</span><span>&nbsp;which tracks the inflight count for each individual file descriptor in the </span><span class="ykcrMYlEiJ-c3">unix_inflight</span><span>&nbsp;function (</span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://elixir.bootlin.com/linux/v4.14.277/source/net/unix/scm.c#L45">scm.c#L45</a></span><span>) invoked from </span><span class="ykcrMYlEiJ-c3">unix_attach_fds</span><span>:</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><a id="t.029ba7ef27b97405e8e6fdfbd115b01f42a3bdd9"></a><a id="t.7"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c14">void</span><span class="ykcrMYlEiJ-c0">&nbsp;unix_inflight</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;user_struct </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">user</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;file </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">fp</span><span class="ykcrMYlEiJ-c10">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;sock </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">s </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;unix_get_socket</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">fp</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; spin_lock</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">unix_gc_lock</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">if</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">s</span><span class="ykcrMYlEiJ-c10">)</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;unix_sock </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">u </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;unix_sk</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">s</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14 ykcrMYlEiJ-c7">if</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">atomic_long_inc_return</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(&amp;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">u</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">inflight</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">)</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">==</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c35 ykcrMYlEiJ-c7">1</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">)</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BUG_ON</span><span class="ykcrMYlEiJ-c10">(!</span><span class="ykcrMYlEiJ-c0">list_empty</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">u</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">link</span><span class="ykcrMYlEiJ-c10">));</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list_add_tail</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(&amp;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">u</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">link</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">,</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">&amp;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">gc_inflight_list</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c10">}</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c14">else</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BUG_ON</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">list_empty</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">u</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">link</span><span class="ykcrMYlEiJ-c10">));</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c10">}</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; unix_tot_inflight</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">++;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c10">}</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; user</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">unix_inflight</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">++;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; spin_unlock</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">unix_gc_lock</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">}</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Thus, here is what the </span><span class="ykcrMYlEiJ-c3">sk_buff</span><span>&nbsp;looks like when transferring a file descriptor within sockets </span><span class="ykcrMYlEiJ-c8">A</span><span>&nbsp;and </span><span class="ykcrMYlEiJ-c8">B</span><span class="ykcrMYlEiJ-c2">:</span></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7JYdav9RAoJLT1TJAAfsVJ6kudGtVBqb8V8Xs0DjEVDEfouQv3SX06oh4AmpRx8UrMNnjqhe0i0FYB6c2jjNtiwGSa1LpHSsg-0AI270tzyX2ziVEHuOO69qTIYhjj780S0oMvXfrdAuyNImJYtBfZ8oUV869w62NV5wshFX3cM0hpmPW219HZT3u/s756/image64.png" style="display: block; padding: 1em 0;text-align: center;"><img alt="When the file descriptor A sends itself to the file descriptor B, the reference count of the file descriptor A is 2 and the inflight count is 1. For the receiver file descriptor B, the file reference count is 1 and the inflight count is 0." border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7JYdav9RAoJLT1TJAAfsVJ6kudGtVBqb8V8Xs0DjEVDEfouQv3SX06oh4AmpRx8UrMNnjqhe0i0FYB6c2jjNtiwGSa1LpHSsg-0AI270tzyX2ziVEHuOO69qTIYhjj780S0oMvXfrdAuyNImJYtBfZ8oUV869w62NV5wshFX3cM0hpmPW219HZT3u/s756/image64.png" style="max-height: 750px; max-width: 600px;" title="When the file descriptor A sends itself to the file descriptor B, the reference count of the file descriptor A is 2 and the inflight count is 1. For the receiver file descriptor B, the file reference count is 1 and the inflight count is 0." /></a></span></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c32">The inflight count of </span><span class="ykcrMYlEiJ-c8">A</span><span class="c34 c19 c32">&nbsp;is incremented</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>When the socket file descriptor is received from the other side, the </span><span class="ykcrMYlEiJ-c3">unix_sock.inflight</span><span class="ykcrMYlEiJ-c2">&nbsp;count will be decremented.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Let&rsquo;s revisit the reference count cycle scenario before the close syscall. </span><span>This cycle is breakable because any socket files can receive the transmitted file and break the reference cycle:</span><span class="ykcrMYlEiJ-c32">&nbsp;</span></p> <p class="c31 c20 c48"></p> <p class="c31 c20 c48"><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXASWOd1HPgwueBa5J636vqpj3uP4onThAwMEL0K_ZBBh3mUr5WklN_YPLIYzXaKl2aSpzcf_odw0ymXe-k7wewgh592dQfkj8AYn6r4jHVh6TXpML2-zsCyFt6ZjmR8N-hcyCeHIwVDjtgCGuRU-YfulCdMk5GWTu9h7X8N7iuCV7GXkzLOKEwFy9/s704/image70.png" style="display: block; padding: 1em 0;text-align: center;"><img alt="The file descriptor A sends itself to the file descriptor B and vice versa. The inflight count of the file descriptor A and B is both 1 and the file reference count is both 2." border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXASWOd1HPgwueBa5J636vqpj3uP4onThAwMEL0K_ZBBh3mUr5WklN_YPLIYzXaKl2aSpzcf_odw0ymXe-k7wewgh592dQfkj8AYn6r4jHVh6TXpML2-zsCyFt6ZjmR8N-hcyCeHIwVDjtgCGuRU-YfulCdMk5GWTu9h7X8N7iuCV7GXkzLOKEwFy9/s704/image70.png" style="max-height: 750px; max-width: 600px;" title="The file descriptor A sends itself to the file descriptor B and vice versa. The inflight count of the file descriptor A and B is both 1 and the file reference count is both 2." /></a></span></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c32">Breakable cycle before close </span><span class="ykcrMYlEiJ-c8">A</span><span class="ykcrMYlEiJ-c32">&nbsp;and </span><span class="ykcrMYlEiJ-c8">B</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2">After closing both of the file descriptors, the reference count equals the inflight count for each of the socket file descriptors, which is a sign of possible garbage:</span></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiLYC-jGxNwF2UbjAZgIsusMaCUGbBo61ZVRxLljS27iXShVhfCth-_lXBBevW9hyWaIcKBWdkX_6BixTMWNDoE56ZrUFbiKLolrc8orEqPTp_0ITjwRfxUzJZwvaJZWkomMlkM-_Lqr1DdFQVKjnEW_nnuSOz51JCvu-xZDterJudPenVekqGpqP-/s700/image61.png" style="display: block; padding: 1em 0;text-align: center;"><img alt="The cycle becomes unbreakable after closing A and B. The reference count equals to the inflight count for A and B." border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiLYC-jGxNwF2UbjAZgIsusMaCUGbBo61ZVRxLljS27iXShVhfCth-_lXBBevW9hyWaIcKBWdkX_6BixTMWNDoE56ZrUFbiKLolrc8orEqPTp_0ITjwRfxUzJZwvaJZWkomMlkM-_Lqr1DdFQVKjnEW_nnuSOz51JCvu-xZDterJudPenVekqGpqP-/s700/image61.png" style="max-height: 750px; max-width: 600px;" title="The cycle becomes unbreakable after closing A and B. The reference count equals to the inflight count for A and B." /></a></span></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c32">Unbreakable cycle after close </span><span class="ykcrMYlEiJ-c8">A</span><span class="ykcrMYlEiJ-c32">&nbsp;and </span><span class="ykcrMYlEiJ-c8">B</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Now, let&rsquo;s check another example. </span><span>Assume we have sockets </span><span class="ykcrMYlEiJ-c8">A</span><span>, </span><span class="ykcrMYlEiJ-c8">B</span><span>&nbsp;and </span><span class="ykcrMYlEiJ-c44">&#x1d6fc;</span><span>:</span></p><ol class="c27 lst-kix_9prd8pa3o8y7-0 start" start="1"><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">A</span><span>&nbsp;sends socket </span><span class="ykcrMYlEiJ-c8">A</span><span>&nbsp;to socket </span><span class="ykcrMYlEiJ-c8">B</span><span class="ykcrMYlEiJ-c2">.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">B</span><span>&nbsp;sends socket </span><span class="ykcrMYlEiJ-c8">B</span><span>&nbsp;to socket </span><span class="ykcrMYlEiJ-c8">A</span><span class="ykcrMYlEiJ-c2">.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">B</span><span>&nbsp;sends socket </span><span class="ykcrMYlEiJ-c8">B</span><span>&nbsp;to socket </span><span class="ykcrMYlEiJ-c44">&#x1d6fc;</span><span class="ykcrMYlEiJ-c2">.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c44">&#x1d6fc;</span><span>&nbsp;sends socket </span><span class="ykcrMYlEiJ-c44">&#x1d6fc;</span><span>&nbsp;to socket </span><span class="ykcrMYlEiJ-c8">B</span><span class="ykcrMYlEiJ-c2">.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span>Close </span><span class="ykcrMYlEiJ-c8">A</span><span class="ykcrMYlEiJ-c2">.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span>Close </span><span class="ykcrMYlEiJ-c8">B</span><span class="ykcrMYlEiJ-c2">.</span></li></ol> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnuMdkCyfn1Xhzr4NJiNcf3Oxt8ZB8kCVOZEIIVcuTGoHGEq37NFy44gE-wgNaaIZiwoSE0iWSpfifiXtfEMc0qec9_Lih7VE3xqzQJ6PjIGMT7K6Jcz0VLfYELIev025FXRJbnmnKHdChHBnk7DnjFQSRe0kB8k9zoXBP_ZYh7SYlCkQ08qHYhyxY/s1999/image68.png" style="display: block; padding: 1em 0;text-align: center;"><img alt="A, B and alpha form a breakable cycle." border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnuMdkCyfn1Xhzr4NJiNcf3Oxt8ZB8kCVOZEIIVcuTGoHGEq37NFy44gE-wgNaaIZiwoSE0iWSpfifiXtfEMc0qec9_Lih7VE3xqzQJ6PjIGMT7K6Jcz0VLfYELIev025FXRJbnmnKHdChHBnk7DnjFQSRe0kB8k9zoXBP_ZYh7SYlCkQ08qHYhyxY/s1200/image68.png" style="max-height: 750px; max-width: 600px;" title="A, B and alpha form a breakable cycle." /></a></span></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c32">Breakable cycle for </span><span class="ykcrMYlEiJ-c8">A</span><span>, </span><span class="ykcrMYlEiJ-c8">B</span><span>&nbsp;</span><span class="ykcrMYlEiJ-c32">and</span><span>&nbsp;</span><span class="ykcrMYlEiJ-c15">&#x1d6fc;</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>The cycle is breakable, because </span><span>we can get newly installed file descriptor </span><span class="ykcrMYlEiJ-c8">B</span><span>&rsquo;</span><span>&nbsp;from the socket file descriptor </span><span class="ykcrMYlEiJ-c44">&#x1d6fc;</span><span>&nbsp;and newly installed file descriptor </span><span class="ykcrMYlEiJ-c8">A&#39;</span><span>&nbsp;from </span><span class="ykcrMYlEiJ-c8">B</span><span>&rsquo;.</span></p><h2 class="ykcrMYlEiJ-c30 ykcrMYlEiJ-c20" id="h.6bkr31v5bx7w"><span class="ykcrMYlEiJ-c1">Garbage Collection</span></h2> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>A h</span><span>igh level view of garbage collection is available from </span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://lwn.net/Articles/779472/">lwn.net</a></span><span class="ykcrMYlEiJ-c2">:</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c38">&quot;</span><span class="c34 c19 c49 c38">If, instead, the two counts are equal, that file structure might be part of an unreachable cycle. To determine whether that is the case, the kernel finds the set of all in-flight Unix-domain sockets for which all references are contained in SCM_RIGHTS datagrams (for which f_count and inflight are equal, in other words). It then counts how many references to each of those sockets come from SCM_RIGHTS datagrams attached to sockets in this set. Any socket that has references coming from outside the set is reachable and can be removed from the set. If it is reachable, and if there are any SCM_RIGHTS datagrams waiting to be consumed attached to it, the files contained within that datagram are also reachable and can be removed from the set.</span></p> <p class="ykcrMYlEiJ-c5"><span class="c34 c19 c38 c49"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="c34 c19 c49 c38">At the end of an iterative process, the kernel may find itself with a set of in-flight Unix-domain sockets that are only referenced by unconsumed (and unconsumable) SCM_RIGHTS datagrams; at this point, it has a cycle of file structures holding the only references to each other. Removing those datagrams from the queue, releasing the references they hold, and discarding them will break the cycle.&quot;</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>To be more specific, the </span><span class="ykcrMYlEiJ-c3">SCM_RIGHTS</span><span class="ykcrMYlEiJ-c2">&nbsp;garbage collection system was developed in order to handle the unbreakable reference cycles. To identify which file descriptors are a part of unbreakable cycles:</span></p><ol class="c27 lst-kix_iptxq54yrrnf-0 start" start="1"><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span>Add any </span><span class="ykcrMYlEiJ-c3">unix_sock</span><span>&nbsp;objects whose reference count equals its inflight count to the </span><span class="ykcrMYlEiJ-c3">gc_candidates</span><span class="ykcrMYlEiJ-c2">&nbsp;list.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span>Determine if the socket is referenced by any sockets outside of the </span><span class="ykcrMYlEiJ-c3">gc_candidates</span><span>&nbsp;list. If it is then it is reachable, remove it and any sockets it references from the </span><span class="ykcrMYlEiJ-c3">gc_candidates</span><span>&nbsp;list. </span><span class="ykcrMYlEiJ-c2">Repeat until no more reachable sockets are found.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span>After this iterative process, only sockets who are solely referenced by other sockets within the </span><span class="ykcrMYlEiJ-c3">gc_candidates</span><span class="ykcrMYlEiJ-c2">&nbsp;list are left. </span></li></ol> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Let&rsquo;s take a closer look at how this garbage collection process works. First, the kernel finds all the </span><span class="ykcrMYlEiJ-c3">unix_sock</span><span>&nbsp;objects whose reference counts equals their inflight count and puts them into the </span><span class="ykcrMYlEiJ-c3">gc_candidates</span><span>&nbsp;</span><span>list</span><span>&nbsp;(</span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://elixir.bootlin.com/linux/v4.14.277/source/net/unix/garbage.c#L242">garbage.c#L242)</a></span><span class="ykcrMYlEiJ-c2">:</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><a id="t.abfa5bba6c1c21ddf7addd07cef8c63ba518ddc9"></a><a id="t.8"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">list_for_each_entry_safe</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">u</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c14">next</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">&amp;</span><span class="ykcrMYlEiJ-c0">gc_inflight_list</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;link</span><span class="ykcrMYlEiJ-c10">)</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">long</span><span class="ykcrMYlEiJ-c0">&nbsp;total_refs</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">long</span><span class="ykcrMYlEiJ-c0">&nbsp;inflight_refs</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; total_refs </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;file_count</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">u</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">sk</span><span class="ykcrMYlEiJ-c10">.</span><span class="ykcrMYlEiJ-c0">sk_socket</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">file</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; inflight_refs </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;atomic_long_read</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">u</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">inflight</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; BUG_ON</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">inflight_refs </span><span class="ykcrMYlEiJ-c10">&lt;</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c35">1</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; BUG_ON</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">total_refs </span><span class="ykcrMYlEiJ-c10">&lt;</span><span class="ykcrMYlEiJ-c0">&nbsp;inflight_refs</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14 ykcrMYlEiJ-c7">if</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">total_refs </span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">==</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;inflight_refs</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">)</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list_move_tail</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(&amp;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">u</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">link</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">,</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">&amp;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">gc_candidates</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; __set_bit</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">UNIX_GC_CANDIDATE</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">,</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">&amp;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">u</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">gc_flags</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; __set_bit</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">UNIX_GC_MAYBE_CYCLE</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">,</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">&amp;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">u</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">gc_flags</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">}</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">}</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Next, the kernel removes any sockets that are referenced by other sockets outside of the current </span><span class="ykcrMYlEiJ-c3">gc_candidates</span><span>&nbsp;list. To do this, the kernel invokes </span><span class="ykcrMYlEiJ-c3">scan_children</span><span>&nbsp;(</span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://elixir.bootlin.com/linux/v4.14.277/source/net/unix/garbage.c#L138">garbage.c#138</a></span><span>) along with the function pointer </span><span class="ykcrMYlEiJ-c3">dec_inflight</span><span>&nbsp;to iterate through each candidate&rsquo;s </span><span class="ykcrMYlEiJ-c3">sk-&gt;receive_queue</span><span>.</span><span>&nbsp;It decreases the inflight count for each of the passed file descriptors that are themselves candidates for garbage collection (</span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://elixir.bootlin.com/linux/v4.14.277/source/net/unix/garbage.c#L261">garbage.c#L261</a></span><span class="ykcrMYlEiJ-c2">):</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><a id="t.fc28a79164e4bd7a8bdd4781c31aead0becb7e3a"></a><a id="t.9"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">/* Now remove all internal in-flight reference to children of</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;* the candidates.</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;*/</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">list_for_each_entry</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">u</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">&amp;</span><span class="ykcrMYlEiJ-c0">gc_candidates</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;link</span><span class="ykcrMYlEiJ-c10">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; scan_children</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">u</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">sk</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;dec_inflight</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;NULL</span><span class="ykcrMYlEiJ-c10">);</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>After iterating through all the candidates, if a gc candidate still has a positive inflight count it means that it is referenced by objects outside of the </span><span class="ykcrMYlEiJ-c3">gc_candidates</span><span>&nbsp;list and therefore is reachable. These candidates should not be included in the </span><span class="ykcrMYlEiJ-c3">gc_candidates</span><span class="ykcrMYlEiJ-c2">&nbsp;list so the related inflight counts need to be restored.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>To do this, the kernel will put the candidate to </span><span class="ykcrMYlEiJ-c3">not_cycle_list</span><span>&nbsp;instead and iterates through its receiver queue of each transmitted file in the </span><span class="ykcrMYlEiJ-c3">gc_candidates</span><span>&nbsp;</span><span>list</span><span>&nbsp;(</span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://elixir.bootlin.com/linux/v4.14.277/source/net/unix/garbage.c#L281">garbage.c#L281</a></span><span>) and increments the inflight count back. The entire process is done recursively, i</span><span>n order for the garbage collection to avoid purging reachable sockets:</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><a id="t.361a83de28e804a554f56db20f03ccfb1d948e58"></a><a id="t.10"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">/* Restore the references for children of all candidates,</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;* which have remaining references. &nbsp;Do this recursively, so</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;* only those remain, which form cyclic references.</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;*</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;* Use a &quot;cursor&quot; link, to make the list traversal safe, even</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;* though elements might be moved about.</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;*/</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">list_add</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">cursor</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">&amp;</span><span class="ykcrMYlEiJ-c0">gc_candidates</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c14">while</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">cursor</span><span class="ykcrMYlEiJ-c10">.</span><span class="ykcrMYlEiJ-c14">next</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">!=</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">&amp;</span><span class="ykcrMYlEiJ-c0">gc_candidates</span><span class="ykcrMYlEiJ-c10">)</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; u </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;list_entry</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">cursor</span><span class="ykcrMYlEiJ-c10">.</span><span class="ykcrMYlEiJ-c14">next</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;unix_sock</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;link</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c23">/* Move cursor to after the current position. */</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; list_move</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">cursor</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">&amp;</span><span class="ykcrMYlEiJ-c0">u</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">link</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14 ykcrMYlEiJ-c7">if</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">atomic_long_read</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(&amp;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">u</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">inflight</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">)</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c35 ykcrMYlEiJ-c7">0</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">)</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list_move_tail</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(&amp;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">u</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">link</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">,</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">&amp;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">not_cycle_list</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; __clear_bit</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">UNIX_GC_MAYBE_CYCLE</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">,</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">&amp;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">u</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">gc_flags</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; scan_children</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(&amp;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">u</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">sk</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">,</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;inc_inflight_move_tail</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">,</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;NULL</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">}</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">}</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">list_del</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">cursor</span><span class="ykcrMYlEiJ-c10">);</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Now </span><span class="ykcrMYlEiJ-c3">gc_candidates</span><span>&nbsp;contains only &ldquo;garbage&rdquo;. The kernel restores original inflight counts from </span><span class="ykcrMYlEiJ-c3">gc_candidates</span><span>, moves candidates from </span><span class="ykcrMYlEiJ-c3">not_cycle_list</span><span>&nbsp;back to </span><span class="ykcrMYlEiJ-c3">gc_inflight_list</span><span>&nbsp;and invokes </span><span class="ykcrMYlEiJ-c3">__skb_queue_purge</span><span>&nbsp;for cleaning up </span><span>garbage</span><span>&nbsp;(</span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://elixir.bootlin.com/linux/v4.14.277/source/net/unix/garbage.c#L306">garbage.c#L306</a></span><span class="ykcrMYlEiJ-c2">).</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><a id="t.193055a25333ec1cdf4b6d039bbb9233e94a0884"></a><a id="t.11"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">/* Now gc_candidates contains only garbage. &nbsp;Restore original</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;* inflight counters for these as well, and remove the skbuffs</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;* which are creating the cycle(s).</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;*/</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">skb_queue_head_init</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">hitlist</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">list_for_each_entry</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">u</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">&amp;</span><span class="ykcrMYlEiJ-c0">gc_candidates</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;link</span><span class="ykcrMYlEiJ-c10">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; scan_children</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">u</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">sk</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;inc_inflight</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">&amp;</span><span class="ykcrMYlEiJ-c0">hitlist</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">/* not_cycle_list contains those sockets which do not make up a</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;* cycle. &nbsp;Restore these to the inflight list.</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;*/</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c14">while</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(!</span><span class="ykcrMYlEiJ-c0">list_empty</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">not_cycle_list</span><span class="ykcrMYlEiJ-c10">))</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; u </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;list_entry</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">not_cycle_list</span><span class="ykcrMYlEiJ-c10">.</span><span class="ykcrMYlEiJ-c14">next</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;unix_sock</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;link</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; __clear_bit</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">UNIX_GC_CANDIDATE</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">&amp;</span><span class="ykcrMYlEiJ-c0">u</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">gc_flags</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; list_move_tail</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">u</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">link</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">&amp;</span><span class="ykcrMYlEiJ-c0">gc_inflight_list</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">}</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">spin_unlock</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">unix_gc_lock</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">/* Here we are. Hitlist is filled. Die. */</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">__skb_queue_purge</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(&amp;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">hitlist</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">);</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">spin_lock</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">unix_gc_lock</span><span class="ykcrMYlEiJ-c10">);</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c3">__skb_queue_purge</span><span>&nbsp;clears every </span><span class="ykcrMYlEiJ-c3">skb</span><span>&nbsp;from the receiver queue:</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><a id="t.ef5f1527ea6a99948aacf9ba31c9a016e0a52e01"></a><a id="t.12"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">/**</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;* &nbsp; &nbsp; &nbsp;__skb_queue_purge - empty a list</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;* &nbsp; &nbsp; &nbsp;@list: list to empty</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;*</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;* &nbsp; &nbsp; &nbsp;Delete all buffers on an &amp;sk_buff list. Each buffer is removed from</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;* &nbsp; &nbsp; &nbsp;the list and one reference dropped. This function does not take the</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;* &nbsp; &nbsp; &nbsp;list lock and the caller must hold the relevant locks to use it.</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;*/</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c14">void</span><span class="ykcrMYlEiJ-c0">&nbsp;skb_queue_purge</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;sk_buff_head </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">list</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c14">static</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c14">inline</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c14">void</span><span class="ykcrMYlEiJ-c0">&nbsp;__skb_queue_purge</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;sk_buff_head </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">list</span><span class="ykcrMYlEiJ-c10">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;sk_buff </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">skb</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">while</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">((</span><span class="ykcrMYlEiJ-c0">skb </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;__skb_dequeue</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">list</span><span class="ykcrMYlEiJ-c10">))</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">!=</span><span class="ykcrMYlEiJ-c0">&nbsp;NULL</span><span class="ykcrMYlEiJ-c10">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; kfree_skb</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">skb</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">}</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2">There are two ways to trigger the garbage collection process:</span></p><ol class="c27 lst-kix_58ja23nrczhl-0 start" start="1"><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c3">wait_for_unix_gc</span><span>&nbsp;is invoked at the beginning of the </span><span class="ykcrMYlEiJ-c3">sendmsg</span><span class="ykcrMYlEiJ-c2">&nbsp;function if there are more than 16,000 inflight sockets</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span>When a </span><span>socket file</span><span>&nbsp;is released by the kernel (i.e., a file descriptor is closed), the kernel will directly invoke </span><span class="ykcrMYlEiJ-c3">unix_gc</span><span class="ykcrMYlEiJ-c2">.</span></li></ol> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Note that </span><span class="ykcrMYlEiJ-c3">unix_gc</span><span>&nbsp;is not preemptive. If garbage collection is already in process, the kernel will not perform another </span><span class="ykcrMYlEiJ-c3">unix_gc</span><span class="ykcrMYlEiJ-c2">&nbsp;invocation.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Now, let&rsquo;s check this example (a breakable cycle) with a pair of sockets </span><span class="ykcrMYlEiJ-c8">f0</span><span class="ykcrMYlEiJ-c8 ykcrMYlEiJ-c40">0</span><span>&nbsp;and </span><span class="ykcrMYlEiJ-c8">f0</span><span class="ykcrMYlEiJ-c8 ykcrMYlEiJ-c40">1</span><span>,</span><span>&nbsp;and a single socket </span><span class="ykcrMYlEiJ-c15">&#x1d6fc;</span><span>:</span></p><ol class="c27 lst-kix_51hgl6mwb3et-0 start" start="1"><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span>Socket </span><span class="ykcrMYlEiJ-c8">f&#8239;</span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span>&nbsp;sends socket </span><span class="ykcrMYlEiJ-c8">f&#8239;</span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c8 ykcrMYlEiJ-c40">&nbsp;</span><span>to socket </span><span class="ykcrMYlEiJ-c8">f&#8239;</span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span>.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span>Socket </span><span class="ykcrMYlEiJ-c8">f&#8239;</span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;sends socket </span><span class="ykcrMYlEiJ-c8">f&#8239;</span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;to socket </span><span class="ykcrMYlEiJ-c15">&#x1d6fc;</span><span>.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span>Close </span><span class="ykcrMYlEiJ-c8">f&#8239;</span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span>.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span>Close </span><span class="ykcrMYlEiJ-c8">f&#8239;</span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span>.</span></li></ol> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2">Before starting the garbage collection process, the status of socket file descriptors are:</span></p><ul style="padding: 0;" class="c27 lst-kix_yzib59bcdnhj-0 start"><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">f&#8239;</span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c2">: ref = 1, inflight = 1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">f&#8239;</span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c2">: ref = 1, inflight = 1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c15">&#x1d6fc;</span><span class="ykcrMYlEiJ-c2">: ref = 1, inflight = 0</span></li></ul> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfD3EkqhRCP3nucxrm7-5h2T0Z0Q9e2xWhLX_CA07nU5IWXOAejwDvqPBd2CeJVLrM5bg502cpkm2noANVBV24QVmHRGA3IkHF_at3u6i2rYCHZH4wpvS5EfIC6ibJgtZb4LSO2IjdNbqw_PawxHzGAI9LtmhXRO5rv8SDTHa5mwncMXptSJmjnBZx/s834/image69.png" style="display: block; padding: 1em 0;text-align: center;"><img alt="f00, f01 and alpha form a breakable cycle." border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfD3EkqhRCP3nucxrm7-5h2T0Z0Q9e2xWhLX_CA07nU5IWXOAejwDvqPBd2CeJVLrM5bg502cpkm2noANVBV24QVmHRGA3IkHF_at3u6i2rYCHZH4wpvS5EfIC6ibJgtZb4LSO2IjdNbqw_PawxHzGAI9LtmhXRO5rv8SDTHa5mwncMXptSJmjnBZx/s834/image69.png" style="max-height: 750px; max-width: 600px;" title="f00, f01 and alpha form a breakable cycle." /></a></span></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c32">Breakable cycle by </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c32">, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c32">&nbsp;and </span><span class="ykcrMYlEiJ-c15">&#x1d6fc;</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>During the garbage collection process, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c8 ykcrMYlEiJ-c40">&nbsp;</span><span>and </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c8 ykcrMYlEiJ-c40">&nbsp;</span><span>are considered garbage candidates. The inflight count of </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span>&nbsp;is dropped to zero, but the count of </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;is still 1 because </span><span class="ykcrMYlEiJ-c15">&#x1d6fc;</span><span>&nbsp;is not a candidate. Thus, the kernel will restore the inflight count from </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span>&rsquo;s</span><span>&nbsp;receive queue. As a result, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span>&nbsp;and </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;are not treated as garbage anymore.</span></p><h1 class="ykcrMYlEiJ-c30 ykcrMYlEiJ-c20" id="h.rjtckjrq5zqp"><span class="ykcrMYlEiJ-c47 ykcrMYlEiJ-c39">CVE-2021-0920 </span><span class="ykcrMYlEiJ-c39 ykcrMYlEiJ-c47">Root Cause Analysis</span></h1> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>When</span><span>&nbsp;a user receives </span><span class="ykcrMYlEiJ-c3">SCM_RIGHTS</span><span>&nbsp;message from </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;without the </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag, the kernel will wait until the garbage collection process finishes if it is in progress. However, if the </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span class="ykcrMYlEiJ-c2">&nbsp;flag is on, the kernel will increment the reference count of the transmitted file structures without synchronizing with any ongoing garbage collection process. This may lead to inconsistency of the internal garbage collection state, making the garbage collector mark a non-garbage sock object as garbage to purge.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><h2 class="ykcrMYlEiJ-c20 ykcrMYlEiJ-c30" id="h.7lz5lcv6k4oi"><span>r</span><span class="ykcrMYlEiJ-c1">ecvmsg without MSG_PEEK flag</span></h2> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>The kernel function</span><span>&nbsp;</span><span class="ykcrMYlEiJ-c3">unix_stream_read_generic</span><span>&nbsp;(</span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://elixir.bootlin.com/linux/v4.14.277/source/net/unix/af_unix.c#L2290">af_unix.c#L2290</a></span><span>) parses the </span><span class="ykcrMYlEiJ-c3">SCM_RIGHTS</span><span>&nbsp;message and manages the file inflight count when the </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag is </span><span class="ykcrMYlEiJ-c39">NOT</span><span>&nbsp;set. Then, the function </span><span class="ykcrMYlEiJ-c3">unix_stream_read_generic</span><span>&nbsp;calls </span><span class="ykcrMYlEiJ-c3">unix_detach_fds</span><span>&nbsp;to decrement the inflight count. Then, </span><span class="ykcrMYlEiJ-c3">unix_detach_fds</span><span>&nbsp;clears the list of passed file descriptors (</span><span class="ykcrMYlEiJ-c3">scm_fp_list</span><span>) from the </span><span class="ykcrMYlEiJ-c3">skb</span><span class="ykcrMYlEiJ-c2">:</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><a id="t.0251da5f97c6a33bfc5ce0e11f69ded3f816103b"></a><a id="t.13"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c14">static</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c14">void</span><span class="ykcrMYlEiJ-c0">&nbsp;unix_detach_fds</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;scm_cookie </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">scm</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;sk_buff </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">skb</span><span class="ykcrMYlEiJ-c10">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">int</span><span class="ykcrMYlEiJ-c0">&nbsp;i</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; scm</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">fp </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;UNIXCB</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">skb</span><span class="ykcrMYlEiJ-c10">).</span><span class="ykcrMYlEiJ-c0">fp</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">UNIXCB</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">skb</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">).</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">fp </span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">=</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;NULL</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">;</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">for</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">i </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;scm</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">fp</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">count</span><span class="ykcrMYlEiJ-c10">-</span><span class="ykcrMYlEiJ-c35">1</span><span class="ykcrMYlEiJ-c10">;</span><span class="ykcrMYlEiJ-c0">&nbsp;i </span><span class="ykcrMYlEiJ-c10">&gt;=</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c35">0</span><span class="ykcrMYlEiJ-c10">;</span><span class="ykcrMYlEiJ-c0">&nbsp;i</span><span class="ykcrMYlEiJ-c10">--)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; unix_notinflight</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">scm</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">fp</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">user</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">,</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;scm</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">fp</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">fp</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">[</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">i</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">]);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">}</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>The </span><span class="ykcrMYlEiJ-c3">unix_notinflight</span><span>&nbsp;from </span><span class="ykcrMYlEiJ-c3">unix_detach_fds</span><span>&nbsp;will reverse the effect of </span><span class="ykcrMYlEiJ-c3">unix_inflight</span><span class="ykcrMYlEiJ-c2">&nbsp;by decrementing the inflight count:</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><a id="t.d890a653a46688c713ffbe9f71996b050052c85f"></a><a id="t.14"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c14">void</span><span class="ykcrMYlEiJ-c0">&nbsp;unix_notinflight</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;user_struct </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">user</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;file </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">fp</span><span class="ykcrMYlEiJ-c10">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;sock </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">s </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;unix_get_socket</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">fp</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; spin_lock</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">unix_gc_lock</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">if</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">s</span><span class="ykcrMYlEiJ-c10">)</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;unix_sock </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">u </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;unix_sk</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">s</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BUG_ON</span><span class="ykcrMYlEiJ-c10">(!</span><span class="ykcrMYlEiJ-c0">atomic_long_read</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">u</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">inflight</span><span class="ykcrMYlEiJ-c10">));</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BUG_ON</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">list_empty</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">u</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">link</span><span class="ykcrMYlEiJ-c10">));</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14 ykcrMYlEiJ-c7">if</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">atomic_long_dec_and_test</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(&amp;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">u</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">-&gt;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">inflight</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">))</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list_del_init</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">u</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">link</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; unix_tot_inflight</span><span class="ykcrMYlEiJ-c10">--;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c10">}</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; user</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">unix_inflight</span><span class="ykcrMYlEiJ-c10">--;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; spin_unlock</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">unix_gc_lock</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">}</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Later </span><span class="ykcrMYlEiJ-c3">skb_unlink</span><span>&nbsp;and </span><span class="ykcrMYlEiJ-c3">consume_skb</span><span>&nbsp;are invoked from </span><span class="ykcrMYlEiJ-c3">unix_stream_read_generic</span><span>&nbsp;</span><span>(</span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://elixir.bootlin.com/linux/v4.14.277/source/net/unix/af_unix.c#L2451">af_unix.c#2451</a></span><span>)</span><span>&nbsp;to destroy the current </span><span class="ykcrMYlEiJ-c3">skb</span><span>. Following the call chain </span><span class="ykcrMYlEiJ-c3">kfree(skb)-&gt;__kfree_skb</span><span>, the kernel will invoke the function pointer </span><span class="ykcrMYlEiJ-c3">skb-&gt;destructor</span><span>&nbsp;(</span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://elixir.bootlin.com/linux/v4.14.277/source/net/unix/af_unix.c#L1605">code</a></span><span>) which redirects to </span><span class="ykcrMYlEiJ-c3">unix_destruct_scm</span><span class="ykcrMYlEiJ-c2">:</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><a id="t.d928301c0cdf3e7a332926420806a793608d77ac"></a><a id="t.15"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c14">static</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c14">void</span><span class="ykcrMYlEiJ-c0">&nbsp;unix_destruct_scm</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;sk_buff </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">skb</span><span class="ykcrMYlEiJ-c10">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;scm_cookie scm</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; memset</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">scm</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c35">0</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c14">sizeof</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">scm</span><span class="ykcrMYlEiJ-c10">));</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; scm</span><span class="ykcrMYlEiJ-c10">.</span><span class="ykcrMYlEiJ-c0">pid &nbsp;</span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;UNIXCB</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">skb</span><span class="ykcrMYlEiJ-c10">).</span><span class="ykcrMYlEiJ-c0">pid</span><span class="ykcrMYlEiJ-c10">;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14 ykcrMYlEiJ-c7">if</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">UNIXCB</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">skb</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">).</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">fp</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; unix_detach_fds</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(&amp;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">scm</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">,</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;skb</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">);</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c23">/* Alas, it calls VFS */</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c23">/* So fscking what? fput() had been SMP-safe since the last Summer */</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; scm_destroy</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(&amp;</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">scm</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; sock_wfree</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">skb</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">}</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>In fact, the </span><span class="ykcrMYlEiJ-c3">unix_detach_fds</span><span>&nbsp;will not be invoked again here from </span><span class="ykcrMYlEiJ-c3">unix_destruct_scm</span><span>&nbsp;because </span><span class="ykcrMYlEiJ-c3">UNIXCB(skb).fp</span><span>&nbsp;is already cleared by </span><span class="ykcrMYlEiJ-c3">unix_detach_fds</span><span>. Finally, </span><span class="ykcrMYlEiJ-c3">fd_install(new_fd, get_file(fp[i]))</span><span>&nbsp;from </span><span class="ykcrMYlEiJ-c3">scm_detach_fds</span><span class="ykcrMYlEiJ-c2">&nbsp;is invoked for installing a new file descriptor.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><h2 class="ykcrMYlEiJ-c30 ykcrMYlEiJ-c20" id="h.yfq48nayx2kg"><span>r</span><span class="ykcrMYlEiJ-c1">ecvmsg with MSG_PEEK flag</span></h2> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>The </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;process is different i</span><span>f the </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag is set. The </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag is used during receive to &ldquo;peek&rdquo; at the message, but the data is treated as unread. </span><span class="ykcrMYlEiJ-c3">unix_stream_read_generic</span><span>&nbsp;will invoke </span><span class="ykcrMYlEiJ-c3">scm_fp_dup</span><span>&nbsp;instead of </span><span class="ykcrMYlEiJ-c3">unix_detach_fds</span><span>. </span><span>This increases the reference count of the inflight file (</span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://android.googlesource.com/kernel/goldfish/+/eee65a1282369eedfcbb664d0c865a0ef3eb7017/net/unix/af_unix.c#2149">af_unix.c#2149</a></span><span>)</span><span>:</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><a id="t.54ddd657e781757bb7c1f32330ad770b045c0ed3"></a><a id="t.16"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">/* It is questionable, see note in unix_dgram_recvmsg.</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c23">&nbsp;*/</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c14 ykcrMYlEiJ-c7">if</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">UNIXCB</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">skb</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">).</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">fp</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp; &nbsp; &nbsp; &nbsp; scm</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">.</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">fp </span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">=</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">&nbsp;scm_fp_dup</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">UNIXCB</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">(</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">skb</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">).</span><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c7">fp</span><span class="ykcrMYlEiJ-c10 ykcrMYlEiJ-c7">);</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">sk_peek_offset_fwd</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">sk</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;chunk</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c29"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13"></span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c14">if</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">UNIXCB</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">skb</span><span class="ykcrMYlEiJ-c10">).</span><span class="ykcrMYlEiJ-c0">fp</span><span class="ykcrMYlEiJ-c10">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">break</span><span class="ykcrMYlEiJ-c10">;</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Because the data should be treated as unread, the </span><span class="ykcrMYlEiJ-c3">skb</span><span>&nbsp;is not unlinked and consumed when the </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span class="ykcrMYlEiJ-c2">&nbsp;flag is set. However, the receiver will still get a new file descriptor for the inflight socket.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><h2 class="ykcrMYlEiJ-c30 ykcrMYlEiJ-c20" id="h.4kuedi8b9x2y"><span>recvmsg </span><span>Examples</span></h2> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2">Let&rsquo;s see a concrete example. Assume there are the following socket pairs:</span></p><ul style="padding: 0;" class="c27 lst-kix_k47gmg94hbw2-0 start"><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span></li></ul> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2">Now, the program does the following operations:</span></p><ul style="padding: 0;" class="c27 lst-kix_8chkxhfzc2ds-0 start"><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span>&nbsp;&rarr; [</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span>] &rarr; </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1 </span><span>(means </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span>&nbsp;sends [</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span>] to </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c2">)</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span>&nbsp;&rarr; [</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span>] &rarr; </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="c11 c19 c37">1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">Close</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c15">)</span></li></ul> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi5B8kJXBAiYH3vq8NcQtmatM_hz8o9KgBZpMbMyd9QwRC84jh-SZo76fLhvSFrRohs4pUhBW48q3fQ0bUu0DlySHyJhDMC69rz8qwEM8nHK4b1RGLMw9QGwPmf4E7iMjo5Noa6eF-GDEuMqa4Gzq0fwiBCXU_x0i_Q7eGd2OqiIbu7lYFFaErVE5o/s1102/image62.png" style="display: block; padding: 1em 0;text-align: center;"><img alt="f00, f01, f10, f11 forms a breakable cycle." border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi5B8kJXBAiYH3vq8NcQtmatM_hz8o9KgBZpMbMyd9QwRC84jh-SZo76fLhvSFrRohs4pUhBW48q3fQ0bUu0DlySHyJhDMC69rz8qwEM8nHK4b1RGLMw9QGwPmf4E7iMjo5Noa6eF-GDEuMqa4Gzq0fwiBCXU_x0i_Q7eGd2OqiIbu7lYFFaErVE5o/s1102/image62.png" style="max-height: 750px; max-width: 600px;" title="f00, f01, f10, f11 forms a breakable cycle." /></a></span></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c32">Breakable cycle by </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span>&nbsp;</span><span class="ykcrMYlEiJ-c32">and</span><span>&nbsp;</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2">Here is the status:</span></p><ul style="padding: 0;" class="c27 lst-kix_9gryrzygx46m-0 start"><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c15">) = 2, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="c13 c19 c15">) = 2</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 0, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span class="c13 c19 c15">) = 1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c15">) = 0, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="c13 c19 c15">) = 1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 0, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 1</span></li></ul> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>If the garbage collection process happens now, before any </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;calls, the kernel will choose </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span>&nbsp;as the garbage candidate. However, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span>&nbsp;will not have the inflight count altered and the kernel will not purge any garbage.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>I</span><span>f </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;then calls </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;</span><span class="ykcrMYlEiJ-c39">with</span><span>&nbsp;</span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag, t</span><span>he receive queue doesn&rsquo;t change and the inflight counts are not decremented. </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;gets a new file descriptor </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c8">&#39;</span><span>&nbsp;which increments the </span><span>reference count on </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c2">:</span></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO9D3ODJFXZt6dQmkyP1e7zZe0smN042wAbdy7isVbd407L-oCrSDS9LDCBshKwft2pWiuKHXQBclib4tQFoou-8U14ZNuyeJMRxDjtuFsTk3B_TDHVQNDl5x8aLt09negBlNpoEzrYgybadh-KbAAGu_U4hqaDNLyOpWFbI06Vjfh1kam2JHuD7yH/s1216/image63.png" style="display: block; padding: 1em 0;text-align: center;"><img alt="After f01 receives the socket file descriptor by MSG_PEEK, the reference count of f00 is incremented and the receive queue from f01 remains the same." border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO9D3ODJFXZt6dQmkyP1e7zZe0smN042wAbdy7isVbd407L-oCrSDS9LDCBshKwft2pWiuKHXQBclib4tQFoou-8U14ZNuyeJMRxDjtuFsTk3B_TDHVQNDl5x8aLt09negBlNpoEzrYgybadh-KbAAGu_U4hqaDNLyOpWFbI06Vjfh1kam2JHuD7yH/s1216/image63.png" style="max-height: 750px; max-width: 600px;" title="After f01 receives the socket file descriptor by MSG_PEEK, the reference count of f00 is incremented and the receive queue from f01 remains the same." /></a></span></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c3 ykcrMYlEiJ-c38">MSG_PEEK</span><span class="ykcrMYlEiJ-c32">&nbsp;increment the reference count of </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="c34 c19 c32">&nbsp;while the receive queue is not cleared</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2">Status:</span></p><ul style="padding: 0;" class="c27 lst-kix_9gryrzygx46m-0"><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c15">) = 2, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="c13 c19 c15">) = 3</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 0, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span class="c50 c19 c49 c42">) = 1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c15">) = 0, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="c50 c19 c49 c42">) = 1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 0, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 1</span></li></ul> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Then, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;calls </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;</span><span class="ykcrMYlEiJ-c39">without</span><span>&nbsp;</span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span>&rsquo;s receive queue is removed. </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;also fetches a new file descriptor </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c8">&#39;&#39;</span><span class="ykcrMYlEiJ-c2">:</span></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNsC7ADpPbHG_EVgFzDOGi6oaXluRrxDKc6kaQAkdwadnfFOu4SbwVESi0-SGHDwu9La-ztndastPnhfiocmhd6fmU0mhCy9a5sDosCQu6eW3x_uu7wHGL5d1c0eMTO3inZlhObh4faQkcGU2fM6zd-cXDjbg6fjS6CKUMpT8Sre9XHefE7Exrt04s/s1344/image67.png" style="display: block; padding: 1em 0;text-align: center;"><img alt="After f01 receives the socket file descriptor without MSG_PEEK, the receive queue is cleared and file descriptor f00&#39;&#39;&#39; is obtained." border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNsC7ADpPbHG_EVgFzDOGi6oaXluRrxDKc6kaQAkdwadnfFOu4SbwVESi0-SGHDwu9La-ztndastPnhfiocmhd6fmU0mhCy9a5sDosCQu6eW3x_uu7wHGL5d1c0eMTO3inZlhObh4faQkcGU2fM6zd-cXDjbg6fjS6CKUMpT8Sre9XHefE7Exrt04s/s1200/image67.png" style="max-height: 750px; max-width: 600px;" title="After f01 receives the socket file descriptor without MSG_PEEK, the receive queue is cleared and file descriptor f00&#39;&#39;&#39; is obtained." /></a></span></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c32">The receive queue of </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c32">&nbsp;is cleared and </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c8">&#39;&#39;</span><span class="ykcrMYlEiJ-c32">&nbsp;is obtained from </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2">Status:</span></p><ul style="padding: 0;" class="c27 lst-kix_9gryrzygx46m-0"><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c15">) = 1, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="c13 c19 c15">) = 3</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 0, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span class="c13 c15 c19">) = 1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c15">) = 0, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="c50 c19 c49 c42">) = 1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 0, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 1</span></li></ul> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><h2 class="ykcrMYlEiJ-c30 ykcrMYlEiJ-c20" id="h.v0psi01ks7q2"><span class="ykcrMYlEiJ-c1">UAF Scenario</span></h2> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>From a very high level perspective, the internal state of Linux garbage collection can be non-deterministic because </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;is not synchronized with the garbage collector. T</span><span>here is a race condition where the garbage collector can treat an inflight socket as a garbage candidate while the file reference is incremented at the same time during the </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;receive. As a consequence, the garbage collector may purge the candidate, freeing the socket buffer, while a receiver may install the file descriptor, leading to a UAF on the </span><span class="ykcrMYlEiJ-c3">skb</span><span class="ykcrMYlEiJ-c2">&nbsp;object.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Let&rsquo;s see how the captured </span><span>0-day</span><span>&nbsp;sample triggers the bug step by step (simplified version, in reality you may need more threads working together, but it should demonstrate the core idea). First of all, the sample allocates the following socket pairs and single socket </span><span class="ykcrMYlEiJ-c15">&#x1d6fc;</span><span>:</span></p><ul style="padding: 0;" class="c27 lst-kix_whw4pjgxp3w1-0 start"><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">2</span><span class="ykcrMYlEiJ-c11">0</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">2</span><span class="ykcrMYlEiJ-c11">1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">3</span><span class="ykcrMYlEiJ-c11">0</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">3</span><span class="ykcrMYlEiJ-c11">1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">sock</span><span class="ykcrMYlEiJ-c15">&nbsp;&#x1d6fc;</span><span>&nbsp;(actually there might be even thousands of </span><span class="ykcrMYlEiJ-c15">&#x1d6fc;</span><span>&nbsp;for protracting the garbage collection process in order to evade a </span><span class="ykcrMYlEiJ-c3">BUG_ON</span><span class="ykcrMYlEiJ-c2">&nbsp;check which will be introduced later).</span></li></ul> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Now, the program does the below operations:</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAHUeccUboPeEe8ydW1HHpM2R-iibCZnsJSrhByCsnhQHtW4IJcC_8GEPtO3R3GPV5x2C9xJfxT7l6Z3UoqRcUeMtuf65G9wI2tPnd91q_vO7spVOfZgAwjeC6WCILmjs1ED618PGlxgMp196O3odP-fKaqIloMSEYRNory126HtXPNyyXCUWefJew/s564/image17.png" style="display: block; padding: 1em 0;text-align: left;"><img alt="" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAHUeccUboPeEe8ydW1HHpM2R-iibCZnsJSrhByCsnhQHtW4IJcC_8GEPtO3R3GPV5x2C9xJfxT7l6Z3UoqRcUeMtuf65G9wI2tPnd91q_vO7spVOfZgAwjeC6WCILmjs1ED618PGlxgMp196O3odP-fKaqIloMSEYRNory126HtXPNyyXCUWefJew/s564/image17.png" style="max-height: 750px; max-width: 250px; border:0; box-shadow: none; --webkit-box-shadow: none; --moz-box-shadow: none;" title="" /></a></span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Close the following file descriptors prior to any </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span class="ykcrMYlEiJ-c2">&nbsp;calls:</span></p><ul style="padding: 0;" class="c27 lst-kix_9gryrzygx46m-0"><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">Close</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="c13 c19 c15">)</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">Close</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span class="c50 c19 c49 c42">)</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">Close</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span class="c50 c19 c49 c42">)</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">Close</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="c13 c19 c15">)</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">Close</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">3</span><span class="ykcrMYlEiJ-c11">0</span><span class="c13 c19 c15">)</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">Close</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">3</span><span class="ykcrMYlEiJ-c11">1</span><span class="c13 c19 c15">)</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">Close</span><span class="ykcrMYlEiJ-c15">(&#x1d6fc;)</span></li></ul> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Here is the status:</span></p><ul style="padding: 0;" class="c27 lst-kix_9gryrzygx46m-0"><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c15">) = </span><span class="ykcrMYlEiJ-c8">N</span><span class="ykcrMYlEiJ-c15">&nbsp;+ 1, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c15">) = </span><span class="ykcrMYlEiJ-c8">N </span><span class="c13 c19 c15">+ 1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 2, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span class="c13 c19 c15">) = 2</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c15">) = 3, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="c13 c19 c15">) = 3</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 1, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span class="c50 c19 c49 c42">) = 1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">2</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c15">) = 0, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">2</span><span class="ykcrMYlEiJ-c11">0</span><span class="c50 c19 c49 c42">) = 1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">2</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 0, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">2</span><span class="ykcrMYlEiJ-c11">1</span><span class="c13 c19 c15">) = 1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">3</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 1, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">3</span><span class="ykcrMYlEiJ-c11">1</span><span class="c50 c19 c49 c42">) = 1</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c15">&#x1d6fc;</span><span class="ykcrMYlEiJ-c15">) = 1, </span><span class="ykcrMYlEiJ-c8">ref</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c15">&#x1d6fc;</span><span class="ykcrMYlEiJ-c15">) = 1</span></li></ul> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2">If the garbage collection process happens now, the kernel will do the following scrutiny:</span></p><ul style="padding: 0;" class="c27 lst-kix_h1p96gz9lzq4-0 start"><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span>List </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span>, &nbsp;</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">3</span><span class="ykcrMYlEiJ-c11">1</span><span>, </span><span class="ykcrMYlEiJ-c15">&#x1d6fc;</span><span class="ykcrMYlEiJ-c2">&nbsp;as garbage candidates. Decrease inflight count for the candidate children in each receive queue.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span>Since </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">2</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;is not considered a candidate, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c2">&rsquo;s inflight count is still above zero.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c2">Recursively restore the inflight count.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c2">Nothing is considered garbage.</span></li></ul> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2">A potential skb UAF by race condition can be triggered by:</span></p><ol class="c27 lst-kix_j5vmamheymgq-0 start" start="1"><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span>Call </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;with </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag from </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">2</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;to get </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c2">&rsquo;.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span>Call </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;with </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag from </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;to get </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c2">&rsquo;.</span></li><li style="margin-left: 46pt;" class="c12 c20 c25 li-bullet-0"><span class="ykcrMYlEiJ-c2">Concurrently do the following operations:</span></li></ol><ol class="c27 lst-kix_j5vmamheymgq-1 start" start="1"><li style="margin-left: 46pt;" class="c12 c21 c20 li-bullet-0"><span>Call </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;without </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag from </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;to get </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c2">&rsquo;&rsquo;.</span></li><li style="margin-left: 46pt;" class="c12 c20 c21 li-bullet-0"><span>Call </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;with </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag from </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c2">&rsquo;</span></li></ol> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2">How is it possible? Let&rsquo;s see a case where the race condition is not hit so there is no UAF:</span></p><a id="t.b47553220f0960b2834e887266a030fb4dc49b24"></a><a id="t.17"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Thread 0</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Thread 1</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Thread 2</span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Call unix_gc</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span>Stage0: List </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span>, &nbsp;</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">3</span><span class="ykcrMYlEiJ-c11">1</span><span>, </span><span class="ykcrMYlEiJ-c15">&#x1d6fc;</span><span class="ykcrMYlEiJ-c15">&nbsp;</span><span class="ykcrMYlEiJ-c2">as garbage candidates.</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span>Call </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;with </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag from </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">2</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;to get </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c2">&rsquo;</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span>Increase reference count: </span><span class="ykcrMYlEiJ-c3">scm.fp = scm_fp_dup(</span><span class="ykcrMYlEiJ-c3">UNIXCB</span><span class="ykcrMYlEiJ-c3">(skb).fp);</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Stage0: decrease inflight count from the child of every garbage candidate</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Status after stage 0:</span></p> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c15">) = 0</span></p> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 0</span></p> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c15">) = 0</span></p> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 1</span></p> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">3</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 0</span></p> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(&#x1d6fc;) = 0</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Stage1: Recursively restore inflight count if a candidate still has inflight count. </span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Stage1: All inflight counts have been restored.</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Stage2: No garbage, return.</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span>Call </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;with </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag from </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;to get </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c2">&rsquo;</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span>Call </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;without </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag from </span><span class="ykcrMYlEiJ-c8">f&#8239;</span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;to get </span><span class="ykcrMYlEiJ-c8">f&#8239;</span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c2">&rsquo;&rsquo;</span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span>Call </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;with </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag from </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c2">&rsquo;</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Everyone is happy</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Everyone is happy</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Everyone is happy</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>However, if the second </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;occurs </span><span>just after stage </span><span class="ykcrMYlEiJ-c2">1 of the garbage collection process, the UAF is triggered:</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><a id="t.4cb3bda9bda9e3eb3317a2b662883e2cb8968cd6"></a><a id="t.18"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Thread 0</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Thread 1</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Thread 2</span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Call unix_gc</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span>Stage0: List </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span>, &nbsp;</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">3</span><span class="ykcrMYlEiJ-c11">1</span><span>, </span><span class="ykcrMYlEiJ-c15">&#x1d6fc;</span><span class="ykcrMYlEiJ-c15">&nbsp;</span><span class="ykcrMYlEiJ-c2">as garbage candidates.</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span>Call </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;with </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag from </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">2</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;to get </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c2">&rsquo;</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span>Increase reference count: </span><span class="ykcrMYlEiJ-c3">scm.fp = scm_fp_dup(</span><span class="ykcrMYlEiJ-c3">UNIXCB</span><span class="ykcrMYlEiJ-c3">(skb).fp);</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Stage0: decrease inflight count from the child of every garbage candidates</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Status after stage 0:</span></p> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c15">) = 0</span></p> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 0</span></p> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c15">) = 0</span></p> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 1</span></p> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(</span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">3</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c15">) = 0</span></p> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c8">inflight</span><span class="ykcrMYlEiJ-c15">(&#x1d6fc;) = 0</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Stage1: Start restoring inflight count.</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span>Call </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;with </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag from </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;to get </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c2">&rsquo;</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c46"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span>Call </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;without </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag from </span><span class="ykcrMYlEiJ-c8">f&#8239;</span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;to get </span><span class="ykcrMYlEiJ-c8">f&#8239;</span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c2">&rsquo;&rsquo;</span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c3">unix_detach_fds</span><span>: </span><span class="ykcrMYlEiJ-c3">UNIXCB</span><span class="ykcrMYlEiJ-c3">(skb).fp = NULL</span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span>Blocked by </span><span class="ykcrMYlEiJ-c3">spin_lock(&amp;unix_gc_lock)</span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span>Stage1: </span><span class="ykcrMYlEiJ-c3">scan_inflight</span><span>&nbsp;cannot find candidate children from </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c2">. Thus, the inflight count accidentally remains the same.</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span>Stage2: </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">1</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span>, </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">3</span><span class="ykcrMYlEiJ-c11">1</span><span>, </span><span class="ykcrMYlEiJ-c15">&#x1d6fc;</span><span class="ykcrMYlEiJ-c2">&nbsp;are garbage.</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Stage2: start purging garbage.</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span>Start calling </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;with </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag from </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span>&rsquo;, which would expect to receive </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">0</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c2">&#39;</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span>Get </span><span class="ykcrMYlEiJ-c3">skb = skb_peek(&amp;sk-&gt;sk_receive_queue)</span><span>, </span><span class="ykcrMYlEiJ-c3">skb</span><span class="ykcrMYlEiJ-c2">&nbsp;is going to be freed by thread 0.</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span>Stage2: for</span><span><img alt="" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRTVI1goYtLkJZYRh0P5Wj_jeCjDeIhbMLEzwbzMCMWdag6uBicpIv7TtDorvArzkMmQGMRq6Ss5WdVDwyKTZE9frPBY44fOF667d2D7rKxarcAfp9x9t-YrNRielyFYOgI0998OI0TplaeHW7CGyz4SAFs2udorAlUMxe4gaCPYqr2zP9AjmKbyip/s260/image18.png" style="max-height: 750px; max-width: 100px; box-shadow: none; --webkit-box-shadow: none; --moz-box-shadow: none; border:0; display: inline;" title="" />, calls </span><span class="ykcrMYlEiJ-c3">__skb_unlink</span><span>&nbsp;and </span><span class="ykcrMYlEiJ-c3">kfree_skb</span><span class="ykcrMYlEiJ-c2">&nbsp;later.</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c3">state-&gt;recv_actor(skb, skip, chunk, state)</span><span>&nbsp;</span><span class="c34 c19 c7 c39 c42">UAF</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">GC finished.</span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span class="ykcrMYlEiJ-c2">Start garbage collection.</span></p></td></tr><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c6"><span class="ykcrMYlEiJ-c2"></span></p></td><td class="ykcrMYlEiJ-c4" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c22"><span>Get </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">0</span><span class="ykcrMYlEiJ-c2">&rsquo;&rsquo;</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Therefore, the race condition causes a UAF of the skb object. At first glance, we should blame the second </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;syscall because it clears </span><span class="ykcrMYlEiJ-c3">skb.fp</span><span>, the passed file list.</span><span>&nbsp;However, if the first </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;syscall doesn&rsquo;t set the </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag, the UAF can be avoided because </span><span class="ykcrMYlEiJ-c3">unix_notinflight</span><span>&nbsp;is serialized with the garbage collection. In other words, the kernel makes sure the garbage collection is either not processed or finished before decrementing the inflight count and removing the skb. After </span><span class="ykcrMYlEiJ-c3">unix_notinflight</span><span>, the receiver obtains </span><span class="ykcrMYlEiJ-c8">f</span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span class="ykcrMYlEiJ-c2">&#39; and inflight sockets don&#39;t form an unbreakable cycle.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Since </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;is not serialized with the garbage collection, when </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span>&nbsp;is called with </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;set, the kernel still considers </span><span class="ykcrMYlEiJ-c8">f </span><span class="ykcrMYlEiJ-c15">1</span><span class="ykcrMYlEiJ-c11">1</span><span>&nbsp;as a garbage candidate. For this reason, the following next </span><span class="ykcrMYlEiJ-c3">recvmsg</span><span class="ykcrMYlEiJ-c2">&nbsp;will eventually trigger the bug due to the inconsistent state of the garbage collection process.</span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2">&nbsp;</span></p><h1 class="ykcrMYlEiJ-c30 ykcrMYlEiJ-c20" id="h.wrjvlggcdxoy"><span class="ykcrMYlEiJ-c47 ykcrMYlEiJ-c39">Patch Analysis</span></h1><h2 class="ykcrMYlEiJ-c30 ykcrMYlEiJ-c20" id="h.de5p59plssty"><span class="ykcrMYlEiJ-c1">CVE-2021-0920 was found in 2016</span></h2> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>The vulnerability was </span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://patchwork.ozlabs.org/project/netdev/patch/CAOssrKcfncAYsQWkfLGFgoOxAQJVT2hYVWdBA6Cw7hhO8RJ_wQ@mail.gmail.com/">initially reported to the Linux kernel community in 2016</a></span><span class="ykcrMYlEiJ-c2">. The researcher also provided the correct patch advice but it was not accepted by the Linux kernel community:</span></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8WLJ5TaSrwBSyzsB2cnn3WlhRBqZzDHyOAnU8PWvMGr9d2l85FCYHw8fwiHRmFRMtPBMSe3kcFyISMGzuqmFyc0Ks5gJymqNPxh_kHdy59iHrUXTkpc5MTEyoOSroIHMzmqgQCibycvyxMRR-kUmjKIB3y0kqNHvN1TQULEUY8f04pIe65f-z3l3A/s1202/image65.png" style="display: block; padding: 1em 0;text-align: center;"><img alt="Linux kernel developers: Why would I apply a patch that&#39;s an RFC, doesn&#39;t have a proper commit message, lacks a proper signoff, and also lacks ACK&#39;s and feedback from other knowledgable developers?" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8WLJ5TaSrwBSyzsB2cnn3WlhRBqZzDHyOAnU8PWvMGr9d2l85FCYHw8fwiHRmFRMtPBMSe3kcFyISMGzuqmFyc0Ks5gJymqNPxh_kHdy59iHrUXTkpc5MTEyoOSroIHMzmqgQCibycvyxMRR-kUmjKIB3y0kqNHvN1TQULEUY8f04pIe65f-z3l3A/s1202/image65.png" style="max-height: 750px; max-width: 600px;" title="Linux kernel developers: Why would I apply a patch that&#39;s an RFC, doesn&#39;t have a proper commit message, lacks a proper signoff, and also lacks ACK&#39;s and feedback from other knowledgable developers?" /></a></span></p> <p class="ykcrMYlEiJ-c31 ykcrMYlEiJ-c20"><span class="c34 c19 c32">Patch was not applied in 2016</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c2">In theory, anyone who saw this patch might come up with an exploit against the faulty garbage collector. </span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><h2 class="ykcrMYlEiJ-c30 ykcrMYlEiJ-c20" id="h.4z83prp6b89e"><span class="ykcrMYlEiJ-c41">Patch in 2021</span></h2> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Let&rsquo;s check the official </span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://lore.kernel.org/lkml/20210802134333.066918619@linuxfoundation.org/">patch</a></span><span>&nbsp;</span><span>for CVE-2021-0920. For the </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;branch, it </span><span>requests the</span><span>&nbsp;garbage collection lock </span><span class="ykcrMYlEiJ-c3">unix_gc_lock</span><span>&nbsp;before performing sensitive actions</span><span class="ykcrMYlEiJ-c2">&nbsp;and immediately releases it afterwards:</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><a id="t.35ff1e948ec741d79429e84cee5745d3afcaaae5"></a><a id="t.19"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">&hellip;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">+</span><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp;spin_lock</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">unix_gc_lock</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">+</span><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp;spin_unlock</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">unix_gc_lock</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">&hellip;</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>The patch is confusing - it&rsquo;s rare to see such lock usage in software development. Regardless, the </span><span class="ykcrMYlEiJ-c3">MSG_PEEK</span><span>&nbsp;flag now waits for the completion of the garbage collector, so the UAF issue is resolved.</span></p><h2 class="ykcrMYlEiJ-c30 ykcrMYlEiJ-c20" id="h.9ft0l34fnpmk"><span class="ykcrMYlEiJ-c41">BUG_ON Added in 2017</span></h2> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>Andrey Ulanov from Google in 2017 found another issue in </span><span class="ykcrMYlEiJ-c3">unix_gc</span><span>&nbsp;and provided a fix </span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://lore.kernel.org/lkml/20170315031642.19576-1-andreyu@google.com/">commit</a></span><span>. Additionally, the patch added a </span><span class="ykcrMYlEiJ-c3">BUG_ON</span><span class="ykcrMYlEiJ-c2">&nbsp;for the inflight count:</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><a id="t.9ddfb92c81bd3f8420f9ee8f3bc9bd197a02f533"></a><a id="t.20"></a><table class="ykcrMYlEiJ-c33"><tr class="ykcrMYlEiJ-c17"><td class="ykcrMYlEiJ-c18" colspan="1" rowspan="1"> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c14">void</span><span class="ykcrMYlEiJ-c0">&nbsp;unix_notinflight</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;user_struct </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">user</span><span class="ykcrMYlEiJ-c10">,</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;file </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">fp</span><span class="ykcrMYlEiJ-c10">)</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">if</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">s</span><span class="ykcrMYlEiJ-c10">)</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">{</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">struct</span><span class="ykcrMYlEiJ-c0">&nbsp;unix_sock </span><span class="ykcrMYlEiJ-c10">*</span><span class="ykcrMYlEiJ-c0">u </span><span class="ykcrMYlEiJ-c10">=</span><span class="ykcrMYlEiJ-c0">&nbsp;unix_sk</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">s</span><span class="ykcrMYlEiJ-c10">);</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13">&nbsp;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c10">+</span><span class="ykcrMYlEiJ-c0">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BUG_ON</span><span class="ykcrMYlEiJ-c10">(!</span><span class="ykcrMYlEiJ-c0">atomic_long_read</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">u</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">inflight</span><span class="ykcrMYlEiJ-c10">));</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BUG_ON</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">list_empty</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">u</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">link</span><span class="ykcrMYlEiJ-c10">));</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0 ykcrMYlEiJ-c13">&nbsp;</span></p> <p class="ykcrMYlEiJ-c12"><span class="ykcrMYlEiJ-c0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="ykcrMYlEiJ-c14">if</span><span class="ykcrMYlEiJ-c0">&nbsp;</span><span class="ykcrMYlEiJ-c10">(</span><span class="ykcrMYlEiJ-c0">atomic_long_dec_and_test</span><span class="ykcrMYlEiJ-c10">(&amp;</span><span class="ykcrMYlEiJ-c0">u</span><span class="ykcrMYlEiJ-c10">-&gt;</span><span class="ykcrMYlEiJ-c0">inflight</span><span class="ykcrMYlEiJ-c10">))</span></p></td></tr></table> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>At first glance, i</span><span>t seems that</span><span>&nbsp;the </span><span class="ykcrMYlEiJ-c3">BUG_ON</span><span>&nbsp;can prevent CVE-2021-0920 from being exploitable. However, if the exploit code can delay garbage collection by crafting a large amount of fake garbage, &nbsp;it can waive the </span><span class="ykcrMYlEiJ-c3">BUG_ON</span><span>&nbsp;check by heap spray.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p><h2 class="ykcrMYlEiJ-c30 ykcrMYlEiJ-c20" id="h.f7eb84wuwvc6"><span class="ykcrMYlEiJ-c41">New Garbage Collection</span><span>&nbsp;</span><span class="ykcrMYlEiJ-c41">Discovered </span><span>in 2021</span></h2> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>CVE-2021-4083 deserves an honorable mention: when I </span><span>discussed</span><span>&nbsp;CVE-2021-0920 with Jann Horn and Ben Hawkes, Jann found another </span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://bugs.chromium.org/p/project-zero/issues/detail?id=2247">issue</a></span><span>&nbsp;in the garbage collection, described in the Project Zero blog post </span><span class="ykcrMYlEiJ-c9"><a class="ykcrMYlEiJ-c261" href="https://googleprojectzero.blogspot.com/2022/03/racing-against-clock-hitting-tiny.html">Racing against the clock -- hitting a tiny kernel race window</a></span><span class="ykcrMYlEiJ-c2">.</span></p> \<h1 class="ykcrMYlEiJ-c30 ykcrMYlEiJ-c20" id="h.4yx7dnb7u7k1"><span class="ykcrMYlEiJ-c36 ykcrMYlEiJ-c34">Part I Conclusion</span></h1> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c28">To recap, we have discussed the kernel internals of </span><span class="ykcrMYlEiJ-c3 ykcrMYlEiJ-c28">SCM_RIGHTS</span><span class="ykcrMYlEiJ-c28">&nbsp;and the designs and implementations of the Linux kernel garbage collector. Besides, we have analyzed the behavior of </span><span class="ykcrMYlEiJ-c3 ykcrMYlEiJ-c28">MSG_PEEK</span><span class="ykcrMYlEiJ-c28">&nbsp;flag with the </span><span class="ykcrMYlEiJ-c3 ykcrMYlEiJ-c28">recvmsg</span><span class="ykcrMYlEiJ-c2 ykcrMYlEiJ-c28">&nbsp;syscall and how it leads to a kernel UAF by a subtle and arcane race condition.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2 ykcrMYlEiJ-c28"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span class="ykcrMYlEiJ-c28">The bug was spotted in 2016 publicly, but unfortunately the Linux kernel community did not accept the patch at that time. Any threat actors who saw the public email thread may have a chance to develop an LPE exploit against the Linux kernel.</span></p> <p class="ykcrMYlEiJ-c5"><span class="ykcrMYlEiJ-c2"></span></p> <p class="ykcrMYlEiJ-c12 ykcrMYlEiJ-c20"><span>In part two, we&#39;ll look at how the vulnerability was exploited and the functionalities of the post compromise modules.</span></p> <div style='clear: both;'></div> </div> <div class='post-footer'> <div class='post-footer-line post-footer-line-1'> <span class='post-author vcard'> Posted by <span class='fn' itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://www.blogger.com/profile/08975904405228580347' itemprop='url'/> <a class='g-profile' href='https://www.blogger.com/profile/08975904405228580347' rel='author' title='author profile'> <span itemprop='name'>Google Project Zero</span> </a> </span> </span> <span class='post-timestamp'> at <meta content='https://googleprojectzero.blogspot.com/2022/08/the-quantum-state-of-linux-kernel.html' itemprop='url'/> <a class='timestamp-link' href='https://googleprojectzero.blogspot.com/2022/08/the-quantum-state-of-linux-kernel.html' rel='bookmark' title='permanent link'><abbr class='published' itemprop='datePublished' title='2022-08-10T16:00:00-07:00'>4:00&#8239;PM</abbr></a> </span> <span class='post-comment-link'> </span> <span class='post-icons'> <span class='item-control blog-admin pid-1053444070'> <a href='https://www.blogger.com/post-edit.g?blogID=4838136820032157985&postID=6481767562526230244&from=pencil' title='Edit Post'> <img alt='' class='icon-action' height='18' src='https://resources.blogblog.com/img/icon18_edit_allbkg.gif' width='18'/> </a> </span> </span> <div class='post-share-buttons goog-inline-block'> <a class='goog-inline-block share-button sb-email' href='https://www.blogger.com/share-post.g?blogID=4838136820032157985&postID=6481767562526230244&target=email' target='_blank' title='Email This'><span class='share-button-link-text'>Email This</span></a><a class='goog-inline-block share-button sb-blog' href='https://www.blogger.com/share-post.g?blogID=4838136820032157985&postID=6481767562526230244&target=blog' onclick='window.open(this.href, "_blank", "height=270,width=475"); return false;' target='_blank' title='BlogThis!'><span class='share-button-link-text'>BlogThis!</span></a><a class='goog-inline-block share-button sb-twitter' href='https://www.blogger.com/share-post.g?blogID=4838136820032157985&postID=6481767562526230244&target=twitter' target='_blank' title='Share to X'><span class='share-button-link-text'>Share to X</span></a><a class='goog-inline-block share-button sb-facebook' href='https://www.blogger.com/share-post.g?blogID=4838136820032157985&postID=6481767562526230244&target=facebook' onclick='window.open(this.href, "_blank", "height=430,width=640"); return false;' target='_blank' title='Share to Facebook'><span class='share-button-link-text'>Share to Facebook</span></a><a class='goog-inline-block share-button sb-pinterest' href='https://www.blogger.com/share-post.g?blogID=4838136820032157985&postID=6481767562526230244&target=pinterest' target='_blank' title='Share to Pinterest'><span class='share-button-link-text'>Share to Pinterest</span></a> </div> </div> <div class='post-footer-line post-footer-line-2'> <span class='post-labels'> </span> </div> <div class='post-footer-line post-footer-line-3'> <span class='post-location'> </span> </div> </div> </div> <div class='comments' id='comments'> <a name='comments'></a> <h4>No comments:</h4> <div id='Blog1_comments-block-wrapper'> <dl class='avatar-comment-indent' id='comments-block'> </dl> </div> <p class='comment-footer'> <div class='comment-form'> <a name='comment-form'></a> <h4 id='comment-post-message'>Post a Comment</h4> <p> </p> <a href='https://www.blogger.com/comment/frame/4838136820032157985?po=6481767562526230244&hl=en' id='comment-editor-src'></a> <iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' frameborder='0' height='410px' id='comment-editor' name='comment-editor' src='' width='100%'></iframe> <script src='https://www.blogger.com/static/v1/jsbin/3061944402-comment_from_post_iframe.js' type='text/javascript'></script> <script type='text/java '> BLOG_CMT_createIframe('https://www.blogger.com/rpc_relay.html'); </script> </div> </p> </div> </div> </div></div> </div> <div class='blog-pager' id='blog-pager'> <span id='blog-pager-newer-link'> <a class='blog-pager-newer-link' href='https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html' id='Blog1_blog-pager-newer-link' title='Newer Post'>Newer Post</a> </span> <span id='blog-pager-older-link'> <a class='blog-pager-older-link' href='https://googleprojectzero.blogspot.com/2022/06/2022-0-day-in-wild-exploitationso-far.html' id='Blog1_blog-pager-older-link' title='Older Post'>Older Post</a> </span> <a class='home-link' href='https://googleprojectzero.blogspot.com/'>Home</a> </div> <div class='clear'></div> <div class='post-feeds'> <div class='feed-links'> Subscribe to: <a class='feed-link' href='https://googleprojectzero.blogspot.com/feeds/6481767562526230244/comments/default' target='_blank' type='application/atom+xml'>Post Comments (Atom)</a> </div> </div> </div></div> </div> </div> <div class='column-left-outer'> <div class='column-left-inner'> <aside> </aside> </div> </div> <div class='column-right-outer'> <div class='column-right-inner'> <aside> <div class='sidebar section' id='sidebar-right-1'><div class='widget BlogSearch' data-version='1' id='BlogSearch1'> <h2 class='title'>Search This Blog</h2> <div class='widget-content'> <div id='BlogSearch1_form'> <form action='https://googleprojectzero.blogspot.com/search' class='gsc-search-box' target='_top'> <table cellpadding='0' cellspacing='0' class='gsc-search-box'> <tbody> <tr> <td class='gsc-input'> <input autocomplete='off' class='gsc-input' name='q' size='10' title='search' type='text' value=''/> </td> <td class='gsc-search-button'> <input class='gsc-search-button' title='search' type='submit' value='Search'/> </td> </tr> </tbody> </table> </form> </div> </div> <div class='clear'></div> </div><div class='widget PageList' data-version='1' id='PageList1'> <h2>Pages</h2> <div class='widget-content'> <ul> <li> <a href='https://googleprojectzero.blogspot.com/p/about-project-zero.html'>About Project Zero</a> </li> <li> <a href='https://googleprojectzero.blogspot.com/p/working-at-project-zero.html'>Working at Project Zero</a> </li> <li> <a href='https://googleprojectzero.blogspot.com/p/0day.html'>0day "In the Wild"</a> </li> <li> <a href='https://googleprojectzero.github.io/0days-in-the-wild/rca.html'>0day Exploit Root Cause Analyses</a> </li> <li> <a href='https://googleprojectzero.blogspot.com/p/vulnerability-disclosure-faq.html'>Vulnerability Disclosure FAQ</a> </li> </ul> <div class='clear'></div> </div> </div><div class='widget BlogArchive' data-version='1' id='BlogArchive1'> <h2>Archives</h2> <div class='widget-content'> <div id='ArchiveList'> <div id='BlogArchive1_ArchiveList'> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2025/'> 2025 </a> <span class='post-count' dir='ltr'>(2)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2025/01/'> January </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2024/'> 2024 </a> <span class='post-count' dir='ltr'>(12)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2024/12/'> December </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2024/11/'> November </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2024/10/'> October </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2024/06/'> June </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2024/04/'> April </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2023/'> 2023 </a> <span class='post-count' dir='ltr'>(11)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2023/11/'> November </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2023/10/'> October </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2023/09/'> September </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2023/08/'> August </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2023/04/'> April </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2023/03/'> March </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2023/01/'> January </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate expanded'> <a class='toggle' href='javascript:void(0)'> <span class='zippy toggle-open'> &#9660;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/'> 2022 </a> <span class='post-count' dir='ltr'>(17)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/12/'> December </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/11/'> November </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/10/'> October </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate expanded'> <a class='toggle' href='javascript:void(0)'> <span class='zippy toggle-open'> &#9660;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/08/'> August </a> <span class='post-count' dir='ltr'>(1)</span> <ul class='posts'> <li><a href='https://googleprojectzero.blogspot.com/2022/08/the-quantum-state-of-linux-kernel.html'>The quantum state of Linux kernel garbage collecti...</a></li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/06/'> June </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/04/'> April </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/03/'> March </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/02/'> February </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/01/'> January </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/'> 2021 </a> <span class='post-count' dir='ltr'>(24)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/12/'> December </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/10/'> October </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/09/'> September </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/08/'> August </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/06/'> June </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/04/'> April </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/03/'> March </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/02/'> February </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/01/'> January </a> <span class='post-count' dir='ltr'>(10)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/'> 2020 </a> <span class='post-count' dir='ltr'>(36)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/12/'> December </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/11/'> November </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/10/'> October </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/09/'> September </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/08/'> August </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/07/'> July </a> <span class='post-count' dir='ltr'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/06/'> June </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/04/'> April </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/02/'> February </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/01/'> January </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/'> 2019 </a> <span class='post-count' dir='ltr'>(27)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/12/'> December </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/11/'> November </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/10/'> October </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/09/'> September </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/08/'> August </a> <span class='post-count' dir='ltr'>(11)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/04/'> April </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/03/'> March </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/02/'> February </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/01/'> January </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/'> 2018 </a> <span class='post-count' dir='ltr'>(22)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/12/'> December </a> <span class='post-count' dir='ltr'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/11/'> November </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/10/'> October </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/09/'> September </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/08/'> August </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/07/'> July </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/06/'> June </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/04/'> April </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/01/'> January </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/'> 2017 </a> <span class='post-count' dir='ltr'>(19)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/12/'> December </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/10/'> October </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/09/'> September </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/08/'> August </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/07/'> July </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/04/'> April </a> <span class='post-count' dir='ltr'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/03/'> March </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/02/'> February </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/'> 2016 </a> <span class='post-count' dir='ltr'>(17)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/12/'> December </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/11/'> November </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/10/'> October </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/09/'> September </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/08/'> August </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/07/'> July </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/06/'> June </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/03/'> March </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/02/'> February </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/01/'> January </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/'> 2015 </a> <span class='post-count' dir='ltr'>(33)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/12/'> December </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/11/'> November </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/10/'> October </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/09/'> September </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/08/'> August </a> <span class='post-count' dir='ltr'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/07/'> July </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/06/'> June </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/04/'> April </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/03/'> March </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/02/'> February </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/01/'> January </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2014/'> 2014 </a> <span class='post-count' dir='ltr'>(11)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2014/12/'> December </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2014/11/'> November </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2014/10/'> October </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2014/09/'> September </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2014/08/'> August </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2014/07/'> July </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> </li> </ul> </div> </div> <script type='text/javascript'> //<![CDATA[ (function(){ let archive_list = document.getElementById('ArchiveList'); if (archive_list == null) return; let cur_year = archive_list.querySelector('.post-count-link').innerText.trim() - 0; let last_year = 2014; let elements = []; const MONTHS = ',Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'.split(','); let parent = document.getElementById('ArchiveList'); while (parent.childNodes.length) parent.removeChild(parent.childNodes[0]); function fetch_next_year() { let url = 'https://googleprojectzero.blogspot.com/?action=getTitles&widgetId=BlogArchive1&widgetType=BlogArchive&responseType=js&path=https%3A%2F%2Fgoogleprojectzero.blogspot.com%2F'+cur_year; fetch(url).then(resp => { if (!resp.ok) { console.log('http error'); return; } resp.text().then(text => { let scope = { _WidgetManager: { _HandleControllerResult: (name, method, results) => { elements.push(document.createElement('hr')); let year_header = document.createElement('div'); year_header.appendChild(document.createTextNode(cur_year)); year_header.style.fontSize = 'large'; elements.push(year_header); let list = document.createElement('ul'); elements.push(list); for (let obj of results.posts) { let link_parts = obj.url.split('/'); let year = link_parts[3]; let month = link_parts[4]; let el = document.createElement(/*'div'*/'li'); el.style.listStyleType = 'square'; el.style.listStylePosition = 'inside'; let link = document.createElement('a'); el.appendChild(link); link.appendChild(document.createTextNode(obj.title)); link.href = obj.url; let date_trailer = document.createElement('span'); el.appendChild(date_trailer); //date_trailer.appendChild(document.createTextNode(' ('+year+'-'+month+')')); date_trailer.appendChild(document.createTextNode(' ('+MONTHS[parseInt(month, 10)]+')')); //date_trailer.style.textAlign = 'right'; //elements.push(el); list.appendChild(el); } } } }; with (scope) { eval(text); } if (cur_year == last_year) { finish(); } else { cur_year--; fetch_next_year(); } }); }); } fetch_next_year(); function finish() { for (let obj of elements) { parent.appendChild(obj); } console.log(elements); } })(); //]]> </script> <div class='clear'></div> </div> </div></div> <table border='0' cellpadding='0' cellspacing='0' class='section-columns columns-2'> <tbody> <tr> <td class='first columns-cell'> <div class='sidebar no-items section' id='sidebar-right-2-1'></div> </td> <td class='columns-cell'> <div class='sidebar no-items section' id='sidebar-right-2-2'></div> </td> </tr> </tbody> </table> <div class='sidebar no-items section' id='sidebar-right-3'></div> </aside> </div> </div> </div> <div style='clear: both'></div> <!-- columns --> </div> <!-- main --> </div> </div> <div class='main-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <footer> <div class='footer-outer'> <div class='footer-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left footer-fauxborder-left'> <div class='fauxborder-right footer-fauxborder-right'></div> <div class='region-inner footer-inner'> <div class='foot no-items section' id='footer-1'></div> <table border='0' cellpadding='0' cellspacing='0' class='section-columns columns-2'> <tbody> <tr> <td class='first columns-cell'> <div class='foot no-items section' id='footer-2-1'></div> </td> <td class='columns-cell'> <div class='foot no-items section' id='footer-2-2'></div> </td> </tr> </tbody> </table> <!-- outside of the include in order to lock Attribution widget --> <div class='foot section' id='footer-3' name='Footer'><div class='widget Attribution' data-version='1' id='Attribution1'> <div class='widget-content' style='text-align: center;'> Powered by <a href='https://www.blogger.com' target='_blank'>Blogger</a>. </div> <div class='clear'></div> </div></div> </div> </div> <div class='footer-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </footer> <!-- content --> </div> </div> <div class='content-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </div> <script type='text/javascript'> window.setTimeout(function() { document.body.className = document.body.className.replace('loading', ''); }, 10); </script> <script type="text/javascript" src="https://www.blogger.com/static/v1/widgets/688949419-widgets.js"></script> <script type='text/javascript'> window['__wavt'] = 'AOuZoY7c2_o-IP2_AB2euQmzd5Y7FB-SBg:1739851407703';_WidgetManager._Init('//www.blogger.com/rearrange?blogID\x3d4838136820032157985','//googleprojectzero.blogspot.com/2022/08/the-quantum-state-of-linux-kernel.html','4838136820032157985'); _WidgetManager._SetDataContext([{'name': 'blog', 'data': {'blogId': '4838136820032157985', 'title': 'Project Zero', 'url': 'https://googleprojectzero.blogspot.com/2022/08/the-quantum-state-of-linux-kernel.html', 'canonicalUrl': 'https://googleprojectzero.blogspot.com/2022/08/the-quantum-state-of-linux-kernel.html', 'homepageUrl': 'https://googleprojectzero.blogspot.com/', 'searchUrl': 'https://googleprojectzero.blogspot.com/search', 'canonicalHomepageUrl': 'https://googleprojectzero.blogspot.com/', 'blogspotFaviconUrl': 'https://googleprojectzero.blogspot.com/favicon.ico', 'bloggerUrl': 'https://www.blogger.com', 'hasCustomDomain': false, 'httpsEnabled': true, 'enabledCommentProfileImages': true, 'gPlusViewType': 'FILTERED_POSTMOD', 'adultContent': false, 'analyticsAccountNumber': 'UA-240546891-1', 'encoding': 'UTF-8', 'locale': 'en', 'localeUnderscoreDelimited': 'en', 'languageDirection': 'ltr', 'isPrivate': false, 'isMobile': false, 'isMobileRequest': false, 'mobileClass': '', 'isPrivateBlog': false, 'isDynamicViewsAvailable': true, 'feedLinks': '\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Project Zero - Atom\x22 href\x3d\x22https://googleprojectzero.blogspot.com/feeds/posts/default\x22 /\x3e\n\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/rss+xml\x22 title\x3d\x22Project Zero - RSS\x22 href\x3d\x22https://googleprojectzero.blogspot.com/feeds/posts/default?alt\x3drss\x22 /\x3e\n\x3clink rel\x3d\x22service.post\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Project Zero - Atom\x22 href\x3d\x22https://www.blogger.com/feeds/4838136820032157985/posts/default\x22 /\x3e\n\n\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Project Zero - Atom\x22 href\x3d\x22https://googleprojectzero.blogspot.com/feeds/6481767562526230244/comments/default\x22 /\x3e\n', 'meTag': '', 'adsenseHostId': 'ca-host-pub-1556223355139109', 'adsenseHasAds': false, 'adsenseAutoAds': false, 'boqCommentIframeForm': true, 'loginRedirectParam': '', 'view': '', 'dynamicViewsCommentsSrc': '//www.blogblog.com/dynamicviews/4224c15c4e7c9321/js/comments.js', 'dynamicViewsScriptSrc': '//www.blogblog.com/dynamicviews/f6e0cc369f0f1a05', 'plusOneApiSrc': 'https://apis.google.com/js/platform.js', 'disableGComments': true, 'interstitialAccepted': false, 'sharing': {'platforms': [{'name': 'Get link', 'key': 'link', 'shareMessage': 'Get link', 'target': ''}, {'name': 'Facebook', 'key': 'facebook', 'shareMessage': 'Share to Facebook', 'target': 'facebook'}, {'name': 'BlogThis!', 'key': 'blogThis', 'shareMessage': 'BlogThis!', 'target': 'blog'}, {'name': 'X', 'key': 'twitter', 'shareMessage': 'Share to X', 'target': 'twitter'}, {'name': 'Pinterest', 'key': 'pinterest', 'shareMessage': 'Share to Pinterest', 'target': 'pinterest'}, {'name': 'Email', 'key': 'email', 'shareMessage': 'Email', 'target': 'email'}], 'disableGooglePlus': true, 'googlePlusShareButtonWidth': 0, 'googlePlusBootstrap': '\x3cscript type\x3d\x22text/javascript\x22\x3ewindow.___gcfg \x3d {\x27lang\x27: \x27en\x27};\x3c/script\x3e'}, 'hasCustomJumpLinkMessage': false, 'jumpLinkMessage': 'Read more', 'pageType': 'item', 'postId': '6481767562526230244', 'postImageThumbnailUrl': 'https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNWAkA0RVb4goO21_FhJOVV-LSNTfbXV7GKoqH-CUrdMTpDcNUSQxEssrnAVGxC50aK-Z3HfIWeDyCgkr6lb5-a1Ha9Km5ppaHeBzWmLj8NTmZtUjx8J-VzzM1O7mYdjOfw2ErddrslDXw6rDZrs0g1DEC1Ya4VAbkLKKEhZgNPeiSefH-xpv3zDa8/s72-c/image71.png', 'postImageUrl': 'https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNWAkA0RVb4goO21_FhJOVV-LSNTfbXV7GKoqH-CUrdMTpDcNUSQxEssrnAVGxC50aK-Z3HfIWeDyCgkr6lb5-a1Ha9Km5ppaHeBzWmLj8NTmZtUjx8J-VzzM1O7mYdjOfw2ErddrslDXw6rDZrs0g1DEC1Ya4VAbkLKKEhZgNPeiSefH-xpv3zDa8/s1200/image71.png', 'pageName': 'The quantum state of Linux kernel garbage collection CVE-2021-0920 (Part I)', 'pageTitle': 'Project Zero: The quantum state of Linux kernel garbage collection CVE-2021-0920 (Part I)'}}, {'name': 'features', 'data': {}}, {'name': 'messages', 'data': {'edit': 'Edit', 'linkCopiedToClipboard': 'Link copied to clipboard!', 'ok': 'Ok', 'postLink': 'Post Link'}}, {'name': 'template', 'data': {'name': 'custom', 'localizedName': 'Custom', 'isResponsive': false, 'isAlternateRendering': false, 'isCustom': true}}, {'name': 'view', 'data': {'classic': {'name': 'classic', 'url': '?view\x3dclassic'}, 'flipcard': {'name': 'flipcard', 'url': '?view\x3dflipcard'}, 'magazine': {'name': 'magazine', 'url': '?view\x3dmagazine'}, 'mosaic': {'name': 'mosaic', 'url': '?view\x3dmosaic'}, 'sidebar': {'name': 'sidebar', 'url': '?view\x3dsidebar'}, 'snapshot': {'name': 'snapshot', 'url': '?view\x3dsnapshot'}, 'timeslide': {'name': 'timeslide', 'url': '?view\x3dtimeslide'}, 'isMobile': false, 'title': 'The quantum state of Linux kernel garbage collection CVE-2021-0920 (Part I)', 'description': ' A deep dive into an in-the-wild Android exploit Guest Post by Xingyu Jin, Android Security Research This is part one of a two-part guest...', 'featuredImage': 'https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNWAkA0RVb4goO21_FhJOVV-LSNTfbXV7GKoqH-CUrdMTpDcNUSQxEssrnAVGxC50aK-Z3HfIWeDyCgkr6lb5-a1Ha9Km5ppaHeBzWmLj8NTmZtUjx8J-VzzM1O7mYdjOfw2ErddrslDXw6rDZrs0g1DEC1Ya4VAbkLKKEhZgNPeiSefH-xpv3zDa8/s1200/image71.png', 'url': 'https://googleprojectzero.blogspot.com/2022/08/the-quantum-state-of-linux-kernel.html', 'type': 'item', 'isSingleItem': true, 'isMultipleItems': false, 'isError': false, 'isPage': false, 'isPost': true, 'isHomepage': false, 'isArchive': false, 'isLabelSearch': false, 'postId': 6481767562526230244}}]); _WidgetManager._RegisterWidget('_NavbarView', new _WidgetInfo('Navbar1', 'navbar', document.getElementById('Navbar1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_HeaderView', new _WidgetInfo('Header1', 'header', document.getElementById('Header1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogView', new _WidgetInfo('Blog1', 'main', document.getElementById('Blog1'), {'cmtInteractionsEnabled': false, 'lightboxEnabled': true, 'lightboxModuleUrl': 'https://www.blogger.com/static/v1/jsbin/1360229384-lbx.js', 'lightboxCssUrl': 'https://www.blogger.com/static/v1/v-css/1964470060-lightbox_bundle.css'}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogSearchView', new _WidgetInfo('BlogSearch1', 'sidebar-right-1', document.getElementById('BlogSearch1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_PageListView', new _WidgetInfo('PageList1', 'sidebar-right-1', document.getElementById('PageList1'), {'title': 'Pages', 'links': [{'isCurrentPage': false, 'href': 'https://googleprojectzero.blogspot.com/p/about-project-zero.html', 'id': '4384467920505278144', 'title': 'About Project Zero'}, {'isCurrentPage': false, 'href': 'https://googleprojectzero.blogspot.com/p/working-at-project-zero.html', 'id': '2459334498880008057', 'title': 'Working at Project Zero'}, {'isCurrentPage': false, 'href': 'https://googleprojectzero.blogspot.com/p/0day.html', 'id': '3414239791814532209', 'title': '0day \x22In the Wild\x22'}, {'isCurrentPage': false, 'href': 'https://googleprojectzero.github.io/0days-in-the-wild/rca.html', 'title': '0day Exploit Root Cause Analyses'}, {'isCurrentPage': false, 'href': 'https://googleprojectzero.blogspot.com/p/vulnerability-disclosure-faq.html', 'id': '2935252455704572784', 'title': 'Vulnerability Disclosure FAQ'}], 'mobile': false, 'showPlaceholder': true, 'hasCurrentPage': false}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogArchiveView', new _WidgetInfo('BlogArchive1', 'sidebar-right-1', document.getElementById('BlogArchive1'), {'languageDirection': 'ltr', 'loadingMessage': 'Loading\x26hellip;'}, 'displayModeFull')); _WidgetManager._RegisterWidget('_AttributionView', new _WidgetInfo('Attribution1', 'footer-3', document.getElementById('Attribution1'), {}, 'displayModeFull')); </script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10