---
title: "Bus integrity: 데이터가 맞는데도 엉뚱한 주소에 쓸 수 있다"
author: "브레이브브라우저쓰자"
published_at: "2026-11-03T13:36:01.125Z"
updated_at: "2026-10-06T02:38:05.880Z"
tags: ["bus integrity"]
canonical_url: "https://ariser.io/@writer_a9817d5a8de0/bus-integrity-%EB%8D%B0%EC%9D%B4%ED%84%B0%EA%B0%80-%EB%A7%9E%EB%8A%94%EB%8D%B0%EB%8F%84-%EC%97%89%EB%9A%B1%ED%95%9C-%EC%A3%BC%EC%86%8C%EC%97%90-%EC%93%B8-%EC%88%98-%EC%9E%88%EB%8B%A4"
ai_assisted: true
---

# Bus integrity: 데이터가 맞는데도 엉뚱한 주소에 쓸 수 있다

이 글은 AI가 활용됐습니다.

[원문](https://ariser.io/@writer_a9817d5a8de0/bus-integrity-%EB%8D%B0%EC%9D%B4%ED%84%B0%EA%B0%80-%EB%A7%9E%EB%8A%94%EB%8D%B0%EB%8F%84-%EC%97%89%EB%9A%B1%ED%95%9C-%EC%A3%BC%EC%86%8C%EC%97%90-%EC%93%B8-%EC%88%98-%EC%9E%88%EB%8B%A4)

데이터에 검사 비트를 붙였는데도 엉뚱한 주소에 쓰기가 일어날 수 있을까. 데이터 값이 이동하는 동안 보존됐더라도 주소나 쓰기 제어가 바뀌면 요청의 의미는 달라진다. Bus integrity를 평가할 때는 데이터뿐 아니라 어떤 명령 필드를 보호하고 어디서 검사하는지 확인해야 한다.

## 같은 데이터를 다른 곳에 쓰는 요청

가상의 버스가 8비트 데이터와 4비트 주소, 1비트 쓰기 표시를 갖는다고 하자. 데이터 01010101은 1이 네 개이므로 짝수 parity를 위해 붙이는 비트는 0이다. 주소가 0010에서 0011로 바뀌어도 데이터 자체가 같으면 데이터 parity 검사는 통과한다. 목적지는 달라졌지만 데이터 검사에서 볼 변화는 없는 것이다.

주소와 쓰기 표시에도 별도의 짝수 parity를 붙이면 이 단일 변화는 잡을 수 있다. 원래 주소 0010의 1 하나와 쓰기 표시 1을 합하면 1이 두 개여서 검사 비트는 0이다. 주소 0011로 바뀌면 세 개가 되어 전송된 검사 비트와 맞지 않는다.

하지만 주소의 두 비트를 바꿔 0010을 0001로 만들면 두 경우 모두 1이 하나다. 같은 쓰기 표시와 parity 0이 다시 맞는다. 이 예제의 단순 parity는 모든 종류의 명령 변경을 탐지하는 코드가 아니다. 데이터의 검사 성공과 명령의 검사 성공, 선택한 코드의 검출 능력을 나눠 읽어야 한다.

## 실제 구현에서 보호 필드를 찾는다

OpenTitan의 TL-UL 확장에는 명령·응답과 데이터의 검사 정보가 구분돼 있다. 문서의 user-bit 설명과 실제 `tlul_pkg.sv`를 보면 명령 검사에 주소, opcode, mask, instruction type을 추출한다. 데이터는 별도 경로로 계산한다. [OpenTitan TL-UL 문서](https://opentitan.org/book/hw/ip/tlul/index.html), [명령 필드를 추출하는 구현](https://github.com/lowRISC/opentitan/blob/master/hw/ip/tlul/rtl/tlul_pkg.sv)

이 구조는 앞의 단순 parity 예제와 동일한 코드를 쓴다는 뜻이 아니다. 실제 구현은 SECDED 계열의 integrity encoding을 사용한다. 또한 버스 구조체에 존재하는 모든 필드가 하나의 명령 코드에 무조건 포함되는 것도 아니다. 예를 들어 확인한 추출 함수의 목록을 읽어야 보호 대상과 별도 프로토콜 검사 대상의 경계를 알 수 있다.

주소와 데이터의 정상·오류 조합을 나눠 시험하면 도움이 된다. 데이터만 바꾸는 경우, 주소만 바꾸는 경우, 명령과 검사 비트를 함께 바꾸는 경우는 서로 다른 질문에 답한다. 한 검출 사례가 성공했다는 기록으로 나머지 필드까지 검사됐다고 판단하지 않는다.

## 검출 표시와 오류 대응은 별도의 연결이다

확인한 OpenTitan의 명령 검사 모듈은 명령과 데이터 decoder의 오류 정보를 모으고, 요청이 valid일 때 오류 출력을 낸다. 모듈의 주석도 이 오류 출력이 거래 단위이며 영구적으로 저장할지는 상위 모듈이 결정한다고 설명한다. [TL-UL integrity checker](https://github.com/lowRISC/opentitan/blob/master/hw/ip/tlul/rtl/tlul_cmd_intg_chk.sv)

이 출력이 나왔다는 사실만으로 데이터가 자동 수정됐거나 쓰기 동작이 자동 취소됐다고 말할 수는 없다. decoder의 데이터 출력을 어떻게 사용하고, 오류를 받은 소비자가 무엇을 하는지까지 확인해야 한다. 특히 되돌리기 어려운 동작에서는 검사와 실제 실행의 순서를 검토해야 한다.

가상 회로에서 오류 검사가 한 주기 뒤에 끝나는데 쓰기를 먼저 완료하면, 검출에 성공해도 이미 저장소가 바뀔 수 있다. 오류 응답을 소프트웨어가 받았다는 사실과 내부의 변경이 없었다는 보장은 다르다. 버스가 요청을 수락한 시점, 검사 결과가 준비된 시점, 대상이 동작한 시점을 연결해서 봐야 한다.

## 코드가 맞는 요청에도 접근 권한은 필요하다

공개된 규칙으로 계산하는 오류 검출 코드라면 새 주소에 맞는 검사 정보를 다시 만들 수 있다. 검사 결과가 일치해도 그 주소에 쓰기를 수행할 권한이 있는지는 별도의 정책이다. 여기서 말하는 bus integrity는 필드의 오류 검출이며, 보낸 주체의 인증이나 허용 주소 범위를 대신하는 보장이 아니다.

응답도 같은 관점으로 읽는다. 돌아온 데이터와 오류 표시의 보존을 확인하는 것과, 응답이 어떤 요청에 대응하는지 확인하는 것은 관련되지만 동일한 검사로 자동 해결되지는 않는다. 보호 필드와 요청 추적의 역할을 각각 정해야 한다.

Bus integrity의 의미는 검사 비트의 개수보다 그 비트가 덮는 필드와 실행 전의 판단에 있다. 데이터와 명령을 나누고, 검출 결과를 실제 소비자의 동작까지 이어서 확인하면 어떤 변경을 발견할 수 있고 어떤 접근 제어가 따로 필요한지 분명해진다.

