Files
coollang/lib
coolguyandClaude Opus 5 01d090b065 move: capability가 struct 필드로 복제되던 구멍을 막는다 (보안 정리 ii)
"발견들 다 고쳤나"를 확인하려고 전부 다시 돌려보다 드러났다.

  pub struct Wrapper { pay: Pay }
  pub fn duplicate(w: Wrapper) effects {Pay.charge} {
      consume(w.pay)
      consume(w.pay)      // 같은 capability를 두 번 소비 — 통과했다
  }

w가 빌린 값인데도 통과했다. 즉 "safe code에서 capability는 복제·위조되지
않는다"가 깨져 있었다. 이 세션에서 찾은 것 중 가장 심각하다.

원인은 단순하다. E_field가 빌린 값을 돌려주는데 Move 문맥에서 그것을
검사하는 곳이 E_ident 분기에만 있었고, 필드 접근은 그 분기를 지나가지
않는다. 규칙("v0에 부분 move는 없다")은 주석에 적혀 있었으나 강제되지
않았다.

필드의 affinity를 알아야 정확히 막을 수 있어서 move 검사기에 struct 필드
표와 바인딩의 선언 타입을 넣었다. copyable 필드는 막지 않는다 — w.label은
통과한다.

이것이 LRU에서 열거형으로 우회한 것을 사후에 정당화한다. 그때는 "struct로는
안 되고 열거형으로는 된다"가 우연처럼 보였는데, 열거형이 유일한 길인 것이
규칙이었고 struct 쪽이 새고 있었을 뿐이다.

여태 안 보인 이유: samples/05는 자원 타입을 직접 다루고 struct에 담지
않는다. 개밥 먹기에서 자원을 자료구조에 담는 코드를 처음 쓰면서 드러났다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZVDeU6KLuUVL3gs18Hm3E
2026-08-30 19:21:16 +09:00
..