FlawOpen

flawopen.com/Teardowns/cve-2026-31431-linux-algif-aead-copy-fail

● CVE-2026-31431 · CVSS 7.8 · 높음
보안 연구 · FlawOpen

CVE-2026-31431: Linux 커널 Copy Fail 취약점

Copy Fail은 Linux AF_ALG의 AEAD 경로에 있는 로컬 권한 상승 취약점입니다. in-place 최적화가 소스와 대상 매핑을 혼동했고, 업스트림 수정은 out-of-place 처리를 복원했으며 CISA는 CVE를 KEV에 추가했습니다.[1], [2], [5]

💡 알기 쉬운 설명 (ELI5)

사서가 복사본에 표시해야 하는데 기계의 지름길로 연필이 원본에 닿는 상황을 생각해 보세요. in-place 지름길은 결과용 쓰기가 다른 매핑 페이지에 도달하게 할 수 있었습니다. 수정은 소스와 대상을 분리해 처리합니다.[3], [8]

핵심 개념 및 용어

AF_ALG
사용자 프로세스가 암호화 작업을 요청하는 Linux 소켓 인터페이스입니다.[8], [3]
AEAD
연관 데이터 인증 암호화: 데이터를 암호화하고 추가 비암호화 메타데이터를 인증합니다.[8]
algif_aead
AEAD용 AF_ALG 구현이며 취약한 소스/대상 처리 경로를 포함합니다.[3]
Page cache
파일 내용을 위한 커널 메모리 캐시입니다. 매핑 페이지 쓰기는 디스크 기록 전 읽기에 영향을 줄 수 있습니다.[8]
CWE-1288 / CWE-669
NVD는 redhat-SADP를 매핑 출처로 표시해 CWE-1288을 싣고 있으며, Red Hat 페이지에도 같은 CWE가 나옵니다. 캐나다 사이버 보안 센터 경고는 이 문제를 CWE-669로 분류합니다. 서로 다른 출처의 분류이므로 서로 바꿔 쓸 수 있는 레이블이 아닙니다.[11], [7], [5], [9], [10]

프레임워크 매핑

근본 원인 분석 (Root Cause)

2017년 변경 72548b093ee3은 algif_aead에 in-place 최적화를 도입했습니다. 소스와 대상은 서로 다른 매핑일 수 있습니다. authencesn은 임시 데이터를 예상 출력 영역 밖에 쓸 수 있고, in-place scatterlist는 splice()로 전달된 파일의 page cache 페이지에 기록할 수 있었습니다. Linux CVE 공지는 associated data 복사를 유지하면서 out-of-place 처리로 되돌리는 것을 수정으로 설명합니다. 로컬 접근과 취약 경로 활성화가 필요합니다. CVSS 7.8(AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)이며 인증 없는 원격 진입점은 아닙니다.[1], [3], [8], [7], [9], [10]

단계별 공격 실행 흐름

단계 1

로컬 프로세스가 API에 도달

로컬 프로세스가 AF_ALG로 AEAD 작업을 요청하고 algif_aead가 처리합니다. 원격 요청만으로는 이 로컬 인터페이스에 도달하지 않습니다.[8], [7]

단계 2

데이터 경로가 in-place 최적화를 사용

취약 구현은 매핑이 다른데도 소스와 대상이 같은 페이지를 공유할 수 있는 것처럼 처리합니다.[8], [3]

단계 3

쓰기가 출력 경계를 넘음

authencesn의 임시 데이터가 출력 영역 밖에 쓰여 splice()로 전달된 파일의 page cache에 도달할 수 있습니다.[8]

단계 4

커널이 매핑을 분리

수정은 불필요한 in-place 복잡성을 제거하고 associated data를 복사한 뒤 out-of-place 처리를 복원합니다.[1], [3]

소스 코드 비교: 취약한 구현 vs 보안 패치

개념을 요약한 내용이며 커널 원문 코드나 컴파일 가능한 패치가 아닙니다. 업스트림 공지는 서로 다른 매핑 때문에 associated data 복사는 유지하고 72548b093ee3을 대부분 되돌린다고 설명합니다.[3], [2]

소스 코드 발췌: crypto/algif_aead.c (_aead_recvmsg)

취약한 구현
/* 수정 전: 암호화 작업을 같은 버퍼에서 제자리 수행합니다. */
rsgl_src = areq->first_rsgl.sgl.sg;

if (ctx->enc) {
    memcpy_sglist(areq->first_rsgl.sgl.sg, tsgl_src, processed);
    af_alg_pull_tsgl(sk, processed, NULL, 0);
} else {
    memcpy_sglist(areq->first_rsgl.sgl.sg, tsgl_src, outlen);
    /* 인증 태그용 TX scatterlist를 구성하고 연결합니다. */
    areq->tsgl_entries = af_alg_count_tsgl(sk, processed, processed - as);
    /* ... */
}

aead_request_set_crypt(&areq->cra_u.aead_req, rsgl_src,
                       areq->first_rsgl.sgl.sg, used, ctx->iv);
보안 강화 패치
/* 수정 후: 요청별 소스 scatterlist를 유지합니다. */
processed = used + ctx->aead_assoclen;
areq->tsgl_entries = af_alg_count_tsgl(sk, processed);
/* areq->tsgl을 할당하고 초기화한 다음 TX 페이지를 여기에 추가합니다. */
af_alg_pull_tsgl(sk, processed, areq->tsgl);
tsgl_src = areq->tsgl;

/* 연관 데이터를 복사하되 소스와 대상은 분리합니다. */
rsgl_src = areq->first_rsgl.sgl.sg;
memcpy_sglist(rsgl_src, tsgl_src, ctx->aead_assoclen);
aead_request_set_crypt(&areq->cra_u.aead_req, tsgl_src,
                       areq->first_rsgl.sgl.sg, used, ctx->iv);

엔지니어링 및 시스템 보안 강화 체크리스트

출처